server,ui: prevent role change for default accounts (#11761)

* server,ui: prevent role change for default accounts

Fixes #10931

Role for default accounts shouldn't be changed. Appropriate error should be returned by the server and UI should not present option for them.

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>

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

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Abhishek Kumar 2025-12-12 13:42:26 +01:00 committed by GitHub
parent 79ebf6959e
commit e1c48c3adc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 2 deletions

View File

@ -1398,6 +1398,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
- 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() != null && account.getRoleId().equals(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());
@ -1413,6 +1416,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
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));

View File

@ -1365,6 +1365,22 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase {
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;

View File

@ -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>
@ -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
}