mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-21 16:18:28 +01:00
[AC-2320] Update canEditAnyCollection logic for Flexible Collections v1 (#8394)
* also update calling locations to use canEditAllCiphers where applicable
This commit is contained in:
parent
678ba04781
commit
32981ce30d
@ -45,6 +45,7 @@ export class VaultItemsComponent {
|
||||
@Input() showBulkAddToCollections = false;
|
||||
@Input() showPermissionsColumn = false;
|
||||
@Input() viewingOrgVault: boolean;
|
||||
@Input({ required: true }) flexibleCollectionsV1Enabled = false;
|
||||
|
||||
private _ciphers?: CipherView[] = [];
|
||||
@Input() get ciphers(): CipherView[] {
|
||||
@ -101,7 +102,7 @@ export class VaultItemsComponent {
|
||||
}
|
||||
|
||||
const organization = this.allOrganizations.find((o) => o.id === collection.organizationId);
|
||||
return collection.canEdit(organization);
|
||||
return collection.canEdit(organization, this.flexibleCollectionsV1Enabled);
|
||||
}
|
||||
|
||||
protected canDeleteCollection(collection: CollectionView): boolean {
|
||||
|
@ -31,10 +31,11 @@ export class CollectionAdminView extends CollectionView {
|
||||
this.assigned = response.assigned;
|
||||
}
|
||||
|
||||
override canEdit(org: Organization): boolean {
|
||||
override canEdit(org: Organization, flexibleCollectionsV1Enabled: boolean): boolean {
|
||||
return org?.flexibleCollections
|
||||
? org?.canEditAnyCollection || this.manage
|
||||
: org?.canEditAnyCollection || (org?.canEditAssignedCollections && this.assigned);
|
||||
? org?.canEditAnyCollection(flexibleCollectionsV1Enabled) || this.manage
|
||||
: org?.canEditAnyCollection(flexibleCollectionsV1Enabled) ||
|
||||
(org?.canEditAssignedCollections && this.assigned);
|
||||
}
|
||||
|
||||
override canDelete(org: Organization): boolean {
|
||||
|
@ -1,8 +1,11 @@
|
||||
import { DialogConfig, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
@ -49,6 +52,11 @@ export class BulkDeleteDialogComponent {
|
||||
organizations: Organization[];
|
||||
collections: CollectionView[];
|
||||
|
||||
private flexibleCollectionsV1Enabled$ = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.FlexibleCollectionsV1,
|
||||
false,
|
||||
);
|
||||
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) params: BulkDeleteDialogParams,
|
||||
private dialogRef: DialogRef<BulkDeleteDialogResult>,
|
||||
@ -57,6 +65,7 @@ export class BulkDeleteDialogComponent {
|
||||
private i18nService: I18nService,
|
||||
private apiService: ApiService,
|
||||
private collectionService: CollectionService,
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
this.cipherIds = params.cipherIds ?? [];
|
||||
this.permanent = params.permanent;
|
||||
@ -72,7 +81,12 @@ export class BulkDeleteDialogComponent {
|
||||
protected submit = async () => {
|
||||
const deletePromises: Promise<void>[] = [];
|
||||
if (this.cipherIds.length) {
|
||||
if (!this.organization || !this.organization.canEditAnyCollection) {
|
||||
const flexibleCollectionsV1Enabled = await firstValueFrom(this.flexibleCollectionsV1Enabled$);
|
||||
|
||||
if (
|
||||
!this.organization ||
|
||||
!this.organization.canEditAllCiphers(flexibleCollectionsV1Enabled)
|
||||
) {
|
||||
deletePromises.push(this.deleteCiphers());
|
||||
} else {
|
||||
deletePromises.push(this.deleteCiphersAdmin());
|
||||
@ -104,7 +118,8 @@ export class BulkDeleteDialogComponent {
|
||||
};
|
||||
|
||||
private async deleteCiphers(): Promise<any> {
|
||||
const asAdmin = this.organization?.canEditAnyCollection;
|
||||
const flexibleCollectionsV1Enabled = await firstValueFrom(this.flexibleCollectionsV1Enabled$);
|
||||
const asAdmin = this.organization?.canEditAllCiphers(flexibleCollectionsV1Enabled);
|
||||
if (this.permanent) {
|
||||
await this.cipherService.deleteManyWithServer(this.cipherIds, asAdmin);
|
||||
} else {
|
||||
|
@ -1,6 +1,16 @@
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from "@angular/core";
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
} from "@angular/core";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
|
||||
import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view";
|
||||
@ -17,7 +27,7 @@ import {
|
||||
templateUrl: "./vault-header.component.html",
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class VaultHeaderComponent {
|
||||
export class VaultHeaderComponent implements OnInit {
|
||||
protected Unassigned = Unassigned;
|
||||
protected All = All;
|
||||
protected CollectionDialogTabType = CollectionDialogTabType;
|
||||
@ -55,7 +65,18 @@ export class VaultHeaderComponent {
|
||||
/** Emits an event when the delete collection button is clicked in the header */
|
||||
@Output() onDeleteCollection = new EventEmitter<void>();
|
||||
|
||||
constructor(private i18nService: I18nService) {}
|
||||
private flexibleCollectionsV1Enabled = false;
|
||||
|
||||
constructor(
|
||||
private i18nService: I18nService,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.flexibleCollectionsV1Enabled = await firstValueFrom(
|
||||
this.configService.getFeatureFlag$(FeatureFlag.FlexibleCollectionsV1),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the organization that is currently being filtered on.
|
||||
@ -137,7 +158,7 @@ export class VaultHeaderComponent {
|
||||
const organization = this.organizations.find(
|
||||
(o) => o.id === this.collection?.node.organizationId,
|
||||
);
|
||||
return this.collection.node.canEdit(organization);
|
||||
return this.collection.node.canEdit(organization, this.flexibleCollectionsV1Enabled);
|
||||
}
|
||||
|
||||
async editCollection(tab: CollectionDialogTabType): Promise<void> {
|
||||
|
@ -50,6 +50,7 @@
|
||||
[cloneableOrganizationCiphers]="false"
|
||||
[showAdminActions]="false"
|
||||
(onEvent)="onVaultItemsEvent($event)"
|
||||
[flexibleCollectionsV1Enabled]="flexibleCollectionsV1Enabled$ | async"
|
||||
>
|
||||
</app-vault-items>
|
||||
<div
|
||||
|
@ -39,6 +39,7 @@ import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"
|
||||
import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { EventType } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@ -144,6 +145,10 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
protected selectedCollection: TreeNode<CollectionView> | undefined;
|
||||
protected canCreateCollections = false;
|
||||
protected currentSearchText$: Observable<string>;
|
||||
protected flexibleCollectionsV1Enabled$ = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.FlexibleCollectionsV1,
|
||||
false,
|
||||
);
|
||||
|
||||
private searchText$ = new Subject<string>();
|
||||
private refresh$ = new BehaviorSubject<void>(null);
|
||||
|
@ -1,8 +1,11 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@ -21,10 +24,12 @@ import { AttachmentsComponent as BaseAttachmentsComponent } from "../individual-
|
||||
selector: "app-org-vault-attachments",
|
||||
templateUrl: "../individual-vault/attachments.component.html",
|
||||
})
|
||||
export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
export class AttachmentsComponent extends BaseAttachmentsComponent implements OnInit {
|
||||
viewOnly = false;
|
||||
organization: Organization;
|
||||
|
||||
private flexibleCollectionsV1Enabled = false;
|
||||
|
||||
constructor(
|
||||
cipherService: CipherService,
|
||||
i18nService: I18nService,
|
||||
@ -36,6 +41,7 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
fileDownloadService: FileDownloadService,
|
||||
dialogService: DialogService,
|
||||
billingAccountProfileStateService: BillingAccountProfileStateService,
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
super(
|
||||
cipherService,
|
||||
@ -51,14 +57,24 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
);
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
await super.ngOnInit();
|
||||
this.flexibleCollectionsV1Enabled = await firstValueFrom(
|
||||
this.configService.getFeatureFlag$(FeatureFlag.FlexibleCollectionsV1, false),
|
||||
);
|
||||
}
|
||||
|
||||
protected async reupload(attachment: AttachmentView) {
|
||||
if (this.organization.canEditAnyCollection && this.showFixOldAttachments(attachment)) {
|
||||
if (
|
||||
this.organization.canEditAllCiphers(this.flexibleCollectionsV1Enabled) &&
|
||||
this.showFixOldAttachments(attachment)
|
||||
) {
|
||||
await super.reuploadCipherAttachment(attachment, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected async loadCipher() {
|
||||
if (!this.organization.canEditAnyCollection) {
|
||||
if (!this.organization.canEditAllCiphers(this.flexibleCollectionsV1Enabled)) {
|
||||
return await super.loadCipher();
|
||||
}
|
||||
const response = await this.apiService.getCipherAdmin(this.cipherId);
|
||||
@ -69,18 +85,21 @@ export class AttachmentsComponent extends BaseAttachmentsComponent {
|
||||
return this.cipherService.saveAttachmentWithServer(
|
||||
this.cipherDomain,
|
||||
file,
|
||||
this.organization.canEditAnyCollection,
|
||||
this.organization.canEditAllCiphers(this.flexibleCollectionsV1Enabled),
|
||||
);
|
||||
}
|
||||
|
||||
protected deleteCipherAttachment(attachmentId: string) {
|
||||
if (!this.organization.canEditAnyCollection) {
|
||||
if (!this.organization.canEditAllCiphers(this.flexibleCollectionsV1Enabled)) {
|
||||
return super.deleteCipherAttachment(attachmentId);
|
||||
}
|
||||
return this.apiService.deleteCipherAttachmentAdmin(this.cipherId, attachmentId);
|
||||
}
|
||||
|
||||
protected showFixOldAttachments(attachment: AttachmentView) {
|
||||
return attachment.key == null && this.organization.canEditAnyCollection;
|
||||
return (
|
||||
attachment.key == null &&
|
||||
this.organization.canEditAllCiphers(this.flexibleCollectionsV1Enabled)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
import { Component, EventEmitter, Input, Output } from "@angular/core";
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { ProductType } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
|
||||
import { DialogService, SimpleDialogOptions } from "@bitwarden/components";
|
||||
@ -22,7 +24,7 @@ import {
|
||||
selector: "app-org-vault-header",
|
||||
templateUrl: "./vault-header.component.html",
|
||||
})
|
||||
export class VaultHeaderComponent {
|
||||
export class VaultHeaderComponent implements OnInit {
|
||||
protected All = All;
|
||||
protected Unassigned = Unassigned;
|
||||
|
||||
@ -56,14 +58,23 @@ export class VaultHeaderComponent {
|
||||
protected CollectionDialogTabType = CollectionDialogTabType;
|
||||
protected organizations$ = this.organizationService.organizations$;
|
||||
|
||||
private flexibleCollectionsV1Enabled = false;
|
||||
|
||||
constructor(
|
||||
private organizationService: OrganizationService,
|
||||
private i18nService: I18nService,
|
||||
private dialogService: DialogService,
|
||||
private collectionAdminService: CollectionAdminService,
|
||||
private router: Router,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
this.flexibleCollectionsV1Enabled = await firstValueFrom(
|
||||
this.configService.getFeatureFlag$(FeatureFlag.FlexibleCollectionsV1),
|
||||
);
|
||||
}
|
||||
|
||||
get title() {
|
||||
const headerType = this.organization?.flexibleCollections
|
||||
? this.i18nService.t("collections").toLowerCase()
|
||||
@ -153,7 +164,7 @@ export class VaultHeaderComponent {
|
||||
}
|
||||
|
||||
// Otherwise, check if we can edit the specified collection
|
||||
return this.collection.node.canEdit(this.organization);
|
||||
return this.collection.node.canEdit(this.organization, this.flexibleCollectionsV1Enabled);
|
||||
}
|
||||
|
||||
addCipher() {
|
||||
|
@ -54,6 +54,7 @@
|
||||
[showBulkEditCollectionAccess]="organization?.flexibleCollections"
|
||||
[showBulkAddToCollections]="organization?.flexibleCollections"
|
||||
[viewingOrgVault]="true"
|
||||
[flexibleCollectionsV1Enabled]="flexibleCollectionsV1Enabled"
|
||||
>
|
||||
</app-vault-items>
|
||||
<ng-container *ngIf="!flexibleCollectionsV1Enabled">
|
||||
@ -98,7 +99,10 @@
|
||||
</bit-no-items>
|
||||
<collection-access-restricted
|
||||
*ngIf="showCollectionAccessRestricted"
|
||||
[canEdit]="selectedCollection != null && selectedCollection.node.canEdit(organization)"
|
||||
[canEdit]="
|
||||
selectedCollection != null &&
|
||||
selectedCollection.node.canEdit(organization, flexibleCollectionsV1Enabled)
|
||||
"
|
||||
(editInfoClicked)="editCollection(selectedCollection.node, CollectionDialogTabType.Info)"
|
||||
>
|
||||
</collection-access-restricted>
|
||||
|
@ -213,7 +213,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
switchMap(async ([organization]) => {
|
||||
this.organization = organization;
|
||||
|
||||
if (!organization.canUseAdminCollections) {
|
||||
if (!organization.canUseAdminCollections(this.flexibleCollectionsV1Enabled)) {
|
||||
await this.syncService.fullSync(false);
|
||||
}
|
||||
|
||||
@ -322,7 +322,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
} else {
|
||||
// Pre-flexible collections logic, to be removed after flexible collections is fully released
|
||||
if (organization.canEditAnyCollection) {
|
||||
if (organization.canEditAllCiphers(this.flexibleCollectionsV1Enabled)) {
|
||||
ciphers = await this.cipherService.getAllFromApiForOrganization(organization.id);
|
||||
} else {
|
||||
ciphers = (await this.cipherService.getAllDecrypted()).filter(
|
||||
@ -407,7 +407,8 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
]).pipe(
|
||||
map(([filter, collection, organization]) => {
|
||||
return (
|
||||
(filter.collectionId === Unassigned && !organization.canUseAdminCollections) ||
|
||||
(filter.collectionId === Unassigned &&
|
||||
!organization.canUseAdminCollections(this.flexibleCollectionsV1Enabled)) ||
|
||||
(!organization.canEditAllCiphers(this.flexibleCollectionsV1Enabled) &&
|
||||
collection != undefined &&
|
||||
!collection.node.assigned)
|
||||
@ -453,11 +454,12 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
map(([filter, collection, organization]) => {
|
||||
return (
|
||||
// Filtering by unassigned, show message if not admin
|
||||
(filter.collectionId === Unassigned && !organization.canUseAdminCollections) ||
|
||||
(filter.collectionId === Unassigned &&
|
||||
!organization.canUseAdminCollections(this.flexibleCollectionsV1Enabled)) ||
|
||||
// Filtering by a collection, so show message if user is not assigned
|
||||
(collection != undefined &&
|
||||
!collection.node.assigned &&
|
||||
!organization.canUseAdminCollections)
|
||||
!organization.canUseAdminCollections(this.flexibleCollectionsV1Enabled))
|
||||
);
|
||||
}),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
@ -480,7 +482,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
(await firstValueFrom(allCipherMap$))[cipherId] != undefined;
|
||||
} else {
|
||||
canEditCipher =
|
||||
organization.canUseAdminCollections ||
|
||||
organization.canUseAdminCollections(this.flexibleCollectionsV1Enabled) ||
|
||||
(await this.cipherService.get(cipherId)) != null;
|
||||
}
|
||||
|
||||
@ -856,7 +858,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
try {
|
||||
const asAdmin = this.organization?.canEditAnyCollection;
|
||||
const asAdmin = this.organization?.canEditAnyCollection(this.flexibleCollectionsV1Enabled);
|
||||
await this.cipherService.restoreWithServer(c.id, asAdmin);
|
||||
this.platformUtilsService.showToast("success", null, this.i18nService.t("restoredItem"));
|
||||
this.refresh();
|
||||
@ -1143,7 +1145,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
protected deleteCipherWithServer(id: string, permanent: boolean) {
|
||||
const asAdmin = this.organization?.canEditAnyCollection;
|
||||
const asAdmin = this.organization?.canEditAllCiphers(this.flexibleCollectionsV1Enabled);
|
||||
return permanent
|
||||
? this.cipherService.deleteWithServer(id, asAdmin)
|
||||
: this.cipherService.softDeleteWithServer(id, asAdmin);
|
||||
|
@ -662,7 +662,7 @@ export class AddEditComponent implements OnInit, OnDestroy {
|
||||
|
||||
// if a cipher is unassigned we want to check if they are an admin or have permission to edit any collection
|
||||
if (!cipher.collectionIds) {
|
||||
orgAdmin = this.organization?.canEditAnyCollection;
|
||||
orgAdmin = this.organization?.canEditAllCiphers(this.flexibleCollectionsV1Enabled);
|
||||
}
|
||||
|
||||
return this.cipher.id == null
|
||||
@ -671,14 +671,14 @@ export class AddEditComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
protected deleteCipher() {
|
||||
const asAdmin = this.organization?.canEditAnyCollection;
|
||||
const asAdmin = this.organization?.canEditAllCiphers(this.flexibleCollectionsV1Enabled);
|
||||
return this.cipher.isDeleted
|
||||
? this.cipherService.deleteWithServer(this.cipher.id, asAdmin)
|
||||
: this.cipherService.softDeleteWithServer(this.cipher.id, asAdmin);
|
||||
}
|
||||
|
||||
protected restoreCipher() {
|
||||
const asAdmin = this.organization?.canEditAnyCollection;
|
||||
const asAdmin = this.organization?.canEditAllCiphers(this.flexibleCollectionsV1Enabled);
|
||||
return this.cipherService.restoreWithServer(this.cipher.id, asAdmin);
|
||||
}
|
||||
|
||||
|
@ -188,18 +188,29 @@ export class Organization {
|
||||
return this.isManager || this.permissions.createNewCollections;
|
||||
}
|
||||
|
||||
get canEditAnyCollection() {
|
||||
return this.isAdmin || this.permissions.editAnyCollection;
|
||||
canEditAnyCollection(flexibleCollectionsV1Enabled: boolean) {
|
||||
if (!this.flexibleCollections || !flexibleCollectionsV1Enabled) {
|
||||
// Pre-Flexible Collections v1 logic
|
||||
return this.isAdmin || this.permissions.editAnyCollection;
|
||||
}
|
||||
|
||||
// Post Flexible Collections V1, the allowAdminAccessToAllCollectionItems flag can restrict admins
|
||||
// Providers and custom users with canEditAnyCollection are not affected by allowAdminAccessToAllCollectionItems flag
|
||||
return (
|
||||
this.isProviderUser ||
|
||||
(this.type === OrganizationUserType.Custom && this.permissions.editAnyCollection) ||
|
||||
(this.allowAdminAccessToAllCollectionItems && this.isAdmin)
|
||||
);
|
||||
}
|
||||
|
||||
get canUseAdminCollections() {
|
||||
return this.canEditAnyCollection;
|
||||
canUseAdminCollections(flexibleCollectionsV1Enabled: boolean) {
|
||||
return this.canEditAnyCollection(flexibleCollectionsV1Enabled);
|
||||
}
|
||||
|
||||
canEditAllCiphers(flexibleCollectionsV1Enabled: boolean) {
|
||||
// Before Flexible Collections, anyone with editAnyCollection permission could edit all ciphers
|
||||
if (!flexibleCollectionsV1Enabled) {
|
||||
return this.canEditAnyCollection;
|
||||
// Before Flexible Collections, any admin or anyone with editAnyCollection permission could edit all ciphers
|
||||
if (!this.flexibleCollections || !flexibleCollectionsV1Enabled) {
|
||||
return this.isAdmin || this.permissions.editAnyCollection;
|
||||
}
|
||||
// Post Flexible Collections V1, the allowAdminAccessToAllCollectionItems flag can restrict admins
|
||||
// Providers and custom users with canEditAnyCollection are not affected by allowAdminAccessToAllCollectionItems flag
|
||||
@ -214,8 +225,13 @@ export class Organization {
|
||||
return this.isAdmin || this.permissions.deleteAnyCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the user can view all collection information, such as collection name and access.
|
||||
* This does not indicate that the user can view items inside any collection - for that, see {@link canEditAllCiphers}
|
||||
*/
|
||||
get canViewAllCollections() {
|
||||
return this.canEditAnyCollection || this.canDeleteAnyCollection;
|
||||
// Admins can always see all collections even if collection management settings prevent them from editing them or seeing items
|
||||
return this.isAdmin || this.permissions.editAnyCollection || this.canDeleteAnyCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,11 +53,11 @@ export class CollectionView implements View, ITreeNodeObject {
|
||||
);
|
||||
}
|
||||
|
||||
return org?.canEditAnyCollection || (org?.canEditAssignedCollections && this.assigned);
|
||||
return org?.canEditAnyCollection(false) || (org?.canEditAssignedCollections && this.assigned);
|
||||
}
|
||||
|
||||
// For editing collection details, not the items within it.
|
||||
canEdit(org: Organization): boolean {
|
||||
canEdit(org: Organization, flexibleCollectionsV1Enabled: boolean): boolean {
|
||||
if (org != null && org.id !== this.organizationId) {
|
||||
throw new Error(
|
||||
"Id of the organization provided does not match the org id of the collection.",
|
||||
@ -65,8 +65,8 @@ export class CollectionView implements View, ITreeNodeObject {
|
||||
}
|
||||
|
||||
return org?.flexibleCollections
|
||||
? org?.canEditAnyCollection || this.manage
|
||||
: org?.canEditAnyCollection || org?.canEditAssignedCollections;
|
||||
? org?.canEditAnyCollection(flexibleCollectionsV1Enabled) || this.manage
|
||||
: org?.canEditAnyCollection(flexibleCollectionsV1Enabled) || org?.canEditAssignedCollections;
|
||||
}
|
||||
|
||||
// For deleting a collection, not the items within it.
|
||||
|
Loading…
Reference in New Issue
Block a user