[AC-1122] Add new admin access to all collections and items settings (#6703)

* [AC-1117] Add manage permission (#5910)

* Add 'manage' option to collection access permissions

* Add 'manage' to collection permissions

* remove service accidentally committed from another branch

* Update CLI commands

* update message casing to be consistent

* access selector model updates

* [AC-1374] Limit collection create/delete (#5963)

* feat: udate request/response/data/domain models for new column, refs AC-1374

* feat: create collection management ui, refs AC-1374

* fix: remove limitCollectionCdOwnerAdmin boolean from org update request, refs AC-1374

* fix: moved collection management UI, removed comments, refs AC-1374

* fix: observable chaining now properly calls API when local org updated, refs AC-1374

* fix: remove unused form template variables, refs AC-1374

* fix: clean up observable chain, refs AC-1374

* fix: remove parent.parent route, refs AC-1374

* fix: add cd explaination, refs AC-1374

* [AC-1649] Remove organizationId from collection-bulk-delete.request (#6343)

* refactor: remove organizationId from collection-bulk-delete-request, refs AC-1649

* refactor: remove request model from dialog component, refs AC-1649

* [AC-1174] Bulk collection management (#6133)

* [AC-1174] Add bulk edit collection access event type

* [AC-1174] Add bulk edit collection access menu option

* [AC-1174] Add initial bulk collections access dialog

* [AC-1174] Add logic to open bulk edit collections dialog

* [AC-1174] Move AccessItemView helper methods to access selector model to be shared

* [AC-1174] Add access selector to bulk collections dialog

* [AC-1174] Add bulk assign access method to collection-admin service

* [AC-1174] Introduce strongly typed BulkCollectionAccessRequest model

* [AC-1174] Update vault item event type name

* Update DialogService dependency

---------

Co-authored-by: Thomas Rittson <trittson@bitwarden.com>

* Rename LimitCollectionCdOwnerAdmin -> LimitCollectionCreationDeletion (#6409)

* Add manage property to synced Collection data

* Revert "Add manage property to synced Collection data"

Pushed to feature branch instead of a new one

This reverts commit 65cd39589c.

* Add manage property to synced Collection data

* Revert "Add manage property to synced Collection data"

This reverts commit f7fa30b79a.

* [AC-1680] Add manage property to collection view and response models (#6417)

* Add manage property to synced Collection data

* Update tests

* feat: add LimitCollectionCreationDeletion conditional to canCreateNewCollections logic, refs AC-1659 (#6429)

* [AC-1669] Enforce Can Manage permission on Collection dialog (#6493)

* [AC-1669] Cleanup unhandled promise warnings

* [AC-1669] Force change detection to ensure AccessSelector has the most recent items

* [AC-1669] Initially select acting member when creating a new collection

* [AC-1669] Add validator to ensure manage permission is selected

* [AC-1669] Update error toast logic to support access tab errors

* [AC-1669] Add error icon

* [AC-1713] [Flexible collections] Add feature flags to clients (#6486)

* Add FlexibleCollections and BulkCollectionAccess flags

* Flag Collection Management settings

* Flag bulk collection access dialog

* Flag collection access modal changes

* [AC-1662] Add LimitCollecitonCreationDeletion conditional to CanDelete logic (#6526)

* feat: implement limitCollectionCreationDeletion into canDelete logic, refs AC-1662

* feat: make canDelete functions backwards compatible with feature flag, refs AC-1662

* feat: update vault-items.component for async getter, refs AC-1662

* feat: update configService injection, refs AC-1662

* feat: add config service to canDelete reference, refs AC-1662

* fix: remove configservice dependency from views, refs AC-1757 (#6686)

* Add missing provider to vault-items.stories (#6690)

* [AC-1730] Add new AllowAdminAccessToAllCollectionItems setting to org response models

* [AC-1730] Add new AllowAdminAccessToAllCollectionItems setting to org request model

* [AC-1730] Add new collection setting to UI and include it when submitting

* [AC-1122] Add V1 feature flag

* [AC-1122] Hide new setting behind V1 feature flag

* [AC-1122] Add support for disabled form control

---------

Co-authored-by: Robyn MacCallum <robyntmaccallum@gmail.com>
Co-authored-by: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com>
Co-authored-by: Vincent Salucci <vincesalucci21@gmail.com>
Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
This commit is contained in:
Shane Melton 2023-11-27 11:44:15 -08:00 committed by GitHub
parent 9017c0ed16
commit f82f9ba0d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 32 additions and 3 deletions

View File

@ -53,12 +53,16 @@
</button> </button>
</ng-container> </ng-container>
<form <form
*ngIf="org && !loading && (showCollectionManagementSettings$ | async)" *ngIf="org && !loading && (flexibleCollectionsEnabled$ | async)"
[bitSubmit]="submitCollectionManagement" [bitSubmit]="submitCollectionManagement"
[formGroup]="collectionManagementFormGroup" [formGroup]="collectionManagementFormGroup"
> >
<h1 bitTypography="h1" class="tw-mt-16 tw-pb-2.5">{{ "collectionManagement" | i18n }}</h1> <h1 bitTypography="h1" class="tw-mt-16 tw-pb-2.5">{{ "collectionManagement" | i18n }}</h1>
<p>{{ "collectionManagementDesc" | i18n }}</p> <p>{{ "collectionManagementDesc" | i18n }}</p>
<bit-form-control *ngIf="flexibleCollectionsV1Enabled$ | async">
<bit-label>{{ "allowAdminAccessToAllCollectionItemsDesc" | i18n }}</bit-label>
<input type="checkbox" bitCheckbox formControlName="allowAdminAccessToAllCollectionItems" />
</bit-form-control>
<bit-form-control> <bit-form-control>
<bit-label>{{ "limitCollectionCreationDeletionDesc" | i18n }}</bit-label> <bit-label>{{ "limitCollectionCreationDeletionDesc" | i18n }}</bit-label>
<input type="checkbox" bitCheckbox formControlName="limitCollectionCreationDeletion" /> <input type="checkbox" bitCheckbox formControlName="limitCollectionCreationDeletion" />

View File

@ -1,7 +1,7 @@
import { Component, ViewChild, ViewContainerRef } from "@angular/core"; import { Component, ViewChild, ViewContainerRef } from "@angular/core";
import { FormBuilder, Validators } from "@angular/forms"; import { FormBuilder, Validators } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router"; import { ActivatedRoute, Router } from "@angular/router";
import { combineLatest, lastValueFrom, Subject, switchMap, takeUntil, from, of } from "rxjs"; import { combineLatest, from, lastValueFrom, of, Subject, switchMap, takeUntil } from "rxjs";
import { ModalService } from "@bitwarden/angular/services/modal.service"; import { ModalService } from "@bitwarden/angular/services/modal.service";
import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
@ -41,10 +41,14 @@ export class AccountComponent {
canUseApi = false; canUseApi = false;
org: OrganizationResponse; org: OrganizationResponse;
taxFormPromise: Promise<unknown>; taxFormPromise: Promise<unknown>;
showCollectionManagementSettings$ = this.configService.getFeatureFlag$( flexibleCollectionsEnabled$ = this.configService.getFeatureFlag$(
FeatureFlag.FlexibleCollections, FeatureFlag.FlexibleCollections,
false false
); );
flexibleCollectionsV1Enabled$ = this.configService.getFeatureFlag$(
FeatureFlag.FlexibleCollectionsV1,
false
);
// FormGroup validators taken from server Organization domain object // FormGroup validators taken from server Organization domain object
protected formGroup = this.formBuilder.group({ protected formGroup = this.formBuilder.group({
@ -67,6 +71,10 @@ export class AccountComponent {
protected collectionManagementFormGroup = this.formBuilder.group({ protected collectionManagementFormGroup = this.formBuilder.group({
limitCollectionCreationDeletion: this.formBuilder.control({ value: false, disabled: true }), limitCollectionCreationDeletion: this.formBuilder.control({ value: false, disabled: true }),
allowAdminAccessToAllCollectionItems: this.formBuilder.control({
value: false,
disabled: true,
}),
}); });
protected organizationId: string; protected organizationId: string;
@ -115,6 +123,7 @@ export class AccountComponent {
if (!this.selfHosted) { if (!this.selfHosted) {
this.formGroup.get("orgName").enable(); this.formGroup.get("orgName").enable();
this.collectionManagementFormGroup.get("limitCollectionCreationDeletion").enable(); this.collectionManagementFormGroup.get("limitCollectionCreationDeletion").enable();
this.collectionManagementFormGroup.get("allowAdminAccessToAllCollectionItems").enable();
} }
if (!this.selfHosted || this.canEditSubscription) { if (!this.selfHosted || this.canEditSubscription) {
@ -136,6 +145,7 @@ export class AccountComponent {
}); });
this.collectionManagementFormGroup.patchValue({ this.collectionManagementFormGroup.patchValue({
limitCollectionCreationDeletion: this.org.limitCollectionCreationDeletion, limitCollectionCreationDeletion: this.org.limitCollectionCreationDeletion,
allowAdminAccessToAllCollectionItems: this.org.allowAdminAccessToAllCollectionItems,
}); });
this.loading = false; this.loading = false;
@ -180,6 +190,8 @@ export class AccountComponent {
const request = new OrganizationCollectionManagementUpdateRequest(); const request = new OrganizationCollectionManagementUpdateRequest();
request.limitCreateDeleteOwnerAdmin = request.limitCreateDeleteOwnerAdmin =
this.collectionManagementFormGroup.value.limitCollectionCreationDeletion; this.collectionManagementFormGroup.value.limitCollectionCreationDeletion;
request.allowAdminAccessToAllCollectionItems =
this.collectionManagementFormGroup.value.allowAdminAccessToAllCollectionItems;
await this.organizationApiService.updateCollectionManagement(this.organizationId, request); await this.organizationApiService.updateCollectionManagement(this.organizationId, request);

View File

@ -7322,6 +7322,9 @@
"limitCollectionCreationDeletionDesc": { "limitCollectionCreationDeletionDesc": {
"message": "Limit collection creation and deletion to owners and admins" "message": "Limit collection creation and deletion to owners and admins"
}, },
"allowAdminAccessToAllCollectionItemsDesc": {
"message": "Owners and admins can manage all collections and items"
},
"collectionManagementUpdated": { "collectionManagementUpdated": {
"message": "Collection management behavior saved" "message": "Collection management behavior saved"
}, },

View File

@ -1,3 +1,4 @@
export class OrganizationCollectionManagementUpdateRequest { export class OrganizationCollectionManagementUpdateRequest {
limitCreateDeleteOwnerAdmin: boolean; limitCreateDeleteOwnerAdmin: boolean;
allowAdminAccessToAllCollectionItems: boolean;
} }

View File

@ -33,6 +33,7 @@ export class OrganizationResponse extends BaseResponse {
maxAutoscaleSmSeats?: number; maxAutoscaleSmSeats?: number;
maxAutoscaleSmServiceAccounts?: number; maxAutoscaleSmServiceAccounts?: number;
limitCollectionCreationDeletion: boolean; limitCollectionCreationDeletion: boolean;
allowAdminAccessToAllCollectionItems: boolean;
constructor(response: any) { constructor(response: any) {
super(response); super(response);
@ -71,5 +72,8 @@ export class OrganizationResponse extends BaseResponse {
this.limitCollectionCreationDeletion = this.getResponseProperty( this.limitCollectionCreationDeletion = this.getResponseProperty(
"LimitCollectionCreationDeletion" "LimitCollectionCreationDeletion"
); );
this.allowAdminAccessToAllCollectionItems = this.getResponseProperty(
"AllowAdminAccessToAllCollectionItems"
);
} }
} }

View File

@ -49,6 +49,7 @@ export class ProfileOrganizationResponse extends BaseResponse {
familySponsorshipToDelete?: boolean; familySponsorshipToDelete?: boolean;
accessSecretsManager: boolean; accessSecretsManager: boolean;
limitCollectionCreationDeletion: boolean; limitCollectionCreationDeletion: boolean;
allowAdminAccessToAllCollectionItems: boolean;
constructor(response: any) { constructor(response: any) {
super(response); super(response);
@ -109,5 +110,8 @@ export class ProfileOrganizationResponse extends BaseResponse {
this.limitCollectionCreationDeletion = this.getResponseProperty( this.limitCollectionCreationDeletion = this.getResponseProperty(
"LimitCollectionCreationDeletion" "LimitCollectionCreationDeletion"
); );
this.allowAdminAccessToAllCollectionItems = this.getResponseProperty(
"AllowAdminAccessToAllCollectionItems"
);
} }
} }

View File

@ -8,6 +8,7 @@ export enum FeatureFlag {
BrowserFilelessImport = "browser-fileless-import", BrowserFilelessImport = "browser-fileless-import",
ItemShare = "item-share", ItemShare = "item-share",
FlexibleCollections = "flexible-collections", FlexibleCollections = "flexible-collections",
FlexibleCollectionsV1 = "flexible-collections-v-1", // v-1 is intentional
BulkCollectionAccess = "bulk-collection-access", BulkCollectionAccess = "bulk-collection-access",
} }