Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions server/src/main/java/com/cloud/user/AccountManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,9 @@ public Pair<Long, Account> doInTransaction(TransactionStatus status) {
- New role should not be of type Admin with domain other than ROOT domain
*/
protected void validateRoleChange(Account account, Role role, Account caller) {
if (account.getRoleId() == role.getId()) {
return;
}
Role currentRole = roleService.findRole(account.getRoleId());
Role callerRole = roleService.findRole(caller.getRoleId());
String errorMsg = String.format("Unable to update account role to %s, ", role.getName());
Expand All @@ -1413,6 +1416,9 @@ protected void validateRoleChange(Account account, Role role, Account caller) {
throw new PermissionDeniedException(String.format("%s as either current or new role has higher " +
"privileges than the caller", errorMsg));
}
if (account.isDefault()) {
throw new PermissionDeniedException(String.format("%s as the account is a default account", errorMsg));
}
if (role.getRoleType().equals(RoleType.Admin) && account.getDomainId() != Domain.ROOT_DOMAIN) {
throw new PermissionDeniedException(String.format("%s as the user does not belong to the ROOT domain",
errorMsg));
Expand Down
16 changes: 16 additions & 0 deletions server/src/test/java/com/cloud/user/AccountManagerImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,22 @@ public void testValidateRoleAdminCannotEscalateAdminFromNonRootDomain() {
accountManagerImpl.validateRoleChange(account, newRole, caller);
}

@Test(expected = PermissionDeniedException.class)
public void testValidateRoleAdminCannotChangeDefaultAdmin() {
Account account = Mockito.mock(Account.class);
Mockito.when(account.isDefault()).thenReturn(true);
Mockito.when(account.getRoleId()).thenReturn(1L);
Role newRole = Mockito.mock(Role.class);
Mockito.when(newRole.getRoleType()).thenReturn(RoleType.User);
Role callerRole = Mockito.mock(Role.class);
Mockito.when(callerRole.getRoleType()).thenReturn(RoleType.Admin);
Account caller = Mockito.mock(Account.class);
Mockito.when(caller.getRoleId()).thenReturn(2L);
Mockito.when(roleService.findRole(1L)).thenReturn(Mockito.mock(Role.class));
Mockito.when(roleService.findRole(2L)).thenReturn(callerRole);
accountManagerImpl.validateRoleChange(account, newRole, caller);
}

@Test
public void checkIfAccountManagesProjectsTestNotThrowExceptionWhenTheAccountIsNotAProjectAdministrator() {
long accountId = 1L;
Expand Down
6 changes: 4 additions & 2 deletions ui/src/views/iam/EditAccount.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
v-model:value="form.networkdomain"
:placeholder="apiParams.networkdomain.description" />
</a-form-item>
<a-form-item ref="roleid" name="roleid">
<a-form-item ref="roleid" name="roleid" v-if="!resource.isdefault">
<template #label>
<tooltip-label :title="$t('label.role')" :tooltip="apiParams.roleid.description"/>
</template>
Expand Down Expand Up @@ -145,11 +145,13 @@ export default {
const params = {
newname: values.newname,
networkdomain: values.networkdomain,
roleid: values.roleid,
apikeyaccess: values.apikeyaccess,
account: this.account,
domainid: this.domainId
}
if (values.roleid) {
params.roleid = values.roleid
}
if (this.isValidValueForKey(values, 'networkdomain') && values.networkdomain.length > 0) {
params.networkdomain = values.networkdomain
}
Expand Down