Skip to content

Commit

Permalink
Remove parent OU on group deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
fdaugan committed Mar 5, 2024
1 parent 08abe84 commit 4a302c5
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,7 @@
*/
package org.ligoj.app.plugin.id.ldap.dao;

import java.util.Set;
import java.util.stream.Collectors;

import javax.cache.annotation.CacheKey;
import javax.cache.annotation.CachePut;
import javax.cache.annotation.CacheResult;
import javax.cache.annotation.CacheValue;

import lombok.extern.slf4j.Slf4j;
import org.ligoj.app.iam.IamProvider;
import org.ligoj.app.plugin.id.DnUtils;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -21,7 +14,9 @@
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;
import javax.cache.annotation.*;
import java.util.Set;
import java.util.stream.Collectors;

import static org.ligoj.app.plugin.id.ldap.dao.AbstractManagedLdapRepository.OBJECT_CLASS;

Expand Down Expand Up @@ -72,7 +67,7 @@ public String findById(@CacheKey final String baseDn, @CacheKey final String id)
}

/**
* Create a new group. There is no synchronized block, so error could occur; this is assumed for performance
* Create a new organizational unit. There is no synchronized block, so error could occur; this is assumed for performance
* purpose.
*
* @param baseDn Base DN.
Expand All @@ -92,6 +87,23 @@ public void create(@CacheKey final String baseDn, @CacheKey final String ou, @Ca
getUser().getTemplate().bind(context);
}

/**
* Delete the given organizational unit.
*
* @param baseDn Base DN.
* @param ou The formatted OU.
* @param dn The DN of new customer. Must ends with the OU.
*/
@CacheRemove(cacheName = "customers-by-id")
public void delete(@CacheKey final String baseDn, @CacheKey final String ou, final String dn) {
// Invalidate the customers set
cacheManager.getCache("customers").evict(baseDn);

// First create the LDAP entry
log.info("Customer (OU) {} will be delete from {}", ou, dn);
getUser().getTemplate().unbind(dn);
}

/**
* Map a customer to LDAP.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,17 @@ private String validateAndCreateParent(final String group, final String parentGr
return validateParentGroup(group, parentGroup);
}

/**
* Return the normalized OU DN.
*/
private String getParentOu(final String ou) {
final var groupTypeLdap = containerScopeResource.findByName(ContainerType.GROUP, ContainerScope.TYPE_PROJECT);
final var parentDn = groupTypeLdap.getDn();

// Build the complete normalized DN from the OU and new Group
return "ou=" + ou + "," + parentDn;
}

/**
* Validate the group against its direct parent (a normalized OU) and return its DN.
*/
Expand All @@ -443,7 +454,7 @@ private String validateAndCreateParentOu(final String group, final String ou, fi
final var parentDn = groupTypeLdap.getDn();

// Build the complete normalized DN from the OU and new Group
final var ouDn = "ou=" + ou + "," + parentDn;
final var ouDn = getParentOu(ou);

// Check the target OU exists or not and create the OU as needed
if (projectCustomerLdapRepository.findById(parentDn, ou) == null) {
Expand Down Expand Up @@ -738,7 +749,8 @@ public Collection<INamableBean<String>> findCustomersByName(@PathParam("criteria

@Override
public void delete(final int subscription, final boolean deleteRemoteData) {
final var projectId = subscriptionRepository.findOne(subscription).getProject().getId();
final var project = subscriptionRepository.findOne(subscription).getProject();
final var projectId = project.getId();
final var parameters = subscriptionResource.getParameters(subscription);
final var group = parameters.get(IdentityResource.PARAMETER_GROUP);
cacheProjectGroupRepository.deleteAllBy("group.id", group, new String[]{"project.id"}, projectId);
Expand All @@ -751,6 +763,19 @@ public void delete(final int subscription, final boolean deleteRemoteData) {
// Perform the deletion
repository.delete(groupLdap);
}

// Also try to delete the parent OU. Ignore the failures.
final var ou = parameters.get(IdentityResource.PARAMETER_OU);
if (ou != null) {
final var groupTypeLdap = containerScopeResource.findByName(ContainerType.GROUP, ContainerScope.TYPE_PROJECT);
try {
projectCustomerLdapRepository.delete(groupTypeLdap.getDn(), ou, getParentOu(ou));
log.info("OU {} has been cleaned, after deleting group {}, project {} and subscription {}", ou, group, project.getPkey(), subscription);
} catch (Exception e) {
// Ignore this failure, this OU might not be empty
log.info("OU {} could not be deleted while deleting group {}, project {} and subscription {}", ou, group, project.getPkey(), subscription);
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,22 @@ void createOuNotExists() {
Assertions.assertNotNull(projectCustomerLdapRepository.findById("ou=project,dc=sample,dc=com", "some"));
Assertions.assertTrue(projectCustomerLdapRepository.findAll("ou=project,dc=sample,dc=com").contains("some"));

// Attach the new group
final var subscription3 = new Subscription();
subscription3.setProject(subscription2.getProject());
subscription3.setNode(subscription.getNode());
em.persist(subscription3);

// Add parameters
setGroup(subscription3, "some-new-project-sub");
setOu(subscription3, "some");
basicCreate(subscription3);

// Delete the group, and also try to delete the parent OU. This last step fail silently
resource.delete(subscription2.getId(), true);

// Delete the group, and also delete sucessfully the parent
resource.delete(subscription3.getId(), true);
}

@Test
Expand Down

0 comments on commit 4a302c5

Please sign in to comment.