<div
class="form-item"
*ngIf="allRoles"
+ [class.roles-clear-disabled]="isAdminRoleProtected"
>
<cds-combo-box
label="Roles"
[cdRequiredField]="!isSSO ? 'Roles' : ''"
[invalid]="!userForm.controls.roles.valid && userForm.controls.roles.dirty"
[invalidText]="rolesError"
+ (clear)="onRolesClear()"
i18n
>
- <cds-dropdown-list [listTpl]="roleItemTpl"></cds-dropdown-list>
+ <cds-dropdown-list></cds-dropdown-list>
</cds-combo-box>
<ng-template #rolesError>
class="invalid-feedback"
*ngIf="userForm.showError('roles', formDir, 'required')"
i18n
- >This field is required.</span>
- </ng-template>
-
- <ng-template #roleItemTpl
- let-item="item">
- <div class="cds--form-item cds--checkbox-wrapper">
- <label class="cds--checkbox-label"
- [attr.data-contained-checkbox-disabled]="item.disabled ? 'true' : null"
- [attr.data-contained-checkbox-state]="item.selected ? 'true' : 'false'"
- [ngbTooltip]="item.disabled ? roleTooltipTpl : null">
- <input class="cds--checkbox"
- type="checkbox"
- [checked]="item.selected"
- [disabled]="item.disabled"
- tabindex="-1"/>
- <span class="cds--checkbox-appearance"></span>
- <span class="cds--checkbox-label-text">{{ item.content }}</span>
- </label>
- </div>
- </ng-template>
-
- <ng-template #roleTooltipTpl>
- <span i18n>You cannot remove the administrator role from your own account.</span>
+ >This field is required.</span
+ >
</ng-template>
</div>
<!-- Enabled -->
+.roles-clear-disabled {
+ cds-combo-box .cds--list-box__selection--multi {
+ pointer-events: none;
+ cursor: not-allowed;
+ opacity: 0.5;
+ }
+}
beforeEach(() => {
spyOn(userService, 'get').and.callFake(() => of(user));
spyOn(TestBed.inject(RoleService), 'list').and.callFake(() => of(roles));
+ spyOn(TestBed.inject(AuthStorageService), 'getUsername').and.returnValue(user.username);
setUrl('/user-management/users/edit/user1');
spyOn(TestBed.inject(SettingsService), 'getStandardSettings').and.callFake(() =>
of({
expect(form.get('confirmpassword').valid).toBeTruthy();
});
+ it('should disable administrator role for current user', () => {
+ const administratorRole = component.allRoles.find((role) => role.name === 'administrator');
+ expect(administratorRole.disabled).toBeTruthy();
+ expect(component.disableRolesClearButton()).toBeTruthy();
+ });
+
+ it('should restore roles when clear is triggered for current user with protected admin role', () => {
+ formHelper.setValue('roles', []);
+ component.onRolesClear();
+ expect(form.getValue('roles')).toContain('administrator');
+ });
+
it('should alert if user is removing needed role permission', () => {
- spyOn(TestBed.inject(AuthStorageService), 'getUsername').and.callFake(() => user.username);
let modalBodyTpl = null;
spyOn(modalService, 'show').and.callFake((_content, initialState) => {
modalBodyTpl = initialState.bodyTpl;
});
it('should logout if current user roles have been changed', () => {
- spyOn(TestBed.inject(AuthStorageService), 'getUsername').and.callFake(() => user.username);
formHelper.setValue('roles', ['user-manager']);
component.submit();
const userReq = httpTesting.expectOne(`api/user/${user.username}`);
});
it('should submit', () => {
- spyOn(TestBed.inject(AuthStorageService), 'getUsername').and.callFake(() => user.username);
component.submit();
const userReq = httpTesting.expectOne(`api/user/${user.username}`);
expect(userReq.request.method).toBe('PUT');
-import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
+import { Component, OnInit, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
import { Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
selector: 'cd-user-form',
templateUrl: './user-form.component.html',
styleUrls: ['./user-form.component.scss'],
- standalone: false
+ standalone: false,
+ encapsulation: ViewEncapsulation.None
})
export class UserFormComponent extends CdForm implements OnInit {
@ViewChild('removeSelfUserReadUpdatePermissionTpl', { static: true })
selectedRole: string[];
passwordexp: boolean = false;
isSSO = false;
+ isAdminRoleProtected: boolean = false;
+
constructor(
private authService: AuthService,
private authStorageService: AuthStorageService,
this.userService.get(username).subscribe((userFormModel: UserFormModel) => {
this.response = _.cloneDeep(userFormModel);
this.setResponse(userFormModel);
- if (this.authStorageService.getUsername() === username) {
- this.allRoles = _.map(this.allRoles, (role) => {
- role.disabled =
- role.name.toLowerCase() === 'administrator' && this.isCurrentUser() ? true : false;
- return role;
- });
+ if (this.authStorageService.getUsername() === userFormModel.username) {
+ this.allRoles = _.map(this.allRoles, (role) => ({
+ ...role,
+ disabled: role.name.toLowerCase() === 'administrator'
+ }));
}
+ this.isAdminRoleProtected = this.disableRolesClearButton();
this.loadingReady();
});
});
return this.authStorageService.getUsername() === this.userForm.getValue('username');
}
+ disableRolesClearButton(): boolean {
+ if (!this.isCurrentUser() || !this.allRoles) {
+ return false;
+ }
+ const administratorRole = this.allRoles.find(
+ (role) => role.name.toLowerCase() === 'administrator'
+ );
+ return !!administratorRole?.disabled;
+ }
+
+ onRolesClear(): void {
+ if (!this.disableRolesClearButton()) {
+ return;
+ }
+ const roles = this.userForm.getValue('roles') ?? [];
+ if (!roles.includes('administrator')) {
+ this.userForm.get('roles').setValue([...roles, 'administrator'], { emitEvent: false });
+ }
+ }
+
private isUserChangingRoles(): boolean {
const isCurrentUser = this.isCurrentUser();
return (