360 lines
12 KiB
TypeScript
360 lines
12 KiB
TypeScript
import { mock, MockProxy } from "jest-mock-extended";
|
|
|
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
|
import { OrganizationUserType } from "@bitwarden/common/admin-console/enums";
|
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
|
|
|
import { AccessPolicySelectorService } from "./access-policy-selector.service";
|
|
import { ApItemValueType } from "./models/ap-item-value.type";
|
|
import { ApItemViewType } from "./models/ap-item-view.type";
|
|
import { ApItemEnum } from "./models/enums/ap-item.enum";
|
|
import { ApPermissionEnum } from "./models/enums/ap-permission.enum";
|
|
|
|
describe("AccessPolicySelectorService", () => {
|
|
let organizationService: MockProxy<OrganizationService>;
|
|
|
|
let sut: AccessPolicySelectorService;
|
|
|
|
beforeEach(() => {
|
|
organizationService = mock<OrganizationService>();
|
|
|
|
sut = new AccessPolicySelectorService(organizationService);
|
|
});
|
|
|
|
afterEach(() => jest.resetAllMocks());
|
|
|
|
describe("showAccessRemovalWarning", () => {
|
|
it("returns false when current user is admin", async () => {
|
|
const org = orgFactory();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
it("returns false when current user is owner", async () => {
|
|
const org = orgFactory();
|
|
org.type = OrganizationUserType.Owner;
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
it("returns true when current user isn't owner/admin and all policies are removed", async () => {
|
|
const org = setupUserOrg();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
it("returns true when current user isn't owner/admin and user policy is set to canRead", async () => {
|
|
const org = setupUserOrg();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [];
|
|
selectedPolicyValues.push(
|
|
createApItemValueType({
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
);
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
it("returns false when current user isn't owner/admin and user policy is set to canReadWrite", async () => {
|
|
const org = setupUserOrg();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
permission: ApPermissionEnum.CanReadWrite,
|
|
currentUser: true,
|
|
}),
|
|
];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
it("returns true when current user isn't owner/admin and a group Read policy is submitted that the user is a member of", async () => {
|
|
const org = setupUserOrg();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
id: "groupId",
|
|
type: ApItemEnum.Group,
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUserInGroup: true,
|
|
}),
|
|
];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
it("returns false when current user isn't owner/admin and a group ReadWrite policy is submitted that the user is a member of", async () => {
|
|
const org = setupUserOrg();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
id: "groupId",
|
|
type: ApItemEnum.Group,
|
|
permission: ApPermissionEnum.CanReadWrite,
|
|
currentUserInGroup: true,
|
|
}),
|
|
];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
it("returns true when current user isn't owner/admin and a group ReadWrite policy is submitted that the user is not a member of", async () => {
|
|
const org = setupUserOrg();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
id: "groupId",
|
|
type: ApItemEnum.Group,
|
|
permission: ApPermissionEnum.CanReadWrite,
|
|
currentUserInGroup: false,
|
|
}),
|
|
];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
it("returns false when current user isn't owner/admin, user policy is set to CanRead, and user is in read write group", async () => {
|
|
const org = setupUserOrg();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
createApItemValueType({
|
|
id: "groupId",
|
|
type: ApItemEnum.Group,
|
|
permission: ApPermissionEnum.CanReadWrite,
|
|
currentUserInGroup: true,
|
|
}),
|
|
];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(false);
|
|
});
|
|
|
|
it("returns true when current user isn't owner/admin, user policy is set to CanRead, and user is not in ReadWrite group", async () => {
|
|
const org = setupUserOrg();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
createApItemValueType({
|
|
id: "groupId",
|
|
type: ApItemEnum.Group,
|
|
permission: ApPermissionEnum.CanReadWrite,
|
|
currentUserInGroup: false,
|
|
}),
|
|
];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(true);
|
|
});
|
|
|
|
it("returns true when current user isn't owner/admin, user policy is set to CanRead, and user is in Read group", async () => {
|
|
const org = setupUserOrg();
|
|
organizationService.get.calledWith(org.id).mockResolvedValue(org);
|
|
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
createApItemValueType({
|
|
id: "groupId",
|
|
type: ApItemEnum.Group,
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUserInGroup: true,
|
|
}),
|
|
];
|
|
|
|
const result = await sut.showAccessRemovalWarning(org.id, selectedPolicyValues);
|
|
|
|
expect(result).toBe(true);
|
|
});
|
|
});
|
|
describe("isAccessRemoval", () => {
|
|
it("returns false when there are no previous policies and no selected policies", async () => {
|
|
const currentAccessPolicies: ApItemViewType[] = [];
|
|
const selectedPolicyValues: ApItemValueType[] = [];
|
|
|
|
const result = sut.isAccessRemoval(currentAccessPolicies, selectedPolicyValues);
|
|
|
|
expect(result).toBe(false);
|
|
});
|
|
it("returns false when there are no previous policies", async () => {
|
|
const currentAccessPolicies: ApItemViewType[] = [];
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
id: "example",
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
];
|
|
|
|
const result = sut.isAccessRemoval(currentAccessPolicies, selectedPolicyValues);
|
|
|
|
expect(result).toBe(false);
|
|
});
|
|
it("returns false when previous policies and selected policies are the same", async () => {
|
|
const currentAccessPolicies: ApItemViewType[] = [
|
|
createApItemViewType({
|
|
id: "example",
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
];
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
id: "example",
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
];
|
|
|
|
const result = sut.isAccessRemoval(currentAccessPolicies, selectedPolicyValues);
|
|
|
|
expect(result).toBe(false);
|
|
});
|
|
it("returns false when previous policies are still selected", async () => {
|
|
const currentAccessPolicies: ApItemViewType[] = [
|
|
createApItemViewType({
|
|
id: "example",
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
];
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
id: "example",
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
createApItemValueType({
|
|
id: "example-2",
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
];
|
|
|
|
const result = sut.isAccessRemoval(currentAccessPolicies, selectedPolicyValues);
|
|
|
|
expect(result).toBe(false);
|
|
});
|
|
it("returns true when previous policies are not selected", async () => {
|
|
const currentAccessPolicies: ApItemViewType[] = [
|
|
createApItemViewType({
|
|
id: "example",
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
];
|
|
const selectedPolicyValues: ApItemValueType[] = [
|
|
createApItemValueType({
|
|
id: "test",
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
createApItemValueType({
|
|
id: "example-2",
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
];
|
|
|
|
const result = sut.isAccessRemoval(currentAccessPolicies, selectedPolicyValues);
|
|
|
|
expect(result).toBe(true);
|
|
});
|
|
it("returns true when there are previous policies and nothing was selected", async () => {
|
|
const currentAccessPolicies: ApItemViewType[] = [
|
|
createApItemViewType({
|
|
permission: ApPermissionEnum.CanRead,
|
|
currentUser: true,
|
|
}),
|
|
];
|
|
const selectedPolicyValues: ApItemValueType[] = [];
|
|
|
|
const result = sut.isAccessRemoval(currentAccessPolicies, selectedPolicyValues);
|
|
|
|
expect(result).toBe(true);
|
|
});
|
|
});
|
|
});
|
|
|
|
const orgFactory = (props: Partial<Organization> = {}) =>
|
|
Object.assign(
|
|
new Organization(),
|
|
{
|
|
id: "myOrgId",
|
|
enabled: true,
|
|
type: OrganizationUserType.Admin,
|
|
},
|
|
props,
|
|
);
|
|
|
|
function createApItemValueType(options: Partial<ApItemValueType> = {}) {
|
|
return {
|
|
id: options?.id ?? "test",
|
|
type: options?.type ?? ApItemEnum.User,
|
|
permission: options?.permission ?? ApPermissionEnum.CanRead,
|
|
currentUserInGroup: options?.currentUserInGroup ?? false,
|
|
};
|
|
}
|
|
|
|
function createApItemViewType(options: Partial<ApItemViewType> = {}) {
|
|
return {
|
|
id: options?.id ?? "test",
|
|
listName: options?.listName ?? "test",
|
|
labelName: options?.labelName ?? "test",
|
|
type: options?.type ?? ApItemEnum.User,
|
|
permission: options?.permission ?? ApPermissionEnum.CanRead,
|
|
readOnly: options?.readOnly ?? false,
|
|
};
|
|
}
|
|
|
|
function setupUserOrg() {
|
|
const userId = "testUserId";
|
|
const org = orgFactory({ userId: userId });
|
|
org.type = OrganizationUserType.User;
|
|
return org;
|
|
}
|