Fix account deletion blocked by deleted project admin mappings

This commit is contained in:
Surya Srinivasan 2026-02-08 02:44:39 +05:30
parent 408e8c079d
commit 836f84ab19
2 changed files with 43 additions and 7 deletions

View File

@ -2118,16 +2118,31 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
return deleteAccount(account, callerUserId, caller);
}
protected void checkIfAccountManagesProjects(long accountId) {
List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
if (!CollectionUtils.isEmpty(managedProjectIds)) {
throw new InvalidParameterValueException(String.format(
"Unable to delete account [%s], because it manages the following project(s): %s. Please, remove the account from these projects or demote it to a regular project role first.",
accountId, managedProjectIds
));
protected void checkIfAccountManagesProjects(long accountId) {
List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
if (CollectionUtils.isEmpty(managedProjectIds)) {
return;
}
List<Long> activeManagedProjects = new ArrayList<>();
for (Long projectId : managedProjectIds) {
ProjectVO project = _projectDao.findById(projectId);
if (project != null && project.getRemoved() == null) {
activeManagedProjects.add(projectId);
}
}
if (!activeManagedProjects.isEmpty()) {
throw new InvalidParameterValueException(String.format(
"Unable to delete account [%s], because it manages the following project(s): %s. Please, remove the account from these projects or demote it to a regular project role first.",
accountId, activeManagedProjects
));
}
}
protected boolean isDeleteNeeded(AccountVO account, long accountId, Account caller) {
if (account == null) {
logger.info(String.format("The account, identified by id %d, doesn't exist", accountId ));

View File

@ -26,6 +26,8 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.acl.Role;
@ -75,6 +77,7 @@ import com.cloud.vm.UserVmManagerImpl;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.projects.ProjectVO;
@RunWith(MockitoJUnitRunner.class)
public class AccountManagerImplTest extends AccountManagetImplTestBase {
@ -1592,4 +1595,22 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
accountManagerImpl.checkCallerApiPermissionsForUserOrAccountOperations(accountMock);
}
@Test
public void testCheckIfAccountManagesOnlyDeletedProjectsDoesNotThrow() {
long accountId = 42L;
long projectId = 100L;
Mockito.when(projectAccountDao.listAdministratedProjectIds(accountId))
.thenReturn(List.of(projectId));
ProjectVO deletedProject = Mockito.mock(ProjectVO.class);
Mockito.when(deletedProject.getRemoved()).thenReturn(new Date());
Mockito.when(projectDao.findById(projectId))
.thenReturn(deletedProject);
accountManager.checkIfAccountManagesProjects(accountId);
}
}