mirror of
https://github.com/bitwarden/browser.git
synced 2024-08-27 23:31:41 +02:00
add check for PersonalOwnershipPolicy in vault filters (#9570)
This commit is contained in:
parent
d594b680f9
commit
cbc34950fb
|
@ -3,6 +3,8 @@ import { FormBuilder } from "@angular/forms";
|
||||||
import { BehaviorSubject, skipWhile } from "rxjs";
|
import { BehaviorSubject, skipWhile } 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 { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
|
import { PolicyType } 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 { ProductType } from "@bitwarden/common/enums";
|
import { ProductType } from "@bitwarden/common/enums";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -23,6 +25,7 @@ describe("VaultPopupListFiltersService", () => {
|
||||||
const folderViews$ = new BehaviorSubject([]);
|
const folderViews$ = new BehaviorSubject([]);
|
||||||
const cipherViews$ = new BehaviorSubject({});
|
const cipherViews$ = new BehaviorSubject({});
|
||||||
const decryptedCollections$ = new BehaviorSubject<CollectionView[]>([]);
|
const decryptedCollections$ = new BehaviorSubject<CollectionView[]>([]);
|
||||||
|
const policyAppliesToActiveUser$ = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
const collectionService = {
|
const collectionService = {
|
||||||
decryptedCollections$,
|
decryptedCollections$,
|
||||||
|
@ -45,9 +48,15 @@ describe("VaultPopupListFiltersService", () => {
|
||||||
t: (key: string) => key,
|
t: (key: string) => key,
|
||||||
} as I18nService;
|
} as I18nService;
|
||||||
|
|
||||||
|
const policyService = {
|
||||||
|
policyAppliesToActiveUser$: jest.fn(() => policyAppliesToActiveUser$),
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
memberOrganizations$.next([]);
|
memberOrganizations$.next([]);
|
||||||
decryptedCollections$.next([]);
|
decryptedCollections$.next([]);
|
||||||
|
policyAppliesToActiveUser$.next(false);
|
||||||
|
policyService.policyAppliesToActiveUser$.mockClear();
|
||||||
|
|
||||||
collectionService.getAllNested = () => Promise.resolve([]);
|
collectionService.getAllNested = () => Promise.resolve([]);
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
|
@ -72,6 +81,10 @@ describe("VaultPopupListFiltersService", () => {
|
||||||
provide: CollectionService,
|
provide: CollectionService,
|
||||||
useValue: collectionService,
|
useValue: collectionService,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: PolicyService,
|
||||||
|
useValue: policyService,
|
||||||
|
},
|
||||||
{ provide: FormBuilder, useClass: FormBuilder },
|
{ provide: FormBuilder, useClass: FormBuilder },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
@ -127,6 +140,65 @@ describe("VaultPopupListFiltersService", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("PersonalOwnership policy", () => {
|
||||||
|
it('calls policyAppliesToActiveUser$ with "PersonalOwnership"', () => {
|
||||||
|
expect(policyService.policyAppliesToActiveUser$).toHaveBeenCalledWith(
|
||||||
|
PolicyType.PersonalOwnership,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns an empty array when the policy applies and there is a single organization", (done) => {
|
||||||
|
policyAppliesToActiveUser$.next(true);
|
||||||
|
memberOrganizations$.next([
|
||||||
|
{ name: "bobby's org", id: "1234-3323-23223" },
|
||||||
|
] as Organization[]);
|
||||||
|
|
||||||
|
service.organizations$.subscribe((organizations) => {
|
||||||
|
expect(organizations).toEqual([]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds "myVault" when the policy does not apply and there are multiple organizations', (done) => {
|
||||||
|
policyAppliesToActiveUser$.next(false);
|
||||||
|
const orgs = [
|
||||||
|
{ name: "bobby's org", id: "1234-3323-23223" },
|
||||||
|
{ name: "alice's org", id: "2223-4343-99888" },
|
||||||
|
] as Organization[];
|
||||||
|
|
||||||
|
memberOrganizations$.next(orgs);
|
||||||
|
|
||||||
|
service.organizations$.subscribe((organizations) => {
|
||||||
|
expect(organizations.map((o) => o.label)).toEqual([
|
||||||
|
"myVault",
|
||||||
|
"alice's org",
|
||||||
|
"bobby's org",
|
||||||
|
]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not add "myVault" the policy applies and there are multiple organizations', (done) => {
|
||||||
|
policyAppliesToActiveUser$.next(true);
|
||||||
|
const orgs = [
|
||||||
|
{ name: "bobby's org", id: "1234-3323-23223" },
|
||||||
|
{ name: "alice's org", id: "2223-3242-99888" },
|
||||||
|
{ name: "catherine's org", id: "77733-4343-99888" },
|
||||||
|
] as Organization[];
|
||||||
|
|
||||||
|
memberOrganizations$.next(orgs);
|
||||||
|
|
||||||
|
service.organizations$.subscribe((organizations) => {
|
||||||
|
expect(organizations.map((o) => o.label)).toEqual([
|
||||||
|
"alice's org",
|
||||||
|
"bobby's org",
|
||||||
|
"catherine's org",
|
||||||
|
]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("icons", () => {
|
describe("icons", () => {
|
||||||
it("sets family icon for family organizations", (done) => {
|
it("sets family icon for family organizations", (done) => {
|
||||||
const orgs = [
|
const orgs = [
|
||||||
|
|
|
@ -13,6 +13,8 @@ import {
|
||||||
|
|
||||||
import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model";
|
import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model";
|
||||||
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 { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
|
||||||
|
import { PolicyType } 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 { ProductType } from "@bitwarden/common/enums";
|
import { ProductType } from "@bitwarden/common/enums";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
|
@ -88,6 +90,7 @@ export class VaultPopupListFiltersService {
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private collectionService: CollectionService,
|
private collectionService: CollectionService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
|
private policyService: PolicyService,
|
||||||
) {
|
) {
|
||||||
this.filterForm.controls.organization.valueChanges
|
this.filterForm.controls.organization.valueChanges
|
||||||
.pipe(takeUntilDestroyed())
|
.pipe(takeUntilDestroyed())
|
||||||
|
@ -167,44 +170,63 @@ export class VaultPopupListFiltersService {
|
||||||
/**
|
/**
|
||||||
* Organization array structured to be directly passed to `ChipSelectComponent`
|
* Organization array structured to be directly passed to `ChipSelectComponent`
|
||||||
*/
|
*/
|
||||||
organizations$: Observable<ChipSelectOption<Organization>[]> =
|
organizations$: Observable<ChipSelectOption<Organization>[]> = combineLatest([
|
||||||
this.organizationService.memberOrganizations$.pipe(
|
this.organizationService.memberOrganizations$,
|
||||||
map((orgs) => orgs.sort(Utils.getSortFunction(this.i18nService, "name"))),
|
this.policyService.policyAppliesToActiveUser$(PolicyType.PersonalOwnership),
|
||||||
map((orgs) => {
|
]).pipe(
|
||||||
if (!orgs.length) {
|
map(([orgs, personalOwnershipApplies]): [Organization[], boolean] => [
|
||||||
return [];
|
orgs.sort(Utils.getSortFunction(this.i18nService, "name")),
|
||||||
}
|
personalOwnershipApplies,
|
||||||
|
]),
|
||||||
|
map(([orgs, personalOwnershipApplies]) => {
|
||||||
|
// When there are no organizations return an empty array,
|
||||||
|
// resulting in the org filter being hidden
|
||||||
|
if (!orgs.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
// When there is only one organization and personal ownership policy applies,
|
||||||
// When the user is a member of an organization, make the "My Vault" option available
|
// return an empty array, resulting in the org filter being hidden
|
||||||
{
|
if (orgs.length === 1 && personalOwnershipApplies) {
|
||||||
value: { id: MY_VAULT_ID } as Organization,
|
return [];
|
||||||
label: this.i18nService.t("myVault"),
|
}
|
||||||
icon: "bwi-user",
|
|
||||||
},
|
|
||||||
...orgs.map((org) => {
|
|
||||||
let icon = "bwi-business";
|
|
||||||
|
|
||||||
if (!org.enabled) {
|
const myVaultOrg: ChipSelectOption<Organization>[] = [];
|
||||||
// Show a warning icon if the organization is deactivated
|
|
||||||
icon = "bwi-exclamation-triangle tw-text-danger";
|
|
||||||
} else if (
|
|
||||||
org.planProductType === ProductType.Families ||
|
|
||||||
org.planProductType === ProductType.Free
|
|
||||||
) {
|
|
||||||
// Show a family icon if the organization is a family or free org
|
|
||||||
icon = "bwi-family";
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
// Only add "My vault" if personal ownership policy does not apply
|
||||||
value: org,
|
if (!personalOwnershipApplies) {
|
||||||
label: org.name,
|
myVaultOrg.push({
|
||||||
icon,
|
value: { id: MY_VAULT_ID } as Organization,
|
||||||
};
|
label: this.i18nService.t("myVault"),
|
||||||
}),
|
icon: "bwi-user",
|
||||||
];
|
});
|
||||||
}),
|
}
|
||||||
);
|
|
||||||
|
return [
|
||||||
|
...myVaultOrg,
|
||||||
|
...orgs.map((org) => {
|
||||||
|
let icon = "bwi-business";
|
||||||
|
|
||||||
|
if (!org.enabled) {
|
||||||
|
// Show a warning icon if the organization is deactivated
|
||||||
|
icon = "bwi-exclamation-triangle tw-text-danger";
|
||||||
|
} else if (
|
||||||
|
org.planProductType === ProductType.Families ||
|
||||||
|
org.planProductType === ProductType.Free
|
||||||
|
) {
|
||||||
|
// Show a family icon if the organization is a family or free org
|
||||||
|
icon = "bwi-family";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: org,
|
||||||
|
label: org.name,
|
||||||
|
icon,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Folder array structured to be directly passed to `ChipSelectComponent`
|
* Folder array structured to be directly passed to `ChipSelectComponent`
|
||||||
|
|
Loading…
Reference in New Issue
Block a user