Skip to content

Commit d57e1f8

Browse files
Surya SrinivasanSurya Srinivasan
authored andcommitted
Fix account deletion blocked by deleted project admin mappings
1 parent a0f35a1 commit d57e1f8

File tree

2 files changed

+43
-7
lines changed

2 files changed

+43
-7
lines changed

server/src/main/java/com/cloud/user/AccountManagerImpl.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,16 +2110,31 @@ public boolean deleteUserAccount(long accountId) {
21102110
return deleteAccount(account, callerUserId, caller);
21112111
}
21122112

2113-
protected void checkIfAccountManagesProjects(long accountId) {
2114-
List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
2115-
if (!CollectionUtils.isEmpty(managedProjectIds)) {
2116-
throw new InvalidParameterValueException(String.format(
2117-
"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.",
2118-
accountId, managedProjectIds
2119-
));
2113+
protected void checkIfAccountManagesProjects(long accountId) {
2114+
List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
2115+
2116+
if (CollectionUtils.isEmpty(managedProjectIds)) {
2117+
return;
2118+
}
2119+
2120+
List<Long> activeManagedProjects = new ArrayList<>();
2121+
2122+
for (Long projectId : managedProjectIds) {
2123+
ProjectVO project = _projectDao.findById(projectId);
2124+
if (project != null && project.getRemoved() == null) {
2125+
activeManagedProjects.add(projectId);
21202126
}
21212127
}
21222128

2129+
if (!activeManagedProjects.isEmpty()) {
2130+
throw new InvalidParameterValueException(String.format(
2131+
"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.",
2132+
accountId, activeManagedProjects
2133+
));
2134+
}
2135+
}
2136+
2137+
21232138
protected boolean isDeleteNeeded(AccountVO account, long accountId, Account caller) {
21242139
if (account == null) {
21252140
logger.info(String.format("The account, identified by id %d, doesn't exist", accountId ));

server/src/test/java/com/cloud/user/AccountManagerImplTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import java.util.HashMap;
2727
import java.util.List;
2828
import java.util.Map;
29+
import java.util.Date;
30+
2931

3032
import org.apache.cloudstack.acl.ControlledEntity;
3133
import org.apache.cloudstack.acl.Role;
@@ -75,6 +77,7 @@
7577
import com.cloud.vm.UserVmVO;
7678
import com.cloud.vm.VMInstanceVO;
7779
import com.cloud.vm.snapshot.VMSnapshotVO;
80+
import com.cloud.projects.ProjectVO;
7881

7982
@RunWith(MockitoJUnitRunner.class)
8083
public class AccountManagerImplTest extends AccountManagetImplTestBase {
@@ -1589,4 +1592,22 @@ public void testcheckCallerApiPermissionsForUserOperationsNotAllowedApis() {
15891592

15901593
accountManagerImpl.checkCallerApiPermissionsForUserOrAccountOperations(accountMock);
15911594
}
1595+
1596+
@Test
1597+
public void testCheckIfAccountManagesOnlyDeletedProjectsDoesNotThrow() {
1598+
long accountId = 42L;
1599+
long projectId = 100L;
1600+
1601+
Mockito.when(projectAccountDao.listAdministratedProjectIds(accountId))
1602+
.thenReturn(List.of(projectId));
1603+
1604+
ProjectVO deletedProject = Mockito.mock(ProjectVO.class);
1605+
Mockito.when(deletedProject.getRemoved()).thenReturn(new Date());
1606+
1607+
Mockito.when(projectDao.findById(projectId))
1608+
.thenReturn(deletedProject);
1609+
1610+
accountManager.checkIfAccountManagesProjects(accountId);
1611+
}
1612+
15921613
}

0 commit comments

Comments
 (0)