1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-22 11:45:59 +01: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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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 { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
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 { LogService } from "@bitwarden/common/platform/abstractions/log.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 location: Location,
logService: LogService,
configService: ConfigService,
accountService: AccountService,
toastService: ToastService,
) {
@ -40,7 +38,6 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
cipherService,
organizationService,
logService,
configService,
accountService,
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 { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
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 { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@ -23,7 +22,6 @@ export class CollectionsComponent extends BaseCollectionsComponent {
platformUtilsService: PlatformUtilsService,
organizationService: OrganizationService,
logService: LogService,
configService: ConfigService,
accountService: AccountService,
toastService: ToastService,
) {
@ -34,7 +32,6 @@ export class CollectionsComponent extends BaseCollectionsComponent {
cipherService,
organizationService,
logService,
configService,
accountService,
toastService,
);

View File

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

View File

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

View File

@ -46,7 +46,6 @@ export class VaultItemsComponent {
@Input() viewingOrgVault: boolean;
@Input() addAccessStatus: number;
@Input() addAccessToggle: boolean;
@Input() restrictProviderAccess: boolean;
@Input() vaultBulkManagementActionEnabled = false;
@Input() activeCollection: CollectionView | undefined;
@ -213,10 +212,7 @@ export class VaultItemsComponent {
}
const organization = this.allOrganizations.find((o) => o.id === cipher.organizationId);
return (
(organization.canEditAllCiphers(this.restrictProviderAccess) && this.viewingOrgVault) ||
cipher.edit
);
return (organization.canEditAllCiphers && this.viewingOrgVault) || cipher.edit;
}
protected canManageCollection(cipher: CipherView) {
@ -306,8 +302,7 @@ export class VaultItemsComponent {
const [orgId] = uniqueCipherOrgIds;
const organization = this.allOrganizations.find((o) => o.id === orgId);
const canEditOrManageAllCiphers =
organization?.canEditAllCiphers(this.restrictProviderAccess) && this.viewingOrgVault;
const canEditOrManageAllCiphers = organization?.canEditAllCiphers && this.viewingOrgVault;
const collectionNotSelected =
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 { 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";
@ -54,10 +51,6 @@ export class BulkDeleteDialogComponent {
collections: CollectionView[];
unassignedCiphers: string[];
private restrictProviderAccess$ = this.configService.getFeatureFlag$(
FeatureFlag.RestrictProviderAccess,
);
constructor(
@Inject(DIALOG_DATA) params: BulkDeleteDialogParams,
private dialogRef: DialogRef<BulkDeleteDialogResult>,
@ -66,7 +59,6 @@ export class BulkDeleteDialogComponent {
private i18nService: I18nService,
private apiService: ApiService,
private collectionService: CollectionService,
private configService: ConfigService,
) {
this.cipherIds = params.cipherIds ?? [];
this.permanent = params.permanent;
@ -82,19 +74,13 @@ export class BulkDeleteDialogComponent {
protected submit = async () => {
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
if (
this.unassignedCiphers.length &&
this.organization.canEditUnassignedCiphers(restrictProviderAccess)
) {
if (this.unassignedCiphers.length && this.organization.canEditUnassignedCiphers) {
deletePromises.push(this.deleteCiphersAdmin(this.unassignedCiphers));
}
if (this.cipherIds.length) {
const restrictProviderAccess = await firstValueFrom(this.restrictProviderAccess$);
if (!this.organization || !this.organization.canEditAllCiphers(restrictProviderAccess)) {
if (!this.organization || !this.organization.canEditAllCiphers) {
deletePromises.push(this.deleteCiphers());
} else {
deletePromises.push(this.deleteCiphersAdmin(this.cipherIds));
@ -126,8 +112,7 @@ export class BulkDeleteDialogComponent {
};
private async deleteCiphers(): Promise<any> {
const restrictProviderAccess = await firstValueFrom(this.restrictProviderAccess$);
const asAdmin = this.organization?.canEditAllCiphers(restrictProviderAccess);
const asAdmin = this.organization?.canEditAllCiphers;
if (this.permanent) {
await this.cipherService.deleteManyWithServer(this.cipherIds, asAdmin);
} else {

View File

@ -32,7 +32,7 @@
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
appStopProp
[disabled]="!c.canEditItems(this.organization, this.restrictProviderAccess)"
[disabled]="!c.canEditItems(this.organization)"
/>
{{ c.name }}
</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 { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
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 { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@ -25,7 +24,6 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
cipherService: CipherService,
organizationSerivce: OrganizationService,
logService: LogService,
configService: ConfigService,
accountService: AccountService,
protected dialogRef: DialogRef,
@Inject(DIALOG_DATA) params: CollectionsDialogParams,
@ -38,7 +36,6 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
cipherService,
organizationSerivce,
logService,
configService,
accountService,
toastService,
);
@ -55,7 +52,7 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
}
check(c: CollectionView, select?: boolean) {
if (!c.canEditItems(this.organization, this.restrictProviderAccess)) {
if (!c.canEditItems(this.organization)) {
return;
}
(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);
return organization.canEditAllCiphers(false);
return organization.canEditAllCiphers;
}
private go(queryParams: any = null) {

View File

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

View File

@ -83,7 +83,7 @@ export class AddEditComponent extends BaseAddEditComponent {
}
protected loadCollections() {
if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) {
if (!this.organization.canEditAllCiphers) {
return super.loadCollections();
}
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
const firstCipherCheck = await super.loadCipher();
if (
!this.organization.canEditAllCiphers(this.restrictProviderAccess) &&
firstCipherCheck != null
) {
if (!this.organization.canEditAllCiphers && firstCipherCheck != null) {
return firstCipherCheck;
}
const response = await this.apiService.getCipherAdmin(this.cipherId);
@ -109,7 +106,7 @@ export class AddEditComponent extends BaseAddEditComponent {
}
protected encryptCipher(userId: UserId) {
if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) {
if (!this.organization.canEditAllCiphers) {
return super.encryptCipher(userId);
}
@ -117,7 +114,7 @@ export class AddEditComponent extends BaseAddEditComponent {
}
protected async deleteCipher() {
if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) {
if (!this.organization.canEditAllCiphers) {
return super.deleteCipher();
}
return this.cipher.isDeleted

View File

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

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

View File

@ -93,7 +93,7 @@
</ng-container>
<bit-search
*ngIf="restrictProviderAccessFlag && organization?.isProviderUser && !organization?.isMember"
*ngIf="organization?.isProviderUser && !organization?.isMember"
class="tw-grow"
[ngModel]="searchText"
(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 { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
import {
DialogService,
SimpleDialogOptions,
BreadcrumbsModule,
DialogService,
MenuModule,
SearchModule,
SimpleDialogOptions,
} from "@bitwarden/components";
import { HeaderModule } from "../../../layouts/header/header.module";
@ -88,8 +88,6 @@ export class VaultHeaderComponent implements OnInit {
protected CollectionDialogTabType = CollectionDialogTabType;
protected organizations$ = this.organizationService.organizations$;
protected restrictProviderAccessFlag = false;
/**
* Whether the extension refresh feature flag is enabled.
*/
@ -108,9 +106,6 @@ export class VaultHeaderComponent implements OnInit {
) {}
async ngOnInit() {
this.restrictProviderAccessFlag = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
this.extensionRefreshEnabled = await this.configService.getFeatureFlag(
FeatureFlag.ExtensionRefresh,
);
@ -245,11 +240,7 @@ export class VaultHeaderComponent implements OnInit {
}
get canCreateCipher(): boolean {
if (
this.organization?.isProviderUser &&
this.restrictProviderAccessFlag &&
!this.organization?.isMember
) {
if (this.organization?.isProviderUser && !this.organization?.isMember) {
return false;
}
return true;

View File

@ -70,7 +70,6 @@
[viewingOrgVault]="true"
[addAccessStatus]="addAccessStatus$ | async"
[addAccessToggle]="showAddAccessToggle"
[restrictProviderAccess]="restrictProviderAccessEnabled"
>
</app-vault-items>
<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 { AccountService } from "@bitwarden/common/auth/abstractions/account.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";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
@ -172,17 +170,8 @@ export class VaultComponent implements OnInit, OnDestroy {
protected orgRevokedUsers: OrganizationUserUserDetailsResponse[];
private _restrictProviderAccessFlagEnabled: boolean;
protected get restrictProviderAccessEnabled(): boolean {
return this._restrictProviderAccessFlagEnabled;
}
protected get hideVaultFilters(): boolean {
return (
this.restrictProviderAccessEnabled &&
this.organization?.isProviderUser &&
!this.organization?.isMember
);
return this.organization?.isProviderUser && !this.organization?.isMember;
}
private searchText$ = new Subject<string>();
@ -218,7 +207,6 @@ export class VaultComponent implements OnInit, OnDestroy {
private apiService: ApiService,
private collectionService: CollectionService,
private organizationUserApiService: OrganizationUserApiService,
protected configService: ConfigService,
private toastService: ToastService,
private accountService: AccountService,
) {}
@ -230,10 +218,6 @@ export class VaultComponent implements OnInit, OnDestroy {
: "trashCleanupWarning",
);
this._restrictProviderAccessFlagEnabled = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
const filter$ = this.routedVaultFilterService.filter$;
const organizationId$ = filter$.pipe(
map((filter) => filter.organizationId),
@ -325,7 +309,7 @@ export class VaultComponent implements OnInit, OnDestroy {
this.editableCollections$ = this.allCollectionsWithoutUnassigned$.pipe(
map((collections) => {
// 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;
}
// 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
// Return early to avoid 404 response
if (
this.restrictProviderAccessEnabled &&
!organization.isMember &&
organization.isProviderUser
) {
if (!organization.isMember && organization.isProviderUser) {
return [];
}
// 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);
} else {
// Otherwise, only fetch ciphers they have access to (includes unassigned for admins).
@ -476,11 +456,8 @@ export class VaultComponent implements OnInit, OnDestroy {
]).pipe(
map(([filter, collection, organization]) => {
return (
(filter.collectionId === Unassigned &&
!organization.canEditUnassignedCiphers(this.restrictProviderAccessEnabled)) ||
(!organization.canEditAllCiphers(this.restrictProviderAccessEnabled) &&
collection != undefined &&
!collection.node.assigned)
(filter.collectionId === Unassigned && !organization.canEditUnassignedCiphers) ||
(!organization.canEditAllCiphers && collection != undefined && !collection.node.assigned)
);
}),
shareReplay({ refCount: true, bufferSize: 1 }),
@ -525,7 +502,7 @@ export class VaultComponent implements OnInit, OnDestroy {
}
const canEditCipher =
organization.canEditAllCiphers(this.restrictProviderAccessEnabled) ||
organization.canEditAllCiphers ||
(await firstValueFrom(allCipherMap$))[cipherId] != undefined;
if (canEditCipher) {
@ -758,15 +735,9 @@ export class VaultComponent implements OnInit, OnDestroy {
this.allCollectionsWithoutUnassigned$.pipe(
map((c) => {
return c.sort((a, b) => {
if (
a.canEditItems(this.organization, this.restrictProviderAccessEnabled) &&
!b.canEditItems(this.organization, this.restrictProviderAccessEnabled)
) {
if (a.canEditItems(this.organization) && !b.canEditItems(this.organization)) {
return -1;
} else if (
!a.canEditItems(this.organization, this.restrictProviderAccessEnabled) &&
b.canEditItems(this.organization, this.restrictProviderAccessEnabled)
) {
} else if (!a.canEditItems(this.organization) && b.canEditItems(this.organization)) {
return 1;
} else {
return a.name.localeCompare(b.name);
@ -1001,9 +972,7 @@ export class VaultComponent implements OnInit, OnDestroy {
const unassignedCiphers: string[] = [];
// If user has edit all Access no need to check for unassigned ciphers
const canEditAll = this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled);
if (canEditAll) {
if (this.organization.canEditAllCiphers) {
ciphers.map((cipher) => {
editAccessCiphers.push(cipher.id);
});
@ -1042,7 +1011,7 @@ export class VaultComponent implements OnInit, OnDestroy {
}
async deleteCipher(c: CipherView): Promise<boolean> {
if (!c.edit && !this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled)) {
if (!c.edit && !this.organization.canEditAllCiphers) {
this.showMissingPermissionsError();
return;
}
@ -1146,9 +1115,7 @@ export class VaultComponent implements OnInit, OnDestroy {
const canDeleteCollections =
collections == null || collections.every((c) => c.canDelete(organization));
const canDeleteCiphers =
ciphers == null ||
ciphers.every((c) => c.edit) ||
this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled);
ciphers == null || ciphers.every((c) => c.edit) || this.organization.canEditAllCiphers;
if (!canDeleteCiphers || !canDeleteCollections) {
this.showMissingPermissionsError();
@ -1351,8 +1318,7 @@ export class VaultComponent implements OnInit, OnDestroy {
}
protected deleteCipherWithServer(id: string, permanent: boolean, isUnassigned: boolean) {
const asAdmin =
this.organization?.canEditAllCiphers(this.restrictProviderAccessEnabled) || isUnassigned;
const asAdmin = this.organization?.canEditAllCiphers || isUnassigned;
return permanent
? this.cipherService.deleteWithServer(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 { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
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 { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@ -27,7 +25,6 @@ export class CollectionsComponent implements OnInit {
collectionIds: string[];
collections: CollectionView[] = [];
organization: Organization;
restrictProviderAccess: boolean;
protected cipherDomain: Cipher;
@ -38,15 +35,11 @@ export class CollectionsComponent implements OnInit {
protected cipherService: CipherService,
protected organizationService: OrganizationService,
private logService: LogService,
private configService: ConfigService,
private accountService: AccountService,
private toastService: ToastService,
) {}
async ngOnInit() {
this.restrictProviderAccess = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
await this.load();
}
@ -76,7 +69,7 @@ export class CollectionsComponent implements OnInit {
async submit(): Promise<boolean> {
const selectedCollectionIds = this.collections
.filter((c) => {
if (this.organization.canEditAllCiphers(this.restrictProviderAccess)) {
if (this.organization.canEditAllCiphers) {
return !!(c as any).checked;
} else {
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 { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
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 { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@ -92,8 +91,6 @@ export class AddEditComponent implements OnInit, OnDestroy {
private personalOwnershipPolicyAppliesToActiveUser: boolean;
private previousCipherId: string;
protected restrictProviderAccess = false;
get fido2CredentialCreationDateValue(): string {
const dateCreated = this.i18nService.t("dateCreated");
const creationDate = this.datePipe.transform(
@ -182,10 +179,6 @@ export class AddEditComponent implements OnInit, OnDestroy {
}
async ngOnInit() {
this.restrictProviderAccess = await this.configService.getFeatureFlag(
FeatureFlag.RestrictProviderAccess,
);
this.policyService
.policyAppliesToActiveUser$(PolicyType.PersonalOwnership)
.pipe(
@ -683,11 +676,11 @@ export class AddEditComponent implements OnInit, OnDestroy {
protected saveCipher(cipher: Cipher) {
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 (!cipher.collectionIds) {
orgAdmin = this.organization?.canEditUnassignedCiphers(this.restrictProviderAccess);
orgAdmin = this.organization?.canEditUnassignedCiphers;
}
return this.cipher.id == null
@ -696,14 +689,14 @@ export class AddEditComponent implements OnInit, OnDestroy {
}
protected deleteCipher() {
const asAdmin = this.organization?.canEditAllCiphers(this.restrictProviderAccess);
const asAdmin = this.organization?.canEditAllCiphers;
return this.cipher.isDeleted
? this.cipherService.deleteWithServer(this.cipher.id, asAdmin)
: this.cipherService.softDeleteWithServer(this.cipher.id, asAdmin);
}
protected restoreCipher() {
const asAdmin = this.organization?.canEditAllCiphers(this.restrictProviderAccess);
const asAdmin = this.organization?.canEditAllCiphers;
return this.cipherService.restoreWithServer(this.cipher.id, asAdmin);
}

View File

@ -183,14 +183,7 @@ export class Organization {
return this.isAdmin || this.permissions.editAnyCollection;
}
canEditUnassignedCiphers(restrictProviderAccessFlagEnabled: boolean) {
// 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;
}
get canEditUnassignedCiphers() {
return (
this.type === OrganizationUserType.Admin ||
this.type === OrganizationUserType.Owner ||
@ -198,14 +191,7 @@ export class Organization {
);
}
canEditAllCiphers(restrictProviderAccessFlagEnabled: boolean) {
// 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;
}
get canEditAllCiphers() {
// The allowAdminAccessToAllCollectionItems flag can restrict admins
// Custom users with canEditAnyCollection are not affected by allowAdminAccessToAllCollectionItems flag
return (

View File

@ -12,7 +12,6 @@ export enum FeatureFlag {
EnableDeleteProvider = "AC-1218-delete-provider",
ExtensionRefresh = "extension-refresh",
PersistPopupView = "persist-popup-view",
RestrictProviderAccess = "restrict-provider-access",
PM4154_BulkEncryptionService = "PM-4154-bulk-encryption-service",
UseTreeWalkerApiForPageDetailsCollection = "use-tree-walker-api-for-page-details-collection",
EmailVerification = "email-verification",
@ -59,7 +58,6 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.EnableDeleteProvider]: FALSE,
[FeatureFlag.ExtensionRefresh]: FALSE,
[FeatureFlag.PersistPopupView]: FALSE,
[FeatureFlag.RestrictProviderAccess]: FALSE,
[FeatureFlag.PM4154_BulkEncryptionService]: FALSE,
[FeatureFlag.UseTreeWalkerApiForPageDetailsCollection]: 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) {
throw new Error(
"Id of the organization provided does not match the org id of the collection.",
);
}
return (
org?.canEditAllCiphers(restrictProviderAccess) ||
this.manage ||
(this.assigned && !this.readOnly)
);
return org?.canEditAllCiphers || this.manage || (this.assigned && !this.readOnly);
}
/**

View File

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