Skip to content

Commit 836f84a

Browse files
Surya SrinivasanSurya Srinivasan
authored andcommitted
Fix account deletion blocked by deleted project admin mappings
1 parent 408e8c0 commit 836f84a

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
@@ -2118,16 +2118,31 @@ public boolean deleteUserAccount(long accountId) {
21182118
return deleteAccount(account, callerUserId, caller);
21192119
}
21202120

2121-
protected void checkIfAccountManagesProjects(long accountId) {
2122-
List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
2123-
if (!CollectionUtils.isEmpty(managedProjectIds)) {
2124-
throw new InvalidParameterValueException(String.format(
2125-
"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.",
2126-
accountId, managedProjectIds
2127-
));
2121+
protected void checkIfAccountManagesProjects(long accountId) {
2122+
List<Long> managedProjectIds = _projectAccountDao.listAdministratedProjectIds(accountId);
2123+
2124+
if (CollectionUtils.isEmpty(managedProjectIds)) {
2125+
return;
2126+
}
2127+
2128+
List<Long> activeManagedProjects = new ArrayList<>();
2129+
2130+
for (Long projectId : managedProjectIds) {
2131+
ProjectVO project = _projectDao.findById(projectId);
2132+
if (project != null && project.getRemoved() == null) {
2133+
activeManagedProjects.add(projectId);
21282134
}
21292135
}
21302136

2137+
if (!activeManagedProjects.isEmpty()) {
2138+
throw new InvalidParameterValueException(String.format(
2139+
"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.",
2140+
accountId, activeManagedProjects
2141+
));
2142+
}
2143+
}
2144+
2145+
21312146
protected boolean isDeleteNeeded(AccountVO account, long accountId, Account caller) {
21322147
if (account == null) {
21332148
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 {
@@ -1592,4 +1595,22 @@ public void testcheckCallerApiPermissionsForUserOperationsNotAllowedApis() {
15921595

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

0 commit comments

Comments
 (0)