1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-13 06:43:35 +00:00

[PM-10996] Remove restrict-provider-access feature flag (#10977)

This commit is contained in:
Shane Melton
2024-09-11 10:45:23 -07:00
committed by GitHub
parent db9003458b
commit 8e4dab5eba
23 changed files with 53 additions and 206 deletions

View File

@@ -6,7 +6,6 @@ import { first } from "rxjs/operators";
import { CollectionsComponent as BaseCollectionsComponent } from "@bitwarden/angular/admin-console/components/collections.component"; import { CollectionsComponent as BaseCollectionsComponent } from "@bitwarden/angular/admin-console/components/collections.component";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -29,7 +28,6 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
private route: ActivatedRoute, private route: ActivatedRoute,
private location: Location, private location: Location,
logService: LogService, logService: LogService,
configService: ConfigService,
accountService: AccountService, accountService: AccountService,
toastService: ToastService, toastService: ToastService,
) { ) {
@@ -40,7 +38,6 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
cipherService, cipherService,
organizationService, organizationService,
logService, logService,
configService,
accountService, accountService,
toastService, toastService,
); );

View File

@@ -3,7 +3,6 @@ import { Component } from "@angular/core";
import { CollectionsComponent as BaseCollectionsComponent } from "@bitwarden/angular/admin-console/components/collections.component"; import { CollectionsComponent as BaseCollectionsComponent } from "@bitwarden/angular/admin-console/components/collections.component";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -23,7 +22,6 @@ export class CollectionsComponent extends BaseCollectionsComponent {
platformUtilsService: PlatformUtilsService, platformUtilsService: PlatformUtilsService,
organizationService: OrganizationService, organizationService: OrganizationService,
logService: LogService, logService: LogService,
configService: ConfigService,
accountService: AccountService, accountService: AccountService,
toastService: ToastService, toastService: ToastService,
) { ) {
@@ -34,7 +32,6 @@ export class CollectionsComponent extends BaseCollectionsComponent {
cipherService, cipherService,
organizationService, organizationService,
logService, logService,
configService,
accountService, accountService,
toastService, toastService,
); );

View File

@@ -34,7 +34,6 @@ export class VaultCollectionRowComponent {
@Input() organizations: Organization[]; @Input() organizations: Organization[];
@Input() groups: GroupView[]; @Input() groups: GroupView[];
@Input() showPermissionsColumn: boolean; @Input() showPermissionsColumn: boolean;
@Input() restrictProviderAccess: boolean;
@Output() onEvent = new EventEmitter<VaultItemEvent>(); @Output() onEvent = new EventEmitter<VaultItemEvent>();
@@ -74,10 +73,7 @@ export class VaultCollectionRowComponent {
} }
get permissionText() { get permissionText() {
if ( if (this.collection.id == Unassigned && this.organization?.canEditUnassignedCiphers) {
this.collection.id == Unassigned &&
this.organization?.canEditUnassignedCiphers(this.restrictProviderAccess)
) {
return this.i18nService.t("canEdit"); return this.i18nService.t("canEdit");
} }
if ((this.collection as CollectionAdminView).assigned) { if ((this.collection as CollectionAdminView).assigned) {

View File

@@ -106,7 +106,6 @@
[canDeleteCollection]="canDeleteCollection(item.collection)" [canDeleteCollection]="canDeleteCollection(item.collection)"
[canEditCollection]="canEditCollection(item.collection)" [canEditCollection]="canEditCollection(item.collection)"
[canViewCollectionInfo]="canViewCollectionInfo(item.collection)" [canViewCollectionInfo]="canViewCollectionInfo(item.collection)"
[restrictProviderAccess]="restrictProviderAccess"
[checked]="selection.isSelected(item)" [checked]="selection.isSelected(item)"
(checkedToggled)="selection.toggle(item)" (checkedToggled)="selection.toggle(item)"
(onEvent)="event($event)" (onEvent)="event($event)"

View File

@@ -46,7 +46,6 @@ export class VaultItemsComponent {
@Input() viewingOrgVault: boolean; @Input() viewingOrgVault: boolean;
@Input() addAccessStatus: number; @Input() addAccessStatus: number;
@Input() addAccessToggle: boolean; @Input() addAccessToggle: boolean;
@Input() restrictProviderAccess: boolean;
@Input() vaultBulkManagementActionEnabled = false; @Input() vaultBulkManagementActionEnabled = false;
@Input() activeCollection: CollectionView | undefined; @Input() activeCollection: CollectionView | undefined;
@@ -213,10 +212,7 @@ export class VaultItemsComponent {
} }
const organization = this.allOrganizations.find((o) => o.id === cipher.organizationId); const organization = this.allOrganizations.find((o) => o.id === cipher.organizationId);
return ( return (organization.canEditAllCiphers && this.viewingOrgVault) || cipher.edit;
(organization.canEditAllCiphers(this.restrictProviderAccess) && this.viewingOrgVault) ||
cipher.edit
);
} }
protected canManageCollection(cipher: CipherView) { protected canManageCollection(cipher: CipherView) {
@@ -306,8 +302,7 @@ export class VaultItemsComponent {
const [orgId] = uniqueCipherOrgIds; const [orgId] = uniqueCipherOrgIds;
const organization = this.allOrganizations.find((o) => o.id === orgId); const organization = this.allOrganizations.find((o) => o.id === orgId);
const canEditOrManageAllCiphers = const canEditOrManageAllCiphers = organization?.canEditAllCiphers && this.viewingOrgVault;
organization?.canEditAllCiphers(this.restrictProviderAccess) && this.viewingOrgVault;
const collectionNotSelected = const collectionNotSelected =
this.selection.selected.filter((item) => item.collection).length === 0; this.selection.selected.filter((item) => item.collection).length === 0;

View File

@@ -1,11 +1,8 @@
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
import { Component, Inject } from "@angular/core"; import { Component, Inject } from "@angular/core";
import { firstValueFrom } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; 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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
@@ -54,10 +51,6 @@ export class BulkDeleteDialogComponent {
collections: CollectionView[]; collections: CollectionView[];
unassignedCiphers: string[]; unassignedCiphers: string[];
private restrictProviderAccess$ = this.configService.getFeatureFlag$(
FeatureFlag.RestrictProviderAccess,
);
constructor( constructor(
@Inject(DIALOG_DATA) params: BulkDeleteDialogParams, @Inject(DIALOG_DATA) params: BulkDeleteDialogParams,
private dialogRef: DialogRef<BulkDeleteDialogResult>, private dialogRef: DialogRef<BulkDeleteDialogResult>,
@@ -66,7 +59,6 @@ export class BulkDeleteDialogComponent {
private i18nService: I18nService, private i18nService: I18nService,
private apiService: ApiService, private apiService: ApiService,
private collectionService: CollectionService, private collectionService: CollectionService,
private configService: ConfigService,
) { ) {
this.cipherIds = params.cipherIds ?? []; this.cipherIds = params.cipherIds ?? [];
this.permanent = params.permanent; this.permanent = params.permanent;
@@ -82,19 +74,13 @@ export class BulkDeleteDialogComponent {
protected submit = async () => { protected submit = async () => {
const deletePromises: Promise<void>[] = []; const deletePromises: Promise<void>[] = [];
const restrictProviderAccess = await firstValueFrom(this.restrictProviderAccess$);
// Unassigned ciphers under an Owner/Admin OR Custom Users With Edit will call the deleteCiphersAdmin method // Unassigned ciphers under an Owner/Admin OR Custom Users With Edit will call the deleteCiphersAdmin method
if ( if (this.unassignedCiphers.length && this.organization.canEditUnassignedCiphers) {
this.unassignedCiphers.length &&
this.organization.canEditUnassignedCiphers(restrictProviderAccess)
) {
deletePromises.push(this.deleteCiphersAdmin(this.unassignedCiphers)); deletePromises.push(this.deleteCiphersAdmin(this.unassignedCiphers));
} }
if (this.cipherIds.length) { if (this.cipherIds.length) {
const restrictProviderAccess = await firstValueFrom(this.restrictProviderAccess$); if (!this.organization || !this.organization.canEditAllCiphers) {
if (!this.organization || !this.organization.canEditAllCiphers(restrictProviderAccess)) {
deletePromises.push(this.deleteCiphers()); deletePromises.push(this.deleteCiphers());
} else { } else {
deletePromises.push(this.deleteCiphersAdmin(this.cipherIds)); deletePromises.push(this.deleteCiphersAdmin(this.cipherIds));
@@ -126,8 +112,7 @@ export class BulkDeleteDialogComponent {
}; };
private async deleteCiphers(): Promise<any> { private async deleteCiphers(): Promise<any> {
const restrictProviderAccess = await firstValueFrom(this.restrictProviderAccess$); const asAdmin = this.organization?.canEditAllCiphers;
const asAdmin = this.organization?.canEditAllCiphers(restrictProviderAccess);
if (this.permanent) { if (this.permanent) {
await this.cipherService.deleteManyWithServer(this.cipherIds, asAdmin); await this.cipherService.deleteManyWithServer(this.cipherIds, asAdmin);
} else { } else {

View File

@@ -32,7 +32,7 @@
[(ngModel)]="$any(c).checked" [(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked" name="Collection[{{ i }}].Checked"
appStopProp appStopProp
[disabled]="!c.canEditItems(this.organization, this.restrictProviderAccess)" [disabled]="!c.canEditItems(this.organization)"
/> />
{{ c.name }} {{ c.name }}
</td> </td>

View File

@@ -4,7 +4,6 @@ import { Component, Inject, OnDestroy } from "@angular/core";
import { CollectionsComponent as BaseCollectionsComponent } from "@bitwarden/angular/admin-console/components/collections.component"; import { CollectionsComponent as BaseCollectionsComponent } from "@bitwarden/angular/admin-console/components/collections.component";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -25,7 +24,6 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
cipherService: CipherService, cipherService: CipherService,
organizationSerivce: OrganizationService, organizationSerivce: OrganizationService,
logService: LogService, logService: LogService,
configService: ConfigService,
accountService: AccountService, accountService: AccountService,
protected dialogRef: DialogRef, protected dialogRef: DialogRef,
@Inject(DIALOG_DATA) params: CollectionsDialogParams, @Inject(DIALOG_DATA) params: CollectionsDialogParams,
@@ -38,7 +36,6 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
cipherService, cipherService,
organizationSerivce, organizationSerivce,
logService, logService,
configService,
accountService, accountService,
toastService, toastService,
); );
@@ -55,7 +52,7 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
} }
check(c: CollectionView, select?: boolean) { check(c: CollectionView, select?: boolean) {
if (!c.canEditItems(this.organization, this.restrictProviderAccess)) { if (!c.canEditItems(this.organization)) {
return; return;
} }
(c as any).checked = select == null ? !(c as any).checked : select; (c as any).checked = select == null ? !(c as any).checked : select;

View File

@@ -1161,7 +1161,7 @@ export class VaultComponent implements OnInit, OnDestroy {
} }
const organization = this.allOrganizations.find((o) => o.id === cipher.organizationId); const organization = this.allOrganizations.find((o) => o.id === cipher.organizationId);
return organization.canEditAllCiphers(false); return organization.canEditAllCiphers;
} }
private go(queryParams: any = null) { private go(queryParams: any = null) {

View File

@@ -1,13 +1,11 @@
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
import { CommonModule } from "@angular/common"; import { CommonModule } from "@angular/common";
import { Component, Inject, OnInit, EventEmitter, OnDestroy } from "@angular/core"; import { Component, EventEmitter, Inject, OnDestroy, OnInit } from "@angular/core";
import { Router } from "@angular/router"; import { Router } from "@angular/router";
import { Subject } from "rxjs"; import { Subject } from "rxjs";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; 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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
@@ -50,9 +48,7 @@ export class ViewComponent implements OnInit, OnDestroy {
cipher: CipherView; cipher: CipherView;
onDeletedCipher = new EventEmitter<CipherView>(); onDeletedCipher = new EventEmitter<CipherView>();
cipherTypeString: string; cipherTypeString: string;
cipherEditUrl: string;
organization: Organization; organization: Organization;
restrictProviderAccess = false;
protected destroy$ = new Subject<void>(); protected destroy$ = new Subject<void>();
@@ -67,7 +63,6 @@ export class ViewComponent implements OnInit, OnDestroy {
private toastService: ToastService, private toastService: ToastService,
private organizationService: OrganizationService, private organizationService: OrganizationService,
private router: Router, private router: Router,
private configService: ConfigService,
) {} ) {}
/** /**
@@ -79,9 +74,6 @@ export class ViewComponent implements OnInit, OnDestroy {
if (this.cipher.organizationId) { if (this.cipher.organizationId) {
this.organization = await this.organizationService.get(this.cipher.organizationId); this.organization = await this.organizationService.get(this.cipher.organizationId);
} }
this.restrictProviderAccess = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
} }
/** /**
@@ -132,7 +124,7 @@ export class ViewComponent implements OnInit, OnDestroy {
* Helper method to delete cipher. * Helper method to delete cipher.
*/ */
protected async deleteCipher(): Promise<void> { protected async deleteCipher(): Promise<void> {
const asAdmin = this.organization?.canEditAllCiphers(this.restrictProviderAccess); const asAdmin = this.organization?.canEditAllCiphers;
if (this.cipher.isDeleted) { if (this.cipher.isDeleted) {
await this.cipherService.deleteWithServer(this.cipher.id, asAdmin); await this.cipherService.deleteWithServer(this.cipher.id, asAdmin);
} else { } else {

View File

@@ -83,7 +83,7 @@ export class AddEditComponent extends BaseAddEditComponent {
} }
protected loadCollections() { protected loadCollections() {
if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) { if (!this.organization.canEditAllCiphers) {
return super.loadCollections(); return super.loadCollections();
} }
return Promise.resolve(this.collections); return Promise.resolve(this.collections);
@@ -93,10 +93,7 @@ export class AddEditComponent extends BaseAddEditComponent {
// Calling loadCipher first to assess if the cipher is unassigned. If null use apiService getCipherAdmin // Calling loadCipher first to assess if the cipher is unassigned. If null use apiService getCipherAdmin
const firstCipherCheck = await super.loadCipher(); const firstCipherCheck = await super.loadCipher();
if ( if (!this.organization.canEditAllCiphers && firstCipherCheck != null) {
!this.organization.canEditAllCiphers(this.restrictProviderAccess) &&
firstCipherCheck != null
) {
return firstCipherCheck; return firstCipherCheck;
} }
const response = await this.apiService.getCipherAdmin(this.cipherId); const response = await this.apiService.getCipherAdmin(this.cipherId);
@@ -109,7 +106,7 @@ export class AddEditComponent extends BaseAddEditComponent {
} }
protected encryptCipher(userId: UserId) { protected encryptCipher(userId: UserId) {
if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) { if (!this.organization.canEditAllCiphers) {
return super.encryptCipher(userId); return super.encryptCipher(userId);
} }
@@ -117,7 +114,7 @@ export class AddEditComponent extends BaseAddEditComponent {
} }
protected async deleteCipher() { protected async deleteCipher() {
if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) { if (!this.organization.canEditAllCiphers) {
return super.deleteCipher(); return super.deleteCipher();
} }
return this.cipher.isDeleted return this.cipher.isDeleted

View File

@@ -1,12 +1,9 @@
import { Component, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { firstValueFrom } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; 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 { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -30,8 +27,6 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
viewOnly = false; viewOnly = false;
organization: Organization; organization: Organization;
private restrictProviderAccess = false;
constructor( constructor(
cipherService: CipherService, cipherService: CipherService,
i18nService: I18nService, i18nService: I18nService,
@@ -44,7 +39,6 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
dialogService: DialogService, dialogService: DialogService,
billingAccountProfileStateService: BillingAccountProfileStateService, billingAccountProfileStateService: BillingAccountProfileStateService,
accountService: AccountService, accountService: AccountService,
private configService: ConfigService,
) { ) {
super( super(
cipherService, cipherService,
@@ -63,22 +57,16 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
async ngOnInit() { async ngOnInit() {
await super.ngOnInit(); await super.ngOnInit();
this.restrictProviderAccess = await firstValueFrom(
this.configService.getFeatureFlag$(FeatureFlag.RestrictProviderAccess),
);
} }
protected async reupload(attachment: AttachmentView) { protected async reupload(attachment: AttachmentView) {
if ( if (this.organization.canEditAllCiphers && this.showFixOldAttachments(attachment)) {
this.organization.canEditAllCiphers(this.restrictProviderAccess) &&
this.showFixOldAttachments(attachment)
) {
await super.reuploadCipherAttachment(attachment, true); await super.reuploadCipherAttachment(attachment, true);
} }
} }
protected async loadCipher() { protected async loadCipher() {
if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) { if (!this.organization.canEditAllCiphers) {
return await super.loadCipher(); return await super.loadCipher();
} }
const response = await this.apiService.getCipherAdmin(this.cipherId); const response = await this.apiService.getCipherAdmin(this.cipherId);
@@ -90,20 +78,18 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
this.cipherDomain, this.cipherDomain,
file, file,
userId, userId,
this.organization.canEditAllCiphers(this.restrictProviderAccess), this.organization.canEditAllCiphers,
); );
} }
protected deleteCipherAttachment(attachmentId: string) { protected deleteCipherAttachment(attachmentId: string) {
if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) { if (!this.organization.canEditAllCiphers) {
return super.deleteCipherAttachment(attachmentId); return super.deleteCipherAttachment(attachmentId);
} }
return this.apiService.deleteCipherAttachmentAdmin(this.cipherId, attachmentId); return this.apiService.deleteCipherAttachmentAdmin(this.cipherId, attachmentId);
} }
protected showFixOldAttachments(attachment: AttachmentView) { protected showFixOldAttachments(attachment: AttachmentView) {
return ( return attachment.key == null && this.organization.canEditAllCiphers;
attachment.key == null && this.organization.canEditAllCiphers(this.restrictProviderAccess)
);
} }
} }

View File

@@ -5,7 +5,6 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -37,7 +36,6 @@ export class CollectionsComponent extends BaseCollectionsComponent {
organizationService: OrganizationService, organizationService: OrganizationService,
private apiService: ApiService, private apiService: ApiService,
logService: LogService, logService: LogService,
configService: ConfigService,
accountService: AccountService, accountService: AccountService,
protected dialogRef: DialogRef, protected dialogRef: DialogRef,
@Inject(DIALOG_DATA) params: OrgVaultCollectionsDialogParams, @Inject(DIALOG_DATA) params: OrgVaultCollectionsDialogParams,
@@ -50,7 +48,6 @@ export class CollectionsComponent extends BaseCollectionsComponent {
cipherService, cipherService,
organizationService, organizationService,
logService, logService,
configService,
accountService, accountService,
dialogRef, dialogRef,
params, params,
@@ -65,10 +62,7 @@ export class CollectionsComponent extends BaseCollectionsComponent {
protected async loadCipher() { protected async loadCipher() {
// if cipher is unassigned use apiService. We can see this by looking at this.collectionIds // if cipher is unassigned use apiService. We can see this by looking at this.collectionIds
if ( if (!this.organization.canEditAllCiphers && this.collectionIds.length !== 0) {
!this.organization.canEditAllCiphers(this.restrictProviderAccess) &&
this.collectionIds.length !== 0
) {
return await super.loadCipher(); return await super.loadCipher();
} }
const response = await this.apiService.getCipherAdmin(this.cipherId); const response = await this.apiService.getCipherAdmin(this.cipherId);
@@ -90,10 +84,7 @@ export class CollectionsComponent extends BaseCollectionsComponent {
} }
protected saveCollections() { protected saveCollections() {
if ( if (this.organization.canEditAllCiphers || this.collectionIds.length === 0) {
this.organization.canEditAllCiphers(this.restrictProviderAccess) ||
this.collectionIds.length === 0
) {
const request = new CipherCollectionsRequest(this.cipherDomain.collectionIds); const request = new CipherCollectionsRequest(this.cipherDomain.collectionIds);
return this.apiService.putCipherCollectionsAdmin(this.cipherId, request); return this.apiService.putCipherCollectionsAdmin(this.cipherId, request);
} else { } else {

View File

@@ -93,7 +93,7 @@
</ng-container> </ng-container>
<bit-search <bit-search
*ngIf="restrictProviderAccessFlag && organization?.isProviderUser && !organization?.isMember" *ngIf="organization?.isProviderUser && !organization?.isMember"
class="tw-grow" class="tw-grow"
[ngModel]="searchText" [ngModel]="searchText"
(ngModelChange)="onSearchTextChanged($event)" (ngModelChange)="onSearchTextChanged($event)"

View File

@@ -13,11 +13,11 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherType } from "@bitwarden/common/vault/enums";
import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node"; import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
import { import {
DialogService,
SimpleDialogOptions,
BreadcrumbsModule, BreadcrumbsModule,
DialogService,
MenuModule, MenuModule,
SearchModule, SearchModule,
SimpleDialogOptions,
} from "@bitwarden/components"; } from "@bitwarden/components";
import { HeaderModule } from "../../../layouts/header/header.module"; import { HeaderModule } from "../../../layouts/header/header.module";
@@ -88,8 +88,6 @@ export class VaultHeaderComponent implements OnInit {
protected CollectionDialogTabType = CollectionDialogTabType; protected CollectionDialogTabType = CollectionDialogTabType;
protected organizations$ = this.organizationService.organizations$; protected organizations$ = this.organizationService.organizations$;
protected restrictProviderAccessFlag = false;
/** /**
* Whether the extension refresh feature flag is enabled. * Whether the extension refresh feature flag is enabled.
*/ */
@@ -108,9 +106,6 @@ export class VaultHeaderComponent implements OnInit {
) {} ) {}
async ngOnInit() { async ngOnInit() {
this.restrictProviderAccessFlag = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
this.extensionRefreshEnabled = await this.configService.getFeatureFlag( this.extensionRefreshEnabled = await this.configService.getFeatureFlag(
FeatureFlag.ExtensionRefresh, FeatureFlag.ExtensionRefresh,
); );
@@ -245,11 +240,7 @@ export class VaultHeaderComponent implements OnInit {
} }
get canCreateCipher(): boolean { get canCreateCipher(): boolean {
if ( if (this.organization?.isProviderUser && !this.organization?.isMember) {
this.organization?.isProviderUser &&
this.restrictProviderAccessFlag &&
!this.organization?.isMember
) {
return false; return false;
} }
return true; return true;

View File

@@ -70,7 +70,6 @@
[viewingOrgVault]="true" [viewingOrgVault]="true"
[addAccessStatus]="addAccessStatus$ | async" [addAccessStatus]="addAccessStatus$ | async"
[addAccessToggle]="showAddAccessToggle" [addAccessToggle]="showAddAccessToggle"
[restrictProviderAccess]="restrictProviderAccessEnabled"
> >
</app-vault-items> </app-vault-items>
<ng-container *ngIf="!performingInitialLoad && isEmpty"> <ng-container *ngIf="!performingInitialLoad && isEmpty">

View File

@@ -43,9 +43,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { EventType } from "@bitwarden/common/enums"; 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 { 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"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
@@ -172,17 +170,8 @@ export class VaultComponent implements OnInit, OnDestroy {
protected orgRevokedUsers: OrganizationUserUserDetailsResponse[]; protected orgRevokedUsers: OrganizationUserUserDetailsResponse[];
private _restrictProviderAccessFlagEnabled: boolean;
protected get restrictProviderAccessEnabled(): boolean {
return this._restrictProviderAccessFlagEnabled;
}
protected get hideVaultFilters(): boolean { protected get hideVaultFilters(): boolean {
return ( return this.organization?.isProviderUser && !this.organization?.isMember;
this.restrictProviderAccessEnabled &&
this.organization?.isProviderUser &&
!this.organization?.isMember
);
} }
private searchText$ = new Subject<string>(); private searchText$ = new Subject<string>();
@@ -218,7 +207,6 @@ export class VaultComponent implements OnInit, OnDestroy {
private apiService: ApiService, private apiService: ApiService,
private collectionService: CollectionService, private collectionService: CollectionService,
private organizationUserApiService: OrganizationUserApiService, private organizationUserApiService: OrganizationUserApiService,
protected configService: ConfigService,
private toastService: ToastService, private toastService: ToastService,
private accountService: AccountService, private accountService: AccountService,
) {} ) {}
@@ -230,10 +218,6 @@ export class VaultComponent implements OnInit, OnDestroy {
: "trashCleanupWarning", : "trashCleanupWarning",
); );
this._restrictProviderAccessFlagEnabled = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
const filter$ = this.routedVaultFilterService.filter$; const filter$ = this.routedVaultFilterService.filter$;
const organizationId$ = filter$.pipe( const organizationId$ = filter$.pipe(
map((filter) => filter.organizationId), map((filter) => filter.organizationId),
@@ -325,7 +309,7 @@ export class VaultComponent implements OnInit, OnDestroy {
this.editableCollections$ = this.allCollectionsWithoutUnassigned$.pipe( this.editableCollections$ = this.allCollectionsWithoutUnassigned$.pipe(
map((collections) => { map((collections) => {
// Users that can edit all ciphers can implicitly add to / edit within any collection // Users that can edit all ciphers can implicitly add to / edit within any collection
if (this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled)) { if (this.organization.canEditAllCiphers) {
return collections; return collections;
} }
// The user is only allowed to add/edit items to assigned collections that are not readonly // The user is only allowed to add/edit items to assigned collections that are not readonly
@@ -362,16 +346,12 @@ export class VaultComponent implements OnInit, OnDestroy {
// Restricted providers (who are not members) do not have access org cipher endpoint below // Restricted providers (who are not members) do not have access org cipher endpoint below
// Return early to avoid 404 response // Return early to avoid 404 response
if ( if (!organization.isMember && organization.isProviderUser) {
this.restrictProviderAccessEnabled &&
!organization.isMember &&
organization.isProviderUser
) {
return []; return [];
} }
// If the user can edit all ciphers for the organization then fetch them ALL. // If the user can edit all ciphers for the organization then fetch them ALL.
if (organization.canEditAllCiphers(this.restrictProviderAccessEnabled)) { if (organization.canEditAllCiphers) {
ciphers = await this.cipherService.getAllFromApiForOrganization(organization.id); ciphers = await this.cipherService.getAllFromApiForOrganization(organization.id);
} else { } else {
// Otherwise, only fetch ciphers they have access to (includes unassigned for admins). // Otherwise, only fetch ciphers they have access to (includes unassigned for admins).
@@ -476,11 +456,8 @@ export class VaultComponent implements OnInit, OnDestroy {
]).pipe( ]).pipe(
map(([filter, collection, organization]) => { map(([filter, collection, organization]) => {
return ( return (
(filter.collectionId === Unassigned && (filter.collectionId === Unassigned && !organization.canEditUnassignedCiphers) ||
!organization.canEditUnassignedCiphers(this.restrictProviderAccessEnabled)) || (!organization.canEditAllCiphers && collection != undefined && !collection.node.assigned)
(!organization.canEditAllCiphers(this.restrictProviderAccessEnabled) &&
collection != undefined &&
!collection.node.assigned)
); );
}), }),
shareReplay({ refCount: true, bufferSize: 1 }), shareReplay({ refCount: true, bufferSize: 1 }),
@@ -525,7 +502,7 @@ export class VaultComponent implements OnInit, OnDestroy {
} }
const canEditCipher = const canEditCipher =
organization.canEditAllCiphers(this.restrictProviderAccessEnabled) || organization.canEditAllCiphers ||
(await firstValueFrom(allCipherMap$))[cipherId] != undefined; (await firstValueFrom(allCipherMap$))[cipherId] != undefined;
if (canEditCipher) { if (canEditCipher) {
@@ -758,15 +735,9 @@ export class VaultComponent implements OnInit, OnDestroy {
this.allCollectionsWithoutUnassigned$.pipe( this.allCollectionsWithoutUnassigned$.pipe(
map((c) => { map((c) => {
return c.sort((a, b) => { return c.sort((a, b) => {
if ( if (a.canEditItems(this.organization) && !b.canEditItems(this.organization)) {
a.canEditItems(this.organization, this.restrictProviderAccessEnabled) &&
!b.canEditItems(this.organization, this.restrictProviderAccessEnabled)
) {
return -1; return -1;
} else if ( } else if (!a.canEditItems(this.organization) && b.canEditItems(this.organization)) {
!a.canEditItems(this.organization, this.restrictProviderAccessEnabled) &&
b.canEditItems(this.organization, this.restrictProviderAccessEnabled)
) {
return 1; return 1;
} else { } else {
return a.name.localeCompare(b.name); return a.name.localeCompare(b.name);
@@ -1001,9 +972,7 @@ export class VaultComponent implements OnInit, OnDestroy {
const unassignedCiphers: string[] = []; const unassignedCiphers: string[] = [];
// If user has edit all Access no need to check for unassigned ciphers // If user has edit all Access no need to check for unassigned ciphers
const canEditAll = this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled); if (this.organization.canEditAllCiphers) {
if (canEditAll) {
ciphers.map((cipher) => { ciphers.map((cipher) => {
editAccessCiphers.push(cipher.id); editAccessCiphers.push(cipher.id);
}); });
@@ -1042,7 +1011,7 @@ export class VaultComponent implements OnInit, OnDestroy {
} }
async deleteCipher(c: CipherView): Promise<boolean> { async deleteCipher(c: CipherView): Promise<boolean> {
if (!c.edit && !this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled)) { if (!c.edit && !this.organization.canEditAllCiphers) {
this.showMissingPermissionsError(); this.showMissingPermissionsError();
return; return;
} }
@@ -1146,9 +1115,7 @@ export class VaultComponent implements OnInit, OnDestroy {
const canDeleteCollections = const canDeleteCollections =
collections == null || collections.every((c) => c.canDelete(organization)); collections == null || collections.every((c) => c.canDelete(organization));
const canDeleteCiphers = const canDeleteCiphers =
ciphers == null || ciphers == null || ciphers.every((c) => c.edit) || this.organization.canEditAllCiphers;
ciphers.every((c) => c.edit) ||
this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled);
if (!canDeleteCiphers || !canDeleteCollections) { if (!canDeleteCiphers || !canDeleteCollections) {
this.showMissingPermissionsError(); this.showMissingPermissionsError();
@@ -1351,8 +1318,7 @@ export class VaultComponent implements OnInit, OnDestroy {
} }
protected deleteCipherWithServer(id: string, permanent: boolean, isUnassigned: boolean) { protected deleteCipherWithServer(id: string, permanent: boolean, isUnassigned: boolean) {
const asAdmin = const asAdmin = this.organization?.canEditAllCiphers || isUnassigned;
this.organization?.canEditAllCiphers(this.restrictProviderAccessEnabled) || isUnassigned;
return permanent return permanent
? this.cipherService.deleteWithServer(id, asAdmin) ? this.cipherService.deleteWithServer(id, asAdmin)
: this.cipherService.softDeleteWithServer(id, asAdmin); : this.cipherService.softDeleteWithServer(id, asAdmin);

View File

@@ -4,8 +4,6 @@ import { firstValueFrom, map } from "rxjs";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -27,7 +25,6 @@ export class CollectionsComponent implements OnInit {
collectionIds: string[]; collectionIds: string[];
collections: CollectionView[] = []; collections: CollectionView[] = [];
organization: Organization; organization: Organization;
restrictProviderAccess: boolean;
protected cipherDomain: Cipher; protected cipherDomain: Cipher;
@@ -38,15 +35,11 @@ export class CollectionsComponent implements OnInit {
protected cipherService: CipherService, protected cipherService: CipherService,
protected organizationService: OrganizationService, protected organizationService: OrganizationService,
private logService: LogService, private logService: LogService,
private configService: ConfigService,
private accountService: AccountService, private accountService: AccountService,
private toastService: ToastService, private toastService: ToastService,
) {} ) {}
async ngOnInit() { async ngOnInit() {
this.restrictProviderAccess = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
await this.load(); await this.load();
} }
@@ -76,7 +69,7 @@ export class CollectionsComponent implements OnInit {
async submit(): Promise<boolean> { async submit(): Promise<boolean> {
const selectedCollectionIds = this.collections const selectedCollectionIds = this.collections
.filter((c) => { .filter((c) => {
if (this.organization.canEditAllCiphers(this.restrictProviderAccess)) { if (this.organization.canEditAllCiphers) {
return !!(c as any).checked; return !!(c as any).checked;
} else { } else {
return !!(c as any).checked && c.readOnly == null; return !!(c as any).checked && c.readOnly == null;

View File

@@ -13,7 +13,6 @@ import { OrganizationUserStatusType, PolicyType } from "@bitwarden/common/admin-
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { EventType } from "@bitwarden/common/enums"; import { EventType } from "@bitwarden/common/enums";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { UriMatchStrategy } from "@bitwarden/common/models/domain/domain-service"; import { UriMatchStrategy } from "@bitwarden/common/models/domain/domain-service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -92,8 +91,6 @@ export class AddEditComponent implements OnInit, OnDestroy {
private personalOwnershipPolicyAppliesToActiveUser: boolean; private personalOwnershipPolicyAppliesToActiveUser: boolean;
private previousCipherId: string; private previousCipherId: string;
protected restrictProviderAccess = false;
get fido2CredentialCreationDateValue(): string { get fido2CredentialCreationDateValue(): string {
const dateCreated = this.i18nService.t("dateCreated"); const dateCreated = this.i18nService.t("dateCreated");
const creationDate = this.datePipe.transform( const creationDate = this.datePipe.transform(
@@ -182,10 +179,6 @@ export class AddEditComponent implements OnInit, OnDestroy {
} }
async ngOnInit() { async ngOnInit() {
this.restrictProviderAccess = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
this.policyService this.policyService
.policyAppliesToActiveUser$(PolicyType.PersonalOwnership) .policyAppliesToActiveUser$(PolicyType.PersonalOwnership)
.pipe( .pipe(
@@ -683,11 +676,11 @@ export class AddEditComponent implements OnInit, OnDestroy {
protected saveCipher(cipher: Cipher) { protected saveCipher(cipher: Cipher) {
const isNotClone = this.editMode && !this.cloneMode; const isNotClone = this.editMode && !this.cloneMode;
let orgAdmin = this.organization?.canEditAllCiphers(this.restrictProviderAccess); let orgAdmin = this.organization?.canEditAllCiphers;
// if a cipher is unassigned we want to check if they are an admin or have permission to edit any collection // if a cipher is unassigned we want to check if they are an admin or have permission to edit any collection
if (!cipher.collectionIds) { if (!cipher.collectionIds) {
orgAdmin = this.organization?.canEditUnassignedCiphers(this.restrictProviderAccess); orgAdmin = this.organization?.canEditUnassignedCiphers;
} }
return this.cipher.id == null return this.cipher.id == null
@@ -696,14 +689,14 @@ export class AddEditComponent implements OnInit, OnDestroy {
} }
protected deleteCipher() { protected deleteCipher() {
const asAdmin = this.organization?.canEditAllCiphers(this.restrictProviderAccess); const asAdmin = this.organization?.canEditAllCiphers;
return this.cipher.isDeleted return this.cipher.isDeleted
? this.cipherService.deleteWithServer(this.cipher.id, asAdmin) ? this.cipherService.deleteWithServer(this.cipher.id, asAdmin)
: this.cipherService.softDeleteWithServer(this.cipher.id, asAdmin); : this.cipherService.softDeleteWithServer(this.cipher.id, asAdmin);
} }
protected restoreCipher() { protected restoreCipher() {
const asAdmin = this.organization?.canEditAllCiphers(this.restrictProviderAccess); const asAdmin = this.organization?.canEditAllCiphers;
return this.cipherService.restoreWithServer(this.cipher.id, asAdmin); return this.cipherService.restoreWithServer(this.cipher.id, asAdmin);
} }

View File

@@ -183,14 +183,7 @@ export class Organization {
return this.isAdmin || this.permissions.editAnyCollection; return this.isAdmin || this.permissions.editAnyCollection;
} }
canEditUnassignedCiphers(restrictProviderAccessFlagEnabled: boolean) { get canEditUnassignedCiphers() {
// Providers can access items until the restrictProviderAccess flag is enabled
// After the flag is enabled and removed, this block will be deleted
// so that they permanently lose access to items
if (this.isProviderUser && !restrictProviderAccessFlagEnabled) {
return true;
}
return ( return (
this.type === OrganizationUserType.Admin || this.type === OrganizationUserType.Admin ||
this.type === OrganizationUserType.Owner || this.type === OrganizationUserType.Owner ||
@@ -198,14 +191,7 @@ export class Organization {
); );
} }
canEditAllCiphers(restrictProviderAccessFlagEnabled: boolean) { get canEditAllCiphers() {
// Providers can access items until the restrictProviderAccess flag is enabled
// After the flag is enabled and removed, this block will be deleted
// so that they permanently lose access to items
if (this.isProviderUser && !restrictProviderAccessFlagEnabled) {
return true;
}
// The allowAdminAccessToAllCollectionItems flag can restrict admins // The allowAdminAccessToAllCollectionItems flag can restrict admins
// Custom users with canEditAnyCollection are not affected by allowAdminAccessToAllCollectionItems flag // Custom users with canEditAnyCollection are not affected by allowAdminAccessToAllCollectionItems flag
return ( return (

View File

@@ -12,7 +12,6 @@ export enum FeatureFlag {
EnableDeleteProvider = "AC-1218-delete-provider", EnableDeleteProvider = "AC-1218-delete-provider",
ExtensionRefresh = "extension-refresh", ExtensionRefresh = "extension-refresh",
PersistPopupView = "persist-popup-view", PersistPopupView = "persist-popup-view",
RestrictProviderAccess = "restrict-provider-access",
PM4154_BulkEncryptionService = "PM-4154-bulk-encryption-service", PM4154_BulkEncryptionService = "PM-4154-bulk-encryption-service",
UseTreeWalkerApiForPageDetailsCollection = "use-tree-walker-api-for-page-details-collection", UseTreeWalkerApiForPageDetailsCollection = "use-tree-walker-api-for-page-details-collection",
EmailVerification = "email-verification", EmailVerification = "email-verification",
@@ -59,7 +58,6 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.EnableDeleteProvider]: FALSE, [FeatureFlag.EnableDeleteProvider]: FALSE,
[FeatureFlag.ExtensionRefresh]: FALSE, [FeatureFlag.ExtensionRefresh]: FALSE,
[FeatureFlag.PersistPopupView]: FALSE, [FeatureFlag.PersistPopupView]: FALSE,
[FeatureFlag.RestrictProviderAccess]: FALSE,
[FeatureFlag.PM4154_BulkEncryptionService]: FALSE, [FeatureFlag.PM4154_BulkEncryptionService]: FALSE,
[FeatureFlag.UseTreeWalkerApiForPageDetailsCollection]: FALSE, [FeatureFlag.UseTreeWalkerApiForPageDetailsCollection]: FALSE,
[FeatureFlag.EmailVerification]: FALSE, [FeatureFlag.EmailVerification]: FALSE,

View File

@@ -38,18 +38,14 @@ export class CollectionView implements View, ITreeNodeObject {
} }
} }
canEditItems(org: Organization, restrictProviderAccess: boolean): boolean { canEditItems(org: Organization): boolean {
if (org != null && org.id !== this.organizationId) { if (org != null && org.id !== this.organizationId) {
throw new Error( throw new Error(
"Id of the organization provided does not match the org id of the collection.", "Id of the organization provided does not match the org id of the collection.",
); );
} }
return ( return org?.canEditAllCiphers || this.manage || (this.assigned && !this.readOnly);
org?.canEditAllCiphers(restrictProviderAccess) ||
this.manage ||
(this.assigned && !this.readOnly)
);
} }
/** /**

View File

@@ -11,12 +11,12 @@ import {
} from "@angular/core"; } from "@angular/core";
import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"; import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms";
import { import {
Observable,
Subject,
combineLatest, combineLatest,
firstValueFrom, firstValueFrom,
map, map,
Observable,
shareReplay, shareReplay,
Subject,
switchMap, switchMap,
takeUntil, takeUntil,
tap, tap,
@@ -27,8 +27,6 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums"; import { OrganizationUserStatusType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid"; import { CipherId, CollectionId, OrganizationId, UserId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
@@ -170,7 +168,6 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
constructor( constructor(
private cipherService: CipherService, private cipherService: CipherService,
private i18nService: I18nService, private i18nService: I18nService,
private configService: ConfigService,
private organizationService: OrganizationService, private organizationService: OrganizationService,
private collectionService: CollectionService, private collectionService: CollectionService,
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
@@ -179,10 +176,6 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
) {} ) {}
async ngOnInit() { async ngOnInit() {
const restrictProviderAccess = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
this.activeUserId = await firstValueFrom( this.activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(map((a) => a?.id)), this.accountService.activeAccount$.pipe(map((a) => a?.id)),
); );
@@ -193,7 +186,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
this.showOrgSelector = true; this.showOrgSelector = true;
} }
await this.initializeItems(this.selectedOrgId, restrictProviderAccess); await this.initializeItems(this.selectedOrgId);
if (this.selectedOrgId && this.selectedOrgId !== MY_VAULT_ID) { if (this.selectedOrgId && this.selectedOrgId !== MY_VAULT_ID) {
await this.handleOrganizationCiphers(); await this.handleOrganizationCiphers();
@@ -339,7 +332,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
} }
} }
private async initializeItems(organizationId: OrganizationId, restrictProviderAccess: boolean) { private async initializeItems(organizationId: OrganizationId) {
this.totalItemCount = this.params.ciphers.length; this.totalItemCount = this.params.ciphers.length;
// If organizationId is not present or organizationId is MyVault, then all ciphers are considered personal items // If organizationId is not present or organizationId is MyVault, then all ciphers are considered personal items
@@ -354,7 +347,7 @@ export class AssignCollectionsComponent implements OnInit, OnDestroy, AfterViewI
const org = await this.organizationService.get(organizationId); const org = await this.organizationService.get(organizationId);
this.orgName = org.name; this.orgName = org.name;
this.editableItems = org.canEditAllCiphers(restrictProviderAccess) this.editableItems = org.canEditAllCiphers
? this.params.ciphers ? this.params.ciphers
: this.params.ciphers.filter((c) => c.edit); : this.params.ciphers.filter((c) => c.edit);