mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-11-04 00:02:37 +01:00 
			
		
		
		
	ldap trust map cleanup on domain delete (#7915)
Co-authored-by: Wei Zhou <weizhou@apache.org>
This commit is contained in:
		
							parent
							
								
									9c9b17885f
								
							
						
					
					
						commit
						09ae0499b2
					
				@ -28,6 +28,7 @@ import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
import com.cloud.user.AccountManager;
 | 
			
		||||
import com.cloud.user.DomainManager;
 | 
			
		||||
import com.cloud.utils.component.ComponentLifecycleBase;
 | 
			
		||||
import com.cloud.utils.exception.CloudRuntimeException;
 | 
			
		||||
import org.apache.cloudstack.api.LdapValidator;
 | 
			
		||||
@ -107,6 +108,13 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
 | 
			
		||||
        super.configure(name, params);
 | 
			
		||||
        LOGGER.debug("Configuring LDAP Manager");
 | 
			
		||||
 | 
			
		||||
        addAccountRemovalListener();
 | 
			
		||||
        addDomainRemovalListener();
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void addAccountRemovalListener() {
 | 
			
		||||
        messageBus.subscribe(AccountManager.MESSAGE_REMOVE_ACCOUNT_EVENT, new MessageSubscriber() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onPublishMessage(String senderAddress, String subject, Object args) {
 | 
			
		||||
@ -115,18 +123,37 @@ public class LdapManagerImpl extends ComponentLifecycleBase implements LdapManag
 | 
			
		||||
                    long domainId = account.getDomainId();
 | 
			
		||||
                    LdapTrustMapVO ldapTrustMapVO = _ldapTrustMapDao.findByAccount(domainId, account.getAccountId());
 | 
			
		||||
                    if (ldapTrustMapVO != null) {
 | 
			
		||||
                        String msg = String.format("Removing link between LDAP: %s - type: %s and account: %s on domain: %s",
 | 
			
		||||
                                ldapTrustMapVO.getName(), ldapTrustMapVO.getType().name(), account.getAccountId(), domainId);
 | 
			
		||||
                        LOGGER.debug(msg);
 | 
			
		||||
                        _ldapTrustMapDao.remove(ldapTrustMapVO.getId());
 | 
			
		||||
                        removeTrustmap(ldapTrustMapVO);
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (final Exception e) {
 | 
			
		||||
                    LOGGER.error("Caught exception while removing account linked to LDAP", e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    private void addDomainRemovalListener() {
 | 
			
		||||
        messageBus.subscribe(DomainManager.MESSAGE_REMOVE_DOMAIN_EVENT, new MessageSubscriber() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void onPublishMessage(String senderAddress, String subject, Object args) {
 | 
			
		||||
                try {
 | 
			
		||||
                    long domainId = ((DomainVO) args).getId();
 | 
			
		||||
                    List<LdapTrustMapVO> ldapTrustMapVOs = _ldapTrustMapDao.searchByDomainId(domainId);
 | 
			
		||||
                    for (LdapTrustMapVO ldapTrustMapVO : ldapTrustMapVOs) {
 | 
			
		||||
                        removeTrustmap(ldapTrustMapVO);
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (final Exception e) {
 | 
			
		||||
                    LOGGER.error("Caught exception while removing trust-map for domain linked to LDAP", e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void removeTrustmap(LdapTrustMapVO ldapTrustMapVO) {
 | 
			
		||||
        String msg = String.format("Removing link between LDAP: %s - type: %s  and account: %s on domain: %s",
 | 
			
		||||
                ldapTrustMapVO.getName(), ldapTrustMapVO.getType().name(), ldapTrustMapVO.getAccountId(), ldapTrustMapVO.getDomainId());
 | 
			
		||||
        LOGGER.debug(msg);
 | 
			
		||||
        _ldapTrustMapDao.remove(ldapTrustMapVO.getId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -1812,15 +1812,37 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
 | 
			
		||||
        // If the user is a System user, return an error. We do not allow this
 | 
			
		||||
        AccountVO account = _accountDao.findById(accountId);
 | 
			
		||||
 | 
			
		||||
        if (account == null || account.getRemoved() != null) {
 | 
			
		||||
            if (account != null) {
 | 
			
		||||
                s_logger.info("The account:" + account.getAccountName() + " is already removed");
 | 
			
		||||
            }
 | 
			
		||||
        if (! isDeleteNeeded(account, accountId, caller)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Account that manages project(s) can't be removed
 | 
			
		||||
        List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
 | 
			
		||||
        if (!managedProjectIds.isEmpty()) {
 | 
			
		||||
            StringBuilder projectIds = new StringBuilder();
 | 
			
		||||
            for (Long projectId : managedProjectIds) {
 | 
			
		||||
                projectIds.append(projectId).append(", ");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw new InvalidParameterValueException("The account id=" + accountId + " manages project(s) with ids " + projectIds + "and can't be removed");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        CallContext.current().putContextParameter(Account.class, account.getUuid());
 | 
			
		||||
 | 
			
		||||
        return deleteAccount(account, callerUserId, caller);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isDeleteNeeded(AccountVO account, long accountId, Account caller) {
 | 
			
		||||
        if (account == null) {
 | 
			
		||||
            s_logger.info(String.format("The account, identified by id %d, doesn't exist", accountId ));
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (account.getRemoved() != null) {
 | 
			
		||||
            s_logger.info("The account:" + account.getAccountName() + " is already removed");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        // don't allow removing Project account
 | 
			
		||||
        if (account == null || account.getType() == Account.Type.PROJECT) {
 | 
			
		||||
        if (account.getType() == Account.Type.PROJECT) {
 | 
			
		||||
            throw new InvalidParameterValueException("The specified account does not exist in the system");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1830,21 +1852,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
 | 
			
		||||
        if (account.isDefault()) {
 | 
			
		||||
            throw new InvalidParameterValueException("The account is default and can't be removed");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Account that manages project(s) can't be removed
 | 
			
		||||
        List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
 | 
			
		||||
        if (!managedProjectIds.isEmpty()) {
 | 
			
		||||
            StringBuilder projectIds = new StringBuilder();
 | 
			
		||||
            for (Long projectId : managedProjectIds) {
 | 
			
		||||
                projectIds.append(projectId + ", ");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw new InvalidParameterValueException("The account id=" + accountId + " manages project(s) with ids " + projectIds + "and can't be removed");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        CallContext.current().putContextParameter(Account.class, account.getUuid());
 | 
			
		||||
 | 
			
		||||
        return deleteAccount(account, callerUserId, caller);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 | 
			
		||||
@ -344,16 +344,8 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean deleteDomain(DomainVO domain, Boolean cleanup) {
 | 
			
		||||
        GlobalLock lock = getGlobalLock("AccountCleanup");
 | 
			
		||||
        if (lock == null) {
 | 
			
		||||
            s_logger.debug("Couldn't get the global lock");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!lock.lock(30)) {
 | 
			
		||||
            s_logger.debug("Couldn't lock the db");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        GlobalLock lock = getGlobalLock();
 | 
			
		||||
        if (lock == null) return false;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // mark domain as inactive
 | 
			
		||||
@ -361,6 +353,28 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
 | 
			
		||||
            domain.setState(Domain.State.Inactive);
 | 
			
		||||
            _domainDao.update(domain.getId(), domain);
 | 
			
		||||
 | 
			
		||||
            return cleanDomain(domain, cleanup);
 | 
			
		||||
        }
 | 
			
		||||
        finally {
 | 
			
		||||
            lock.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private GlobalLock getGlobalLock() {
 | 
			
		||||
        GlobalLock lock = getGlobalLock("DomainCleanup");
 | 
			
		||||
        if (lock == null) {
 | 
			
		||||
            s_logger.debug("Couldn't get the global lock");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!lock.lock(30)) {
 | 
			
		||||
            s_logger.debug("Couldn't lock the db");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return lock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean cleanDomain(DomainVO domain, Boolean cleanup) {
 | 
			
		||||
        try {
 | 
			
		||||
            long ownerId = domain.getAccountId();
 | 
			
		||||
            if (BooleanUtils.toBoolean(cleanup)) {
 | 
			
		||||
@ -392,10 +406,6 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
        finally {
 | 
			
		||||
            lock.unlock();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Roll back domain state to Active
 | 
			
		||||
 | 
			
		||||
@ -136,7 +136,7 @@ public class DomainManagerImplTest {
 | 
			
		||||
    public void setup() throws NoSuchFieldException, SecurityException,
 | 
			
		||||
            IllegalArgumentException, IllegalAccessException {
 | 
			
		||||
        Mockito.doReturn(adminAccount).when(domainManager).getCaller();
 | 
			
		||||
        Mockito.doReturn(lock).when(domainManager).getGlobalLock("AccountCleanup");
 | 
			
		||||
        Mockito.doReturn(lock).when(domainManager).getGlobalLock("DomainCleanup");
 | 
			
		||||
        Mockito.when(lock.lock(Mockito.anyInt())).thenReturn(true);
 | 
			
		||||
        Mockito.when(domainDaoMock.findById(DOMAIN_ID)).thenReturn(domain);
 | 
			
		||||
        Mockito.when(domain.getAccountId()).thenReturn(ACCOUNT_ID);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user