1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 13:23:34 +00:00

[AC-2171] Member modal - limit admin access - editing self (#8299)

* If editing your own member modal, you cannot add new collections or groups
  * Update forms to prevent this
  * Add helper text
* Delete unused api method
This commit is contained in:
Thomas Rittson
2024-03-15 09:33:15 +10:00
committed by GitHub
parent 1d76e80afb
commit 5506842623
9 changed files with 67 additions and 39 deletions

View File

@@ -399,7 +399,11 @@
</bit-tab>
<bit-tab *ngIf="organization.useGroups" [label]="'groups' | i18n">
<div class="tw-mb-6">
{{ "groupAccessUserDesc" | i18n }}
{{
(restrictedAccess$ | async)
? ("restrictedGroupAccess" | i18n)
: ("groupAccessUserDesc" | i18n)
}}
</div>
<bit-access-selector
formControlName="groups"
@@ -408,10 +412,14 @@
[selectorLabelText]="'selectGroups' | i18n"
[emptySelectionText]="'noGroupsAdded' | i18n"
[flexibleCollectionsEnabled]="organization.flexibleCollections"
[hideMultiSelect]="restrictedAccess$ | async"
></bit-access-selector>
</bit-tab>
<bit-tab [label]="'collections' | i18n">
<div *ngIf="organization.useGroups" class="tw-mb-6">
<div class="tw-mb-6" *ngIf="restrictedAccess$ | async">
{{ "restrictedCollectionAccess" | i18n }}
</div>
<div *ngIf="organization.useGroups && !(restrictedAccess$ | async)" class="tw-mb-6">
{{ "userPermissionOverrideHelper" | i18n }}
</div>
<div *ngIf="!organization.flexibleCollections" class="tw-mb-6">
@@ -441,6 +449,7 @@
[selectorLabelText]="'selectCollections' | i18n"
[emptySelectionText]="'noCollectionsAdded' | i18n"
[flexibleCollectionsEnabled]="organization.flexibleCollections"
[hideMultiSelect]="restrictedAccess$ | async"
></bit-access-selector
></bit-tab>
</bit-tab-group>

View File

@@ -4,6 +4,7 @@ import { FormBuilder, Validators } from "@angular/forms";
import {
combineLatest,
firstValueFrom,
map,
Observable,
of,
shareReplay,
@@ -20,7 +21,9 @@ import {
} from "@bitwarden/common/admin-console/enums";
import { PermissionsApi } from "@bitwarden/common/admin-console/models/api/permissions.api";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ProductType } from "@bitwarden/common/enums";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -99,6 +102,8 @@ export class MemberDialogComponent implements OnDestroy {
groups: [[] as AccessItemValue[]],
});
protected restrictedAccess$: Observable<boolean>;
protected permissionsGroup = this.formBuilder.group({
manageAssignedCollectionsGroup: this.formBuilder.group<Record<string, boolean>>({
manageAssignedCollections: false,
@@ -144,6 +149,7 @@ export class MemberDialogComponent implements OnDestroy {
private organizationUserService: OrganizationUserService,
private dialogService: DialogService,
private configService: ConfigServiceAbstraction,
private accountService: AccountService,
organizationService: OrganizationService,
) {
this.organization$ = organizationService
@@ -162,12 +168,42 @@ export class MemberDialogComponent implements OnDestroy {
),
);
const userDetails$ = this.params.organizationUserId
? this.userService.get(this.params.organizationId, this.params.organizationUserId)
: of(null);
// The orgUser cannot manage their own Group assignments if collection access is restricted
// TODO: fix disabled state of access-selector rows so that any controls are hidden
this.restrictedAccess$ = combineLatest([
this.organization$,
userDetails$,
this.accountService.activeAccount$,
this.configService.getFeatureFlag$(FeatureFlag.FlexibleCollectionsV1),
]).pipe(
map(
([organization, userDetails, activeAccount, flexibleCollectionsV1Enabled]) =>
// Feature flag conditionals
flexibleCollectionsV1Enabled &&
organization.flexibleCollections &&
// Business logic conditionals
userDetails.userId == activeAccount.id &&
!organization.allowAdminAccessToAllCollectionItems,
),
shareReplay({ refCount: true, bufferSize: 1 }),
);
this.restrictedAccess$.pipe(takeUntil(this.destroy$)).subscribe((restrictedAccess) => {
if (restrictedAccess) {
this.formGroup.controls.groups.disable();
} else {
this.formGroup.controls.groups.enable();
}
});
combineLatest({
organization: this.organization$,
collections: this.collectionAdminService.getAll(this.params.organizationId),
userDetails: this.params.organizationUserId
? this.userService.get(this.params.organizationId, this.params.organizationUserId)
: of(null),
userDetails: userDetails$,
groups: groups$,
})
.pipe(takeUntil(this.destroy$))
@@ -369,7 +405,11 @@ export class MemberDialogComponent implements OnDestroy {
userView.collections = this.formGroup.value.access
.filter((v) => v.type === AccessItemType.Collection)
.map(convertToSelectionView);
userView.groups = this.formGroup.value.groups.map((m) => m.id);
userView.groups = (await firstValueFrom(this.restrictedAccess$))
? null
: this.formGroup.value.groups.map((m) => m.id);
userView.accessSecretsManager = this.formGroup.value.accessSecretsManager;
if (this.editMode) {

View File

@@ -1,6 +1,6 @@
<!-- Please remove this disable statement when editing this file! -->
<!-- eslint-disable tailwindcss/no-custom-classname -->
<div class="tw-flex">
<div class="tw-flex" *ngIf="!hideMultiSelect">
<bit-form-field *ngIf="permissionMode == 'edit'" class="tw-mr-3 tw-shrink-0">
<bit-label>{{ "permission" | i18n }}</bit-label>
<!--

View File

@@ -197,6 +197,11 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On
this.permissionList = getPermissionList(value);
}
/**
* Hide the multi-select so that new items cannot be added
*/
@Input() hideMultiSelect = false;
private _flexibleCollectionsEnabled: boolean;
constructor(

View File

@@ -7605,5 +7605,11 @@
},
"providerPortal": {
"message": "Provider Portal"
},
"restrictedGroupAccess": {
"message": "You cannot add yourself to groups."
},
"restrictedCollectionAccess": {
"message": "You cannot add yourself to collections."
}
}