diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/access-policy.view.ts b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/access-policy.view.ts index 76be88b610..0863bb0ccc 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/access-policy.view.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/access-policy.view.ts @@ -1,44 +1,26 @@ -export class BaseAccessPolicyView { - id: string; +class BaseAccessPolicyView { read: boolean; write: boolean; - creationDate: string; - revisionDate: string; } -export class UserProjectAccessPolicyView extends BaseAccessPolicyView { +export class UserAccessPolicyView extends BaseAccessPolicyView { organizationUserId: string; organizationUserName: string; - grantedProjectId: string; - userId: string; currentUser: boolean; } -export class UserServiceAccountAccessPolicyView extends BaseAccessPolicyView { - organizationUserId: string; - organizationUserName: string; - grantedServiceAccountId: string; - userId: string; - currentUser: boolean; -} - -export class GroupProjectAccessPolicyView extends BaseAccessPolicyView { +export class GroupAccessPolicyView extends BaseAccessPolicyView { groupId: string; groupName: string; - grantedProjectId: string; currentUserInGroup: boolean; } -export class GroupServiceAccountAccessPolicyView extends BaseAccessPolicyView { - groupId: string; - groupName: string; - grantedServiceAccountId: string; - currentUserInGroup: boolean; -} - -export class ServiceAccountProjectAccessPolicyView extends BaseAccessPolicyView { +export class ServiceAccountAccessPolicyView extends BaseAccessPolicyView { serviceAccountId: string; serviceAccountName: string; +} + +export class GrantedProjectAccessPolicyView extends BaseAccessPolicyView { grantedProjectId: string; grantedProjectName: string; } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/project-people-access-policies.view.ts b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/project-people-access-policies.view.ts index c85b289928..9a35e76a61 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/project-people-access-policies.view.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/project-people-access-policies.view.ts @@ -1,6 +1,6 @@ -import { GroupProjectAccessPolicyView, UserProjectAccessPolicyView } from "./access-policy.view"; +import { GroupAccessPolicyView, UserAccessPolicyView } from "./access-policy.view"; export class ProjectPeopleAccessPoliciesView { - userAccessPolicies: UserProjectAccessPolicyView[]; - groupAccessPolicies: GroupProjectAccessPolicyView[]; + userAccessPolicies: UserAccessPolicyView[]; + groupAccessPolicies: GroupAccessPolicyView[]; } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/project-service-accounts-access-policies.view.ts b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/project-service-accounts-access-policies.view.ts index 28636c4df1..9faaa29b69 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/project-service-accounts-access-policies.view.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/project-service-accounts-access-policies.view.ts @@ -1,5 +1,5 @@ -import { ServiceAccountProjectAccessPolicyView } from "./access-policy.view"; +import { ServiceAccountAccessPolicyView } from "./access-policy.view"; export class ProjectServiceAccountsAccessPoliciesView { - serviceAccountAccessPolicies: ServiceAccountProjectAccessPolicyView[]; + serviceAccountAccessPolicies: ServiceAccountAccessPolicyView[]; } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/secret-access-policies.view.ts b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/secret-access-policies.view.ts new file mode 100644 index 0000000000..8742021a42 --- /dev/null +++ b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/secret-access-policies.view.ts @@ -0,0 +1,11 @@ +import { + GroupAccessPolicyView, + UserAccessPolicyView, + ServiceAccountAccessPolicyView, +} from "./access-policy.view"; + +export class SecretAccessPoliciesView { + userAccessPolicies: UserAccessPolicyView[]; + groupAccessPolicies: GroupAccessPolicyView[]; + serviceAccountAccessPolicies: ServiceAccountAccessPolicyView[]; +} diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/service-account-granted-policies.view.ts b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/service-account-granted-policies.view.ts index 7d53e38263..e055daa199 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/service-account-granted-policies.view.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/service-account-granted-policies.view.ts @@ -1,10 +1,10 @@ -import { ServiceAccountProjectAccessPolicyView } from "./access-policy.view"; +import { GrantedProjectAccessPolicyView } from "./access-policy.view"; export class ServiceAccountGrantedPoliciesView { - grantedProjectPolicies: ServiceAccountProjectPolicyPermissionDetailsView[]; + grantedProjectPolicies: GrantedProjectPolicyPermissionDetailsView[]; } -export class ServiceAccountProjectPolicyPermissionDetailsView { - accessPolicy: ServiceAccountProjectAccessPolicyView; +export class GrantedProjectPolicyPermissionDetailsView { + accessPolicy: GrantedProjectAccessPolicyView; hasPermission: boolean; } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/service-account-people-access-policies.view.ts b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/service-account-people-access-policies.view.ts index 58dcf6d470..2ef4eedc33 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/service-account-people-access-policies.view.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/models/view/access-policies/service-account-people-access-policies.view.ts @@ -1,9 +1,6 @@ -import { - GroupServiceAccountAccessPolicyView, - UserServiceAccountAccessPolicyView, -} from "./access-policy.view"; +import { GroupAccessPolicyView, UserAccessPolicyView } from "./access-policy.view"; export class ServiceAccountPeopleAccessPoliciesView { - userAccessPolicies: UserServiceAccountAccessPolicyView[]; - groupAccessPolicies: GroupServiceAccountAccessPolicyView[]; + userAccessPolicies: UserAccessPolicyView[]; + groupAccessPolicies: GroupAccessPolicyView[]; } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-people.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-people.component.ts index c49008c580..0b0e13fe1f 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-people.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-people.component.ts @@ -12,7 +12,7 @@ import { DialogService } from "@bitwarden/components"; import { AccessPolicySelectorService } from "../../shared/access-policies/access-policy-selector/access-policy-selector.service"; import { ApItemValueType, - convertToProjectPeopleAccessPoliciesView, + convertToPeopleAccessPoliciesView, } from "../../shared/access-policies/access-policy-selector/models/ap-item-value.type"; import { ApItemViewType, @@ -119,10 +119,7 @@ export class ProjectPeopleComponent implements OnInit, OnDestroy { } try { - const projectPeopleView = convertToProjectPeopleAccessPoliciesView( - this.projectId, - formValues, - ); + const projectPeopleView = convertToPeopleAccessPoliciesView(formValues); const peoplePoliciesViews = await this.accessPolicyService.putProjectPeopleAccessPolicies( this.projectId, projectPeopleView, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-service-accounts.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-service-accounts.component.ts index 7ac111ef62..1069033b57 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-service-accounts.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-service-accounts.component.ts @@ -144,7 +144,7 @@ export class ProjectServiceAccountsComponent implements OnInit, OnDestroy { projectId: string, selectedPolicies: ApItemValueType[], ): Promise { - const view = convertToProjectServiceAccountsAccessPoliciesView(projectId, selectedPolicies); + const view = convertToProjectServiceAccountsAccessPoliciesView(selectedPolicies); return await this.accessPolicyService.putProjectServiceAccountsAccessPolicies( organizationId, projectId, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/people/service-account-people.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/people/service-account-people.component.ts index a3d3984ea8..31394f7fec 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/people/service-account-people.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/people/service-account-people.component.ts @@ -11,7 +11,7 @@ import { DialogService } from "@bitwarden/components"; import { AccessPolicySelectorService } from "../../shared/access-policies/access-policy-selector/access-policy-selector.service"; import { ApItemValueType, - convertToServiceAccountPeopleAccessPoliciesView, + convertToPeopleAccessPoliciesView, } from "../../shared/access-policies/access-policy-selector/models/ap-item-value.type"; import { ApItemViewType, @@ -180,10 +180,7 @@ export class ServiceAccountPeopleComponent implements OnInit, OnDestroy { serviceAccountId: string, selectedPolicies: ApItemValueType[], ) { - const serviceAccountPeopleView = convertToServiceAccountPeopleAccessPoliciesView( - serviceAccountId, - selectedPolicies, - ); + const serviceAccountPeopleView = convertToPeopleAccessPoliciesView(selectedPolicies); return await this.accessPolicyService.putServiceAccountPeopleAccessPolicies( serviceAccountId, serviceAccountPeopleView, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/projects/service-account-projects.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/projects/service-account-projects.component.ts index 49ddfe331f..358a152b6f 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/projects/service-account-projects.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/projects/service-account-projects.component.ts @@ -144,10 +144,7 @@ export class ServiceAccountProjectsComponent implements OnInit, OnDestroy { serviceAccountId: string, selectedPolicies: ApItemValueType[], ): Promise { - const grantedViews = convertToServiceAccountGrantedPoliciesView( - serviceAccountId, - selectedPolicies, - ); + const grantedViews = convertToServiceAccountGrantedPoliciesView(selectedPolicies); return await this.accessPolicyService.putServiceAccountGrantedPolicies( organizationId, serviceAccountId, diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-value.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-value.spec.ts new file mode 100644 index 0000000000..ad6564a1c6 --- /dev/null +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-value.spec.ts @@ -0,0 +1,238 @@ +import { + convertToSecretAccessPoliciesView, + convertToPeopleAccessPoliciesView, + ApItemValueType, + convertToProjectServiceAccountsAccessPoliciesView, + convertToServiceAccountGrantedPoliciesView, +} from "./ap-item-value.type"; +import { ApItemEnum } from "./enums/ap-item.enum"; +import { ApPermissionEnum } from "./enums/ap-permission.enum"; + +describe("convertToPeopleAccessPoliciesView", () => { + it("should convert selected policy values to user and group access policies view", () => { + const selectedPolicyValues = [...createUserApItems(), ...createGroupApItems()]; + + const result = convertToPeopleAccessPoliciesView(selectedPolicyValues); + + expect(result.userAccessPolicies).toEqual(expectedUserAccessPolicies); + expect(result.groupAccessPolicies).toEqual(expectedGroupAccessPolicies); + }); + + it("should return empty user array if no selected users are provided", () => { + const selectedPolicyValues = createGroupApItems(); + + const result = convertToPeopleAccessPoliciesView(selectedPolicyValues); + + expect(result.userAccessPolicies).toEqual([]); + expect(result.groupAccessPolicies).toEqual(expectedGroupAccessPolicies); + }); + + it("should return empty group array if no selected groups are provided", () => { + const selectedPolicyValues = createUserApItems(); + + const result = convertToPeopleAccessPoliciesView(selectedPolicyValues); + + expect(result.userAccessPolicies).toEqual(expectedUserAccessPolicies); + expect(result.groupAccessPolicies).toEqual([]); + }); + + it("should return empty arrays if no selected policy values are provided", () => { + const selectedPolicyValues: ApItemValueType[] = []; + + const result = convertToPeopleAccessPoliciesView(selectedPolicyValues); + + expect(result.userAccessPolicies).toEqual([]); + expect(result.groupAccessPolicies).toEqual([]); + }); +}); + +describe("convertToServiceAccountGrantedPoliciesView", () => { + it("should convert selected policy values to ServiceAccountGrantedPoliciesView", () => { + const selectedPolicyValues = createProjectApItems(); + + const result = convertToServiceAccountGrantedPoliciesView(selectedPolicyValues); + + expect(result.grantedProjectPolicies).toHaveLength(2); + expect(result.grantedProjectPolicies[0].accessPolicy.grantedProjectId).toBe( + selectedPolicyValues[0].id, + ); + expect(result.grantedProjectPolicies[0].accessPolicy.read).toBe(true); + expect(result.grantedProjectPolicies[0].accessPolicy.write).toBe(false); + + expect(result.grantedProjectPolicies[1].accessPolicy.grantedProjectId).toBe( + selectedPolicyValues[1].id, + ); + expect(result.grantedProjectPolicies[1].accessPolicy.read).toBe(true); + expect(result.grantedProjectPolicies[1].accessPolicy.write).toBe(true); + }); + + it("should return empty array if no selected project policies are provided", () => { + const selectedPolicyValues: ApItemValueType[] = []; + + const result = convertToServiceAccountGrantedPoliciesView(selectedPolicyValues); + + expect(result.grantedProjectPolicies).toEqual([]); + }); +}); + +describe("convertToProjectServiceAccountsAccessPoliciesView", () => { + it("should convert selected policy values to ProjectServiceAccountsAccessPoliciesView", () => { + const selectedPolicyValues = createServiceAccountApItems(); + + const result = convertToProjectServiceAccountsAccessPoliciesView(selectedPolicyValues); + + expect(result.serviceAccountAccessPolicies).toEqual(expectedServiceAccountAccessPolicies); + }); + + it("should return empty array if nothing is selected.", () => { + const selectedPolicyValues: ApItemValueType[] = []; + + const result = convertToProjectServiceAccountsAccessPoliciesView(selectedPolicyValues); + + expect(result.serviceAccountAccessPolicies).toEqual([]); + }); +}); + +describe("convertToSecretAccessPoliciesView", () => { + it("should convert selected policy values to SecretAccessPoliciesView", () => { + const selectedPolicyValues = [ + ...createUserApItems(), + ...createGroupApItems(), + ...createServiceAccountApItems(), + ]; + const result = convertToSecretAccessPoliciesView(selectedPolicyValues); + + expect(result.userAccessPolicies).toEqual(expectedUserAccessPolicies); + expect(result.groupAccessPolicies).toEqual(expectedGroupAccessPolicies); + expect(result.serviceAccountAccessPolicies).toEqual(expectedServiceAccountAccessPolicies); + }); + + it("should return empty user array if no selected users are provided", () => { + const selectedPolicyValues = [...createGroupApItems(), ...createServiceAccountApItems()]; + + const result = convertToSecretAccessPoliciesView(selectedPolicyValues); + + expect(result.userAccessPolicies).toEqual([]); + expect(result.groupAccessPolicies).toEqual(expectedGroupAccessPolicies); + expect(result.serviceAccountAccessPolicies).toEqual(expectedServiceAccountAccessPolicies); + }); + + it("should return empty group array if no selected groups are provided", () => { + const selectedPolicyValues = [...createUserApItems(), ...createServiceAccountApItems()]; + + const result = convertToSecretAccessPoliciesView(selectedPolicyValues); + + expect(result.userAccessPolicies).toEqual(expectedUserAccessPolicies); + expect(result.groupAccessPolicies).toEqual([]); + expect(result.serviceAccountAccessPolicies).toEqual(expectedServiceAccountAccessPolicies); + }); + + it("should return empty service account array if no selected service accounts are provided", () => { + const selectedPolicyValues = [...createUserApItems(), ...createGroupApItems()]; + + const result = convertToSecretAccessPoliciesView(selectedPolicyValues); + + expect(result.userAccessPolicies).toEqual(expectedUserAccessPolicies); + expect(result.groupAccessPolicies).toEqual(expectedGroupAccessPolicies); + expect(result.serviceAccountAccessPolicies).toEqual([]); + }); + + it("should return empty arrays if nothing is selected.", () => { + const selectedPolicyValues: ApItemValueType[] = []; + + const result = convertToSecretAccessPoliciesView(selectedPolicyValues); + + expect(result.userAccessPolicies).toEqual([]); + expect(result.groupAccessPolicies).toEqual([]); + expect(result.serviceAccountAccessPolicies).toEqual([]); + }); +}); + +function createUserApItems(): ApItemValueType[] { + return [ + { + id: "1", + type: ApItemEnum.User, + permission: ApPermissionEnum.CanRead, + }, + { + id: "3", + type: ApItemEnum.User, + permission: ApPermissionEnum.CanReadWrite, + }, + ]; +} + +const expectedUserAccessPolicies = [ + { + organizationUserId: "1", + read: true, + write: false, + }, + { + organizationUserId: "3", + read: true, + write: true, + }, +]; + +function createServiceAccountApItems(): ApItemValueType[] { + return [ + { + id: "1", + type: ApItemEnum.ServiceAccount, + permission: ApPermissionEnum.CanRead, + }, + { + id: "2", + type: ApItemEnum.ServiceAccount, + permission: ApPermissionEnum.CanReadWrite, + }, + ]; +} + +const expectedServiceAccountAccessPolicies = [ + { + serviceAccountId: "1", + read: true, + write: false, + }, + { + serviceAccountId: "2", + read: true, + write: true, + }, +]; + +function createGroupApItems(): ApItemValueType[] { + return [ + { + id: "2", + type: ApItemEnum.Group, + permission: ApPermissionEnum.CanReadWrite, + }, + ]; +} + +const expectedGroupAccessPolicies = [ + { + groupId: "2", + read: true, + write: true, + }, +]; + +function createProjectApItems(): ApItemValueType[] { + return [ + { + id: "1", + type: ApItemEnum.Project, + permission: ApPermissionEnum.CanRead, + }, + { + id: "2", + type: ApItemEnum.Project, + permission: ApPermissionEnum.CanReadWrite, + }, + ]; +} diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-value.type.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-value.type.ts index 935c77f1b3..2de071fb2e 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-value.type.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-value.type.ts @@ -1,17 +1,15 @@ import { - UserProjectAccessPolicyView, - GroupProjectAccessPolicyView, - UserServiceAccountAccessPolicyView, - GroupServiceAccountAccessPolicyView, - ServiceAccountProjectAccessPolicyView, + UserAccessPolicyView, + GroupAccessPolicyView, + ServiceAccountAccessPolicyView, + GrantedProjectAccessPolicyView, } from "../../../../models/view/access-policies/access-policy.view"; -import { ProjectPeopleAccessPoliciesView } from "../../../../models/view/access-policies/project-people-access-policies.view"; import { ProjectServiceAccountsAccessPoliciesView } from "../../../../models/view/access-policies/project-service-accounts-access-policies.view"; +import { SecretAccessPoliciesView } from "../../../../models/view/access-policies/secret-access-policies.view"; import { ServiceAccountGrantedPoliciesView, - ServiceAccountProjectPolicyPermissionDetailsView, + GrantedProjectPolicyPermissionDetailsView, } from "../../../../models/view/access-policies/service-account-granted-policies.view"; -import { ServiceAccountPeopleAccessPoliciesView } from "../../../../models/view/access-policies/service-account-people-access-policies.view"; import { ApItemEnum } from "./enums/ap-item.enum"; import { ApPermissionEnum, ApPermissionEnumUtil } from "./enums/ap-permission.enum"; @@ -24,67 +22,14 @@ export type ApItemValueType = { currentUser?: boolean; }; -export function convertToProjectPeopleAccessPoliciesView( - projectId: string, - selectedPolicyValues: ApItemValueType[], -): ProjectPeopleAccessPoliciesView { - const view = new ProjectPeopleAccessPoliciesView(); - view.userAccessPolicies = selectedPolicyValues - .filter((x) => x.type == ApItemEnum.User) - .map((filtered) => { - const policyView = new UserProjectAccessPolicyView(); - policyView.grantedProjectId = projectId; - policyView.organizationUserId = filtered.id; - policyView.read = ApPermissionEnumUtil.toRead(filtered.permission); - policyView.write = ApPermissionEnumUtil.toWrite(filtered.permission); - return policyView; - }); - - view.groupAccessPolicies = selectedPolicyValues - .filter((x) => x.type == ApItemEnum.Group) - .map((filtered) => { - const policyView = new GroupProjectAccessPolicyView(); - policyView.grantedProjectId = projectId; - policyView.groupId = filtered.id; - policyView.read = ApPermissionEnumUtil.toRead(filtered.permission); - policyView.write = ApPermissionEnumUtil.toWrite(filtered.permission); - return policyView; - }); - return view; -} - -export function convertToServiceAccountPeopleAccessPoliciesView( - serviceAccountId: string, - selectedPolicyValues: ApItemValueType[], -): ServiceAccountPeopleAccessPoliciesView { - const view = new ServiceAccountPeopleAccessPoliciesView(); - view.userAccessPolicies = selectedPolicyValues - .filter((x) => x.type == ApItemEnum.User) - .map((filtered) => { - const policyView = new UserServiceAccountAccessPolicyView(); - policyView.grantedServiceAccountId = serviceAccountId; - policyView.organizationUserId = filtered.id; - policyView.read = ApPermissionEnumUtil.toRead(filtered.permission); - policyView.write = ApPermissionEnumUtil.toWrite(filtered.permission); - policyView.currentUser = filtered.currentUser; - return policyView; - }); - - view.groupAccessPolicies = selectedPolicyValues - .filter((x) => x.type == ApItemEnum.Group) - .map((filtered) => { - const policyView = new GroupServiceAccountAccessPolicyView(); - policyView.grantedServiceAccountId = serviceAccountId; - policyView.groupId = filtered.id; - policyView.read = ApPermissionEnumUtil.toRead(filtered.permission); - policyView.write = ApPermissionEnumUtil.toWrite(filtered.permission); - return policyView; - }); - return view; +export function convertToPeopleAccessPoliciesView(selectedPolicyValues: ApItemValueType[]) { + return { + userAccessPolicies: convertToUserAccessPolicyViews(selectedPolicyValues), + groupAccessPolicies: convertToGroupAccessPolicyViews(selectedPolicyValues), + }; } export function convertToServiceAccountGrantedPoliciesView( - serviceAccountId: string, selectedPolicyValues: ApItemValueType[], ): ServiceAccountGrantedPoliciesView { const view = new ServiceAccountGrantedPoliciesView(); @@ -92,9 +37,8 @@ export function convertToServiceAccountGrantedPoliciesView( view.grantedProjectPolicies = selectedPolicyValues .filter((x) => x.type == ApItemEnum.Project) .map((filtered) => { - const detailView = new ServiceAccountProjectPolicyPermissionDetailsView(); - const policyView = new ServiceAccountProjectAccessPolicyView(); - policyView.serviceAccountId = serviceAccountId; + const detailView = new GrantedProjectPolicyPermissionDetailsView(); + const policyView = new GrantedProjectAccessPolicyView(); policyView.grantedProjectId = filtered.id; policyView.read = ApPermissionEnumUtil.toRead(filtered.permission); policyView.write = ApPermissionEnumUtil.toWrite(filtered.permission); @@ -107,21 +51,57 @@ export function convertToServiceAccountGrantedPoliciesView( } export function convertToProjectServiceAccountsAccessPoliciesView( - projectId: string, selectedPolicyValues: ApItemValueType[], ): ProjectServiceAccountsAccessPoliciesView { - const view = new ProjectServiceAccountsAccessPoliciesView(); + return { + serviceAccountAccessPolicies: convertToServiceAccountAccessPolicyViews(selectedPolicyValues), + }; +} - view.serviceAccountAccessPolicies = selectedPolicyValues - .filter((x) => x.type == ApItemEnum.ServiceAccount) +export function convertToSecretAccessPoliciesView( + selectedPolicyValues: ApItemValueType[], +): SecretAccessPoliciesView { + return { + userAccessPolicies: convertToUserAccessPolicyViews(selectedPolicyValues), + groupAccessPolicies: convertToGroupAccessPolicyViews(selectedPolicyValues), + serviceAccountAccessPolicies: convertToServiceAccountAccessPolicyViews(selectedPolicyValues), + }; +} + +function convertToUserAccessPolicyViews(apItemValues: ApItemValueType[]): UserAccessPolicyView[] { + return apItemValues + .filter((x) => x.type == ApItemEnum.User) .map((filtered) => { - const policyView = new ServiceAccountProjectAccessPolicyView(); - policyView.serviceAccountId = filtered.id; - policyView.grantedProjectId = projectId; + const policyView = new UserAccessPolicyView(); + policyView.organizationUserId = filtered.id; + policyView.read = ApPermissionEnumUtil.toRead(filtered.permission); + policyView.write = ApPermissionEnumUtil.toWrite(filtered.permission); + return policyView; + }); +} + +function convertToGroupAccessPolicyViews(apItemValues: ApItemValueType[]): GroupAccessPolicyView[] { + return apItemValues + .filter((x) => x.type == ApItemEnum.Group) + .map((filtered) => { + const policyView = new GroupAccessPolicyView(); + policyView.groupId = filtered.id; + policyView.read = ApPermissionEnumUtil.toRead(filtered.permission); + policyView.write = ApPermissionEnumUtil.toWrite(filtered.permission); + return policyView; + }); +} + +function convertToServiceAccountAccessPolicyViews( + apItemValues: ApItemValueType[], +): ServiceAccountAccessPolicyView[] { + return apItemValues + .filter((x) => x.type == ApItemEnum.ServiceAccount) + .map((filtered) => { + const policyView = new ServiceAccountAccessPolicyView(); + policyView.serviceAccountId = filtered.id; policyView.read = ApPermissionEnumUtil.toRead(filtered.permission); policyView.write = ApPermissionEnumUtil.toWrite(filtered.permission); return policyView; }); - - return view; } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-view.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-view.spec.ts new file mode 100644 index 0000000000..c709039121 --- /dev/null +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-view.spec.ts @@ -0,0 +1,310 @@ +import { + GroupAccessPolicyView, + ServiceAccountAccessPolicyView, + UserAccessPolicyView, +} from "../../../../models/view/access-policies/access-policy.view"; +import { ProjectPeopleAccessPoliciesView } from "../../../../models/view/access-policies/project-people-access-policies.view"; +import { ProjectServiceAccountsAccessPoliciesView } from "../../../../models/view/access-policies/project-service-accounts-access-policies.view"; +import { SecretAccessPoliciesView } from "../../../../models/view/access-policies/secret-access-policies.view"; +import { ServiceAccountGrantedPoliciesView } from "../../../../models/view/access-policies/service-account-granted-policies.view"; +import { ServiceAccountPeopleAccessPoliciesView } from "../../../../models/view/access-policies/service-account-people-access-policies.view"; + +import { + convertGrantedPoliciesToAccessPolicyItemViews, + convertProjectServiceAccountsViewToApItemViews, + convertSecretAccessPoliciesToApItemViews, + convertToAccessPolicyItemViews, +} from "./ap-item-view.type"; +import { ApItemEnum } from "./enums/ap-item.enum"; +import { ApPermissionEnum } from "./enums/ap-permission.enum"; + +describe("convertToAccessPolicyItemViews", () => { + it("should convert ProjectPeopleAccessPoliciesView to ApItemViewType array", () => { + const accessPoliciesView: ProjectPeopleAccessPoliciesView = createPeopleAccessPoliciesView(); + + const result = convertToAccessPolicyItemViews(accessPoliciesView); + + expect(result).toEqual([...expectedUserApItemViews, ...expectedGroupApItemViews]); + }); + + it("should convert empty ProjectPeopleAccessPoliciesView to empty ApItemViewType array", () => { + const accessPoliciesView = new ProjectPeopleAccessPoliciesView(); + accessPoliciesView.userAccessPolicies = []; + accessPoliciesView.groupAccessPolicies = []; + + const result = convertToAccessPolicyItemViews(accessPoliciesView); + + expect(result).toEqual([]); + }); + + it("should convert ServiceAccountPeopleAccessPoliciesView to ApItemViewType array", () => { + const accessPoliciesView: ServiceAccountPeopleAccessPoliciesView = + createPeopleAccessPoliciesView(); + + const result = convertToAccessPolicyItemViews(accessPoliciesView); + + expect(result).toEqual([...expectedUserApItemViews, ...expectedGroupApItemViews]); + }); + + it("should convert empty ServiceAccountPeopleAccessPoliciesView to empty ApItemViewType array", () => { + const accessPoliciesView = new ServiceAccountPeopleAccessPoliciesView(); + accessPoliciesView.userAccessPolicies = []; + accessPoliciesView.groupAccessPolicies = []; + + const result = convertToAccessPolicyItemViews(accessPoliciesView); + + expect(result).toEqual([]); + }); +}); + +describe("convertGrantedPoliciesToAccessPolicyItemViews", () => { + it("should convert ServiceAccountGrantedPoliciesView to ApItemViewType array", () => { + const grantedPoliciesView: ServiceAccountGrantedPoliciesView = createGrantedPoliciesView(); + + const result = convertGrantedPoliciesToAccessPolicyItemViews(grantedPoliciesView); + + expect(result).toEqual(expectedGrantedProjectApItemViews); + }); + + it("should convert empty ServiceAccountGrantedPoliciesView to empty ApItemViewType array", () => { + const grantedPoliciesView = new ServiceAccountGrantedPoliciesView(); + grantedPoliciesView.grantedProjectPolicies = []; + + const result = convertGrantedPoliciesToAccessPolicyItemViews(grantedPoliciesView); + + expect(result).toEqual([]); + }); +}); + +describe("convertProjectServiceAccountsViewToApItemViews", () => { + it("should convert ProjectServiceAccountsAccessPoliciesView to ApItemViewType array", () => { + const accessPoliciesView = createProjectServiceAccountsAccessPoliciesView(); + + const result = convertProjectServiceAccountsViewToApItemViews(accessPoliciesView); + + expect(result).toEqual([...expectedServiceAccountAccessPolicyViews]); + }); + + it("should convert empty ProjectPeopleAccessPoliciesView to empty ApItemViewType array", () => { + const accessPoliciesView = new ProjectServiceAccountsAccessPoliciesView(); + accessPoliciesView.serviceAccountAccessPolicies = []; + + const result = convertProjectServiceAccountsViewToApItemViews(accessPoliciesView); + + expect(result).toEqual([]); + }); +}); + +describe("convertSecretAccessPoliciesToApItemViews", () => { + it("should convert SecretAccessPoliciesView to ApItemViewType array", () => { + const accessPoliciesView = createSecretAccessPoliciesView(); + + const result = convertSecretAccessPoliciesToApItemViews(accessPoliciesView); + + expect(result).toEqual([ + ...expectedUserApItemViews, + ...expectedGroupApItemViews, + ...expectedServiceAccountAccessPolicyViews, + ]); + }); + + it("should convert empty SecretAccessPoliciesView to empty ApItemViewType array", () => { + const accessPoliciesView = new SecretAccessPoliciesView(); + accessPoliciesView.userAccessPolicies = []; + accessPoliciesView.groupAccessPolicies = []; + accessPoliciesView.serviceAccountAccessPolicies = []; + + const result = convertSecretAccessPoliciesToApItemViews(accessPoliciesView); + + expect(result).toEqual([]); + }); +}); + +function createUserAccessPolicyViews(): UserAccessPolicyView[] { + return [ + { + organizationUserId: "1", + organizationUserName: "Example organization user name", + read: true, + write: false, + currentUser: true, + }, + { + organizationUserId: "2", + organizationUserName: "Example organization user name", + read: true, + write: true, + currentUser: false, + }, + ]; +} + +const expectedUserApItemViews = [ + { + type: ApItemEnum.User, + icon: "bwi-user", + id: "1", + labelName: "Example organization user name", + listName: "Example organization user name", + permission: ApPermissionEnum.CanRead, + currentUser: true, + readOnly: false, + }, + { + type: ApItemEnum.User, + icon: "bwi-user", + id: "2", + labelName: "Example organization user name", + listName: "Example organization user name", + permission: ApPermissionEnum.CanReadWrite, + currentUser: false, + readOnly: false, + }, +]; + +function createGroupAccessPolicyViews(): GroupAccessPolicyView[] { + return [ + { + groupId: "3", + groupName: "Example group name", + currentUserInGroup: true, + read: true, + write: false, + }, + { + groupId: "4", + groupName: "Example group name", + currentUserInGroup: false, + read: true, + write: true, + }, + ]; +} + +const expectedGroupApItemViews = [ + { + type: ApItemEnum.Group, + icon: "bwi-family", + id: "3", + labelName: "Example group name", + listName: "Example group name", + permission: ApPermissionEnum.CanRead, + currentUserInGroup: true, + readOnly: false, + }, + { + type: ApItemEnum.Group, + icon: "bwi-family", + id: "4", + labelName: "Example group name", + listName: "Example group name", + permission: ApPermissionEnum.CanReadWrite, + currentUserInGroup: false, + readOnly: false, + }, +]; + +function createServiceAccountAccessPolicyViews(): ServiceAccountAccessPolicyView[] { + return [ + { + serviceAccountId: "5", + serviceAccountName: "service account name", + read: true, + write: false, + }, + { + serviceAccountId: "6", + serviceAccountName: "service account name", + read: true, + write: true, + }, + ]; +} + +const expectedServiceAccountAccessPolicyViews = [ + { + type: ApItemEnum.ServiceAccount, + icon: "bwi-wrench", + id: "5", + labelName: "service account name", + listName: "service account name", + permission: ApPermissionEnum.CanRead, + readOnly: false, + }, + { + type: ApItemEnum.ServiceAccount, + icon: "bwi-wrench", + id: "6", + labelName: "service account name", + listName: "service account name", + permission: ApPermissionEnum.CanReadWrite, + readOnly: false, + }, +]; + +function createGrantedPoliciesView() { + return { + grantedProjectPolicies: [ + { + accessPolicy: { + grantedProjectId: "1", + grantedProjectName: "Example project name", + read: true, + write: false, + }, + hasPermission: true, + }, + { + accessPolicy: { + grantedProjectId: "2", + grantedProjectName: "project name", + read: true, + write: true, + }, + hasPermission: false, + }, + ], + }; +} + +const expectedGrantedProjectApItemViews = [ + { + type: ApItemEnum.Project, + icon: "bwi-collection", + id: "1", + labelName: "Example project name", + listName: "Example project name", + permission: ApPermissionEnum.CanRead, + readOnly: false, + }, + { + type: ApItemEnum.Project, + icon: "bwi-collection", + id: "2", + labelName: "project name", + listName: "project name", + permission: ApPermissionEnum.CanReadWrite, + readOnly: true, + }, +]; + +function createPeopleAccessPoliciesView() { + return { + userAccessPolicies: createUserAccessPolicyViews(), + groupAccessPolicies: createGroupAccessPolicyViews(), + }; +} + +function createProjectServiceAccountsAccessPoliciesView(): ProjectServiceAccountsAccessPoliciesView { + return { + serviceAccountAccessPolicies: createServiceAccountAccessPolicyViews(), + }; +} + +function createSecretAccessPoliciesView(): SecretAccessPoliciesView { + return { + userAccessPolicies: createUserAccessPolicyViews(), + groupAccessPolicies: createGroupAccessPolicyViews(), + serviceAccountAccessPolicies: createServiceAccountAccessPolicyViews(), + }; +} diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-view.type.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-view.type.ts index 1a023659c1..52a91c5fd6 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-view.type.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy-selector/models/ap-item-view.type.ts @@ -1,9 +1,15 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SelectItemView } from "@bitwarden/components"; +import { + GroupAccessPolicyView, + ServiceAccountAccessPolicyView, + UserAccessPolicyView, +} from "../../../../models/view/access-policies/access-policy.view"; import { PotentialGranteeView } from "../../../../models/view/access-policies/potential-grantee.view"; import { ProjectPeopleAccessPoliciesView } from "../../../../models/view/access-policies/project-people-access-policies.view"; import { ProjectServiceAccountsAccessPoliciesView } from "../../../../models/view/access-policies/project-service-accounts-access-policies.view"; +import { SecretAccessPoliciesView } from "../../../../models/view/access-policies/secret-access-policies.view"; import { ServiceAccountGrantedPoliciesView } from "../../../../models/view/access-policies/service-account-granted-policies.view"; import { ServiceAccountPeopleAccessPoliciesView } from "../../../../models/view/access-policies/service-account-people-access-policies.view"; @@ -11,7 +17,6 @@ import { ApItemEnum, ApItemEnumUtil } from "./enums/ap-item.enum"; import { ApPermissionEnum, ApPermissionEnumUtil } from "./enums/ap-permission.enum"; export type ApItemViewType = SelectItemView & { - accessPolicyId?: string; permission?: ApPermissionEnum; /** * Flag that this item cannot be modified. @@ -22,7 +27,6 @@ export type ApItemViewType = SelectItemView & { } & ( | { type: ApItemEnum.User; - userId?: string; currentUser?: boolean; } | { @@ -40,38 +44,10 @@ export type ApItemViewType = SelectItemView & { export function convertToAccessPolicyItemViews( value: ProjectPeopleAccessPoliciesView | ServiceAccountPeopleAccessPoliciesView, ): ApItemViewType[] { - const accessPolicies: ApItemViewType[] = []; - - value.userAccessPolicies.forEach((policy) => { - accessPolicies.push({ - type: ApItemEnum.User, - icon: ApItemEnumUtil.itemIcon(ApItemEnum.User), - id: policy.organizationUserId, - accessPolicyId: policy.id, - labelName: policy.organizationUserName, - listName: policy.organizationUserName, - permission: ApPermissionEnumUtil.toApPermissionEnum(policy.read, policy.write), - userId: policy.userId, - currentUser: policy.currentUser, - readOnly: false, - }); - }); - - value.groupAccessPolicies.forEach((policy) => { - accessPolicies.push({ - type: ApItemEnum.Group, - icon: ApItemEnumUtil.itemIcon(ApItemEnum.Group), - id: policy.groupId, - accessPolicyId: policy.id, - labelName: policy.groupName, - listName: policy.groupName, - permission: ApPermissionEnumUtil.toApPermissionEnum(policy.read, policy.write), - currentUserInGroup: policy.currentUserInGroup, - readOnly: false, - }); - }); - - return accessPolicies; + return [ + ...toUserApItemViews(value.userAccessPolicies), + ...toGroupApItemViews(value.groupAccessPolicies), + ]; } export function convertGrantedPoliciesToAccessPolicyItemViews( @@ -84,7 +60,6 @@ export function convertGrantedPoliciesToAccessPolicyItemViews( type: ApItemEnum.Project, icon: ApItemEnumUtil.itemIcon(ApItemEnum.Project), id: detailView.accessPolicy.grantedProjectId, - accessPolicyId: detailView.accessPolicy.id, labelName: detailView.accessPolicy.grantedProjectName, listName: detailView.accessPolicy.grantedProjectName, permission: ApPermissionEnumUtil.toApPermissionEnum( @@ -100,24 +75,17 @@ export function convertGrantedPoliciesToAccessPolicyItemViews( export function convertProjectServiceAccountsViewToApItemViews( value: ProjectServiceAccountsAccessPoliciesView, ): ApItemViewType[] { - const accessPolicies: ApItemViewType[] = []; + return toServiceAccountsApItemViews(value.serviceAccountAccessPolicies); +} - value.serviceAccountAccessPolicies.forEach((accessPolicyView) => { - accessPolicies.push({ - type: ApItemEnum.ServiceAccount, - icon: ApItemEnumUtil.itemIcon(ApItemEnum.ServiceAccount), - id: accessPolicyView.serviceAccountId, - accessPolicyId: accessPolicyView.id, - labelName: accessPolicyView.serviceAccountName, - listName: accessPolicyView.serviceAccountName, - permission: ApPermissionEnumUtil.toApPermissionEnum( - accessPolicyView.read, - accessPolicyView.write, - ), - readOnly: false, - }); - }); - return accessPolicies; +export function convertSecretAccessPoliciesToApItemViews( + value: SecretAccessPoliciesView, +): ApItemViewType[] { + return [ + ...toUserApItemViews(value.userAccessPolicies), + ...toGroupApItemViews(value.groupAccessPolicies), + ...toServiceAccountsApItemViews(value.serviceAccountAccessPolicies), + ]; } export function convertPotentialGranteesToApItemViewType( @@ -166,3 +134,49 @@ export function convertPotentialGranteesToApItemViewType( }; }); } + +function toUserApItemViews(policies: UserAccessPolicyView[]): ApItemViewType[] { + return policies.map((policy) => { + return { + type: ApItemEnum.User, + icon: ApItemEnumUtil.itemIcon(ApItemEnum.User), + id: policy.organizationUserId, + labelName: policy.organizationUserName, + listName: policy.organizationUserName, + permission: ApPermissionEnumUtil.toApPermissionEnum(policy.read, policy.write), + currentUser: policy.currentUser, + readOnly: false, + }; + }); +} + +function toGroupApItemViews(policies: GroupAccessPolicyView[]): ApItemViewType[] { + return policies.map((policy) => { + return { + type: ApItemEnum.Group, + icon: ApItemEnumUtil.itemIcon(ApItemEnum.Group), + id: policy.groupId, + labelName: policy.groupName, + listName: policy.groupName, + permission: ApPermissionEnumUtil.toApPermissionEnum(policy.read, policy.write), + currentUserInGroup: policy.currentUserInGroup, + readOnly: false, + }; + }); +} + +function toServiceAccountsApItemViews( + policies: ServiceAccountAccessPolicyView[], +): ApItemViewType[] { + return policies.map((policy) => { + return { + type: ApItemEnum.ServiceAccount, + icon: ApItemEnumUtil.itemIcon(ApItemEnum.ServiceAccount), + id: policy.serviceAccountId, + labelName: policy.serviceAccountName, + listName: policy.serviceAccountName, + permission: ApPermissionEnumUtil.toApPermissionEnum(policy.read, policy.write), + readOnly: false, + }; + }); +} diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts index 32c130647a..67fb9b19bc 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts @@ -8,18 +8,18 @@ import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { - UserProjectAccessPolicyView, - GroupProjectAccessPolicyView, - UserServiceAccountAccessPolicyView, - GroupServiceAccountAccessPolicyView, - ServiceAccountProjectAccessPolicyView, + UserAccessPolicyView, + GroupAccessPolicyView, + ServiceAccountAccessPolicyView, + GrantedProjectAccessPolicyView, } from "../../models/view/access-policies/access-policy.view"; import { PotentialGranteeView } from "../../models/view/access-policies/potential-grantee.view"; import { ProjectPeopleAccessPoliciesView } from "../../models/view/access-policies/project-people-access-policies.view"; import { ProjectServiceAccountsAccessPoliciesView } from "../../models/view/access-policies/project-service-accounts-access-policies.view"; +import { SecretAccessPoliciesView } from "../../models/view/access-policies/secret-access-policies.view"; import { ServiceAccountGrantedPoliciesView, - ServiceAccountProjectPolicyPermissionDetailsView, + GrantedProjectPolicyPermissionDetailsView, } from "../../models/view/access-policies/service-account-granted-policies.view"; import { ServiceAccountPeopleAccessPoliciesView } from "../../models/view/access-policies/service-account-people-access-policies.view"; import { PeopleAccessPoliciesRequest } from "../../shared/access-policies/models/requests/people-access-policies.request"; @@ -28,18 +28,18 @@ import { ServiceAccountGrantedPoliciesRequest } from "../access-policies/models/ import { AccessPolicyRequest } from "./models/requests/access-policy.request"; import { ProjectServiceAccountsAccessPoliciesRequest } from "./models/requests/project-service-accounts-access-policies.request"; import { - GroupServiceAccountAccessPolicyResponse, - UserServiceAccountAccessPolicyResponse, - GroupProjectAccessPolicyResponse, - ServiceAccountProjectAccessPolicyResponse, - UserProjectAccessPolicyResponse, + GroupAccessPolicyResponse, + UserAccessPolicyResponse, + ServiceAccountAccessPolicyResponse, + GrantedProjectAccessPolicyResponse, } from "./models/responses/access-policy.response"; import { PotentialGranteeResponse } from "./models/responses/potential-grantee.response"; import { ProjectPeopleAccessPoliciesResponse } from "./models/responses/project-people-access-policies.response"; import { ProjectServiceAccountsAccessPoliciesResponse } from "./models/responses/project-service-accounts-access-policies.response"; +import { SecretAccessPoliciesResponse } from "./models/responses/secret-access-policies.response"; import { ServiceAccountGrantedPoliciesPermissionDetailsResponse } from "./models/responses/service-account-granted-policies-permission-details.response"; import { ServiceAccountPeopleAccessPoliciesResponse } from "./models/responses/service-account-people-access-policies.response"; -import { ServiceAccountProjectPolicyPermissionDetailsResponse } from "./models/responses/service-account-project-policy-permission-details.response"; +import { GrantedProjectAccessPolicyPermissionDetailsResponse } from "./models/responses/service-account-project-policy-permission-details.response"; @Injectable({ providedIn: "root", @@ -63,7 +63,7 @@ export class AccessPolicyService { ); const results = new ProjectPeopleAccessPoliciesResponse(r); - return this.createProjectPeopleAccessPoliciesView(results); + return this.createPeopleAccessPoliciesView(results); } async putProjectPeopleAccessPolicies( @@ -79,7 +79,7 @@ export class AccessPolicyService { true, ); const results = new ProjectPeopleAccessPoliciesResponse(r); - return this.createProjectPeopleAccessPoliciesView(results); + return this.createPeopleAccessPoliciesView(results); } async getServiceAccountPeopleAccessPolicies( @@ -94,7 +94,7 @@ export class AccessPolicyService { ); const results = new ServiceAccountPeopleAccessPoliciesResponse(r); - return this.createServiceAccountPeopleAccessPoliciesView(results); + return this.createPeopleAccessPoliciesView(results); } async putServiceAccountPeopleAccessPolicies( @@ -110,7 +110,7 @@ export class AccessPolicyService { true, ); const results = new ServiceAccountPeopleAccessPoliciesResponse(r); - return this.createServiceAccountPeopleAccessPoliciesView(results); + return this.createPeopleAccessPoliciesView(results); } async getServiceAccountGrantedPolicies( @@ -181,6 +181,22 @@ export class AccessPolicyService { return await this.createProjectServiceAccountsAccessPoliciesView(result, organizationId); } + async getSecretAccessPolicies( + organizationId: string, + secretId: string, + ): Promise { + const r = await this.apiService.send( + "GET", + "/secrets/" + secretId + "/access-policies", + null, + true, + true, + ); + + const result = new SecretAccessPoliciesResponse(r); + return await this.createSecretAccessPoliciesView(result, organizationId); + } + async getPeoplePotentialGrantees(organizationId: string) { const r = await this.apiService.send( "GET", @@ -223,12 +239,7 @@ export class AccessPolicyService { private getAccessPolicyRequest( granteeId: string, - view: - | UserProjectAccessPolicyView - | UserServiceAccountAccessPolicyView - | GroupProjectAccessPolicyView - | GroupServiceAccountAccessPolicyView - | ServiceAccountProjectAccessPolicyView, + view: UserAccessPolicyView | GroupAccessPolicyView | ServiceAccountAccessPolicyView, ) { const request = new AccessPolicyRequest(); request.granteeId = granteeId; @@ -285,21 +296,79 @@ export class AccessPolicyService { private createBaseAccessPolicyView( response: - | UserProjectAccessPolicyResponse - | UserServiceAccountAccessPolicyResponse - | GroupProjectAccessPolicyResponse - | GroupServiceAccountAccessPolicyResponse - | ServiceAccountProjectAccessPolicyResponse, + | UserAccessPolicyResponse + | GroupAccessPolicyResponse + | ServiceAccountAccessPolicyResponse + | GrantedProjectAccessPolicyResponse, ) { return { - id: response.id, read: response.read, write: response.write, - creationDate: response.creationDate, - revisionDate: response.revisionDate, }; } + private async createGrantedProjectAccessPolicyView( + organizationKey: SymmetricCryptoKey, + response: GrantedProjectAccessPolicyResponse, + ): Promise { + return { + ...this.createBaseAccessPolicyView(response), + grantedProjectId: response.grantedProjectId, + grantedProjectName: response.grantedProjectName + ? await this.encryptService.decryptToUtf8( + new EncString(response.grantedProjectName), + organizationKey, + ) + : null, + }; + } + + private createUserAccessPolicyViews( + responses: UserAccessPolicyResponse[], + ): UserAccessPolicyView[] { + return responses.map((response) => { + return { + ...this.createBaseAccessPolicyView(response), + organizationUserId: response.organizationUserId, + organizationUserName: response.organizationUserName, + currentUser: response.currentUser, + }; + }); + } + + private createGroupAccessPolicyViews( + responses: GroupAccessPolicyResponse[], + ): GroupAccessPolicyView[] { + return responses.map((response) => { + return { + ...this.createBaseAccessPolicyView(response), + groupId: response.groupId, + groupName: response.groupName, + currentUserInGroup: response.currentUserInGroup, + }; + }); + } + + private async createServiceAccountAccessPolicyViews( + orgKey: SymmetricCryptoKey, + responses: ServiceAccountAccessPolicyResponse[], + ): Promise { + return await Promise.all( + responses.map(async (response) => { + return { + ...this.createBaseAccessPolicyView(response), + serviceAccountId: response.serviceAccountId, + serviceAccountName: response.serviceAccountName + ? await this.encryptService.decryptToUtf8( + new EncString(response.serviceAccountName), + orgKey, + ) + : null, + }; + }), + ); + } + private async createPotentialGranteeViews( organizationId: string, results: PotentialGranteeResponse[], @@ -332,137 +401,44 @@ export class AccessPolicyService { ): Promise { const orgKey = await this.getOrganizationKey(organizationId); - const view = new ServiceAccountGrantedPoliciesView(); - view.grantedProjectPolicies = - await this.createServiceAccountProjectPolicyPermissionDetailsViews( + return { + grantedProjectPolicies: await this.createGrantedProjectPolicyPermissionDetailsViews( orgKey, response.grantedProjectPolicies, - ); - return view; + ), + }; } - private async createServiceAccountProjectPolicyPermissionDetailsViews( + private async createGrantedProjectPolicyPermissionDetailsViews( orgKey: SymmetricCryptoKey, - responses: ServiceAccountProjectPolicyPermissionDetailsResponse[], - ): Promise { + responses: GrantedProjectAccessPolicyPermissionDetailsResponse[], + ): Promise { return await Promise.all( responses.map(async (response) => { - return await this.createServiceAccountProjectPolicyPermissionDetailsView(orgKey, response); + return await this.createGrantedProjectPolicyPermissionDetailsView(orgKey, response); }), ); } - private async createServiceAccountProjectPolicyPermissionDetailsView( + private async createGrantedProjectPolicyPermissionDetailsView( orgKey: SymmetricCryptoKey, - response: ServiceAccountProjectPolicyPermissionDetailsResponse, - ): Promise { - const view = new ServiceAccountProjectPolicyPermissionDetailsView(); + response: GrantedProjectAccessPolicyPermissionDetailsResponse, + ): Promise { + const view = new GrantedProjectPolicyPermissionDetailsView(); view.hasPermission = response.hasPermission; - view.accessPolicy = await this.createServiceAccountProjectAccessPolicyView( + view.accessPolicy = await this.createGrantedProjectAccessPolicyView( orgKey, response.accessPolicy, ); return view; } - private createProjectPeopleAccessPoliciesView( - peopleAccessPoliciesResponse: ProjectPeopleAccessPoliciesResponse, - ): ProjectPeopleAccessPoliciesView { - const view = new ProjectPeopleAccessPoliciesView(); - - view.userAccessPolicies = peopleAccessPoliciesResponse.userAccessPolicies.map((ap) => { - return this.createUserProjectAccessPolicyView(ap); - }); - view.groupAccessPolicies = peopleAccessPoliciesResponse.groupAccessPolicies.map((ap) => { - return this.createGroupProjectAccessPolicyView(ap); - }); - return view; - } - - private createServiceAccountPeopleAccessPoliciesView( - response: ServiceAccountPeopleAccessPoliciesResponse, - ): ServiceAccountPeopleAccessPoliciesView { - const view = new ServiceAccountPeopleAccessPoliciesView(); - - view.userAccessPolicies = response.userAccessPolicies.map((ap) => { - return this.createUserServiceAccountAccessPolicyView(ap); - }); - view.groupAccessPolicies = response.groupAccessPolicies.map((ap) => { - return this.createGroupServiceAccountAccessPolicyView(ap); - }); - return view; - } - - private createUserProjectAccessPolicyView( - response: UserProjectAccessPolicyResponse, - ): UserProjectAccessPolicyView { + private createPeopleAccessPoliciesView( + response: ProjectPeopleAccessPoliciesResponse | ServiceAccountPeopleAccessPoliciesResponse, + ) { return { - ...this.createBaseAccessPolicyView(response), - grantedProjectId: response.grantedProjectId, - organizationUserId: response.organizationUserId, - organizationUserName: response.organizationUserName, - userId: response.userId, - currentUser: response.currentUser, - }; - } - - private createGroupProjectAccessPolicyView( - response: GroupProjectAccessPolicyResponse, - ): GroupProjectAccessPolicyView { - return { - ...this.createBaseAccessPolicyView(response), - grantedProjectId: response.grantedProjectId, - groupId: response.groupId, - groupName: response.groupName, - currentUserInGroup: response.currentUserInGroup, - }; - } - - private async createServiceAccountProjectAccessPolicyView( - organizationKey: SymmetricCryptoKey, - response: ServiceAccountProjectAccessPolicyResponse, - ): Promise { - return { - ...this.createBaseAccessPolicyView(response), - grantedProjectId: response.grantedProjectId, - serviceAccountId: response.serviceAccountId, - grantedProjectName: response.grantedProjectName - ? await this.encryptService.decryptToUtf8( - new EncString(response.grantedProjectName), - organizationKey, - ) - : null, - serviceAccountName: response.serviceAccountName - ? await this.encryptService.decryptToUtf8( - new EncString(response.serviceAccountName), - organizationKey, - ) - : null, - }; - } - - private createUserServiceAccountAccessPolicyView( - response: UserServiceAccountAccessPolicyResponse, - ): UserServiceAccountAccessPolicyView { - return { - ...this.createBaseAccessPolicyView(response), - grantedServiceAccountId: response.grantedServiceAccountId, - organizationUserId: response.organizationUserId, - organizationUserName: response.organizationUserName, - userId: response.userId, - currentUser: response.currentUser, - }; - } - - private createGroupServiceAccountAccessPolicyView( - response: GroupServiceAccountAccessPolicyResponse, - ): GroupServiceAccountAccessPolicyView { - return { - ...this.createBaseAccessPolicyView(response), - grantedServiceAccountId: response.grantedServiceAccountId, - groupId: response.groupId, - groupName: response.groupName, - currentUserInGroup: response.currentUserInGroup, + userAccessPolicies: this.createUserAccessPolicyViews(response.userAccessPolicies), + groupAccessPolicies: this.createGroupAccessPolicyViews(response.groupAccessPolicies), }; } @@ -471,13 +447,26 @@ export class AccessPolicyService { organizationId: string, ): Promise { const orgKey = await this.getOrganizationKey(organizationId); + return { + serviceAccountAccessPolicies: await this.createServiceAccountAccessPolicyViews( + orgKey, + response.serviceAccountAccessPolicies, + ), + }; + } - const view = new ProjectServiceAccountsAccessPoliciesView(); - view.serviceAccountAccessPolicies = await Promise.all( - response.serviceAccountAccessPolicies.map(async (ap) => { - return await this.createServiceAccountProjectAccessPolicyView(orgKey, ap); - }), - ); - return view; + private async createSecretAccessPoliciesView( + response: SecretAccessPoliciesResponse, + organizationId: string, + ): Promise { + const orgKey = await this.getOrganizationKey(organizationId); + return { + userAccessPolicies: this.createUserAccessPolicyViews(response.userAccessPolicies), + groupAccessPolicies: this.createGroupAccessPolicyViews(response.groupAccessPolicies), + serviceAccountAccessPolicies: await this.createServiceAccountAccessPolicyViews( + orgKey, + response.serviceAccountAccessPolicies, + ), + }; } } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/access-policy.response.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/access-policy.response.ts index ef076f9b59..88399b4e12 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/access-policy.response.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/access-policy.response.ts @@ -1,96 +1,59 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response"; -export class BaseAccessPolicyResponse extends BaseResponse { - id: string; +class BaseAccessPolicyResponse extends BaseResponse { read: boolean; write: boolean; - creationDate: string; - revisionDate: string; constructor(response: any) { super(response); - this.id = this.getResponseProperty("Id"); this.read = this.getResponseProperty("Read"); this.write = this.getResponseProperty("Write"); - this.creationDate = this.getResponseProperty("CreationDate"); - this.revisionDate = this.getResponseProperty("RevisionDate"); } } -export class UserProjectAccessPolicyResponse extends BaseAccessPolicyResponse { +export class UserAccessPolicyResponse extends BaseAccessPolicyResponse { organizationUserId: string; organizationUserName: string; - grantedProjectId: string; - userId: string; currentUser: boolean; constructor(response: any) { super(response); this.organizationUserId = this.getResponseProperty("OrganizationUserId"); this.organizationUserName = this.getResponseProperty("OrganizationUserName"); - this.grantedProjectId = this.getResponseProperty("GrantedProjectId"); - this.userId = this.getResponseProperty("UserId"); this.currentUser = this.getResponseProperty("CurrentUser"); } } -export class UserServiceAccountAccessPolicyResponse extends BaseAccessPolicyResponse { - organizationUserId: string; - organizationUserName: string; - grantedServiceAccountId: string; - userId: string; - currentUser: boolean; - - constructor(response: any) { - super(response); - this.organizationUserId = this.getResponseProperty("OrganizationUserId"); - this.organizationUserName = this.getResponseProperty("OrganizationUserName"); - this.grantedServiceAccountId = this.getResponseProperty("GrantedServiceAccountId"); - this.userId = this.getResponseProperty("UserId"); - this.currentUser = this.getResponseProperty("CurrentUser"); - } -} - -export class GroupProjectAccessPolicyResponse extends BaseAccessPolicyResponse { +export class GroupAccessPolicyResponse extends BaseAccessPolicyResponse { groupId: string; groupName: string; - grantedProjectId: string; currentUserInGroup: boolean; constructor(response: any) { super(response); this.groupId = this.getResponseProperty("GroupId"); this.groupName = this.getResponseProperty("GroupName"); - this.grantedProjectId = this.getResponseProperty("GrantedProjectId"); this.currentUserInGroup = this.getResponseProperty("CurrentUserInGroup"); } } -export class GroupServiceAccountAccessPolicyResponse extends BaseAccessPolicyResponse { - groupId: string; - groupName: string; - grantedServiceAccountId: string; - currentUserInGroup: boolean; - - constructor(response: any) { - super(response); - this.groupId = this.getResponseProperty("GroupId"); - this.groupName = this.getResponseProperty("GroupName"); - this.grantedServiceAccountId = this.getResponseProperty("GrantedServiceAccountId"); - this.currentUserInGroup = this.getResponseProperty("CurrentUserInGroup"); - } -} - -export class ServiceAccountProjectAccessPolicyResponse extends BaseAccessPolicyResponse { +export class ServiceAccountAccessPolicyResponse extends BaseAccessPolicyResponse { serviceAccountId: string; serviceAccountName: string; - grantedProjectId: string; - grantedProjectName: string; constructor(response: any) { super(response); this.serviceAccountId = this.getResponseProperty("ServiceAccountId"); this.serviceAccountName = this.getResponseProperty("ServiceAccountName"); + } +} + +export class GrantedProjectAccessPolicyResponse extends BaseAccessPolicyResponse { + grantedProjectId: string; + grantedProjectName: string; + + constructor(response: any) { + super(response); this.grantedProjectId = this.getResponseProperty("GrantedProjectId"); this.grantedProjectName = this.getResponseProperty("GrantedProjectName"); } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/project-people-access-policies.response.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/project-people-access-policies.response.ts index 3fa0fa652e..fbd2716807 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/project-people-access-policies.response.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/project-people-access-policies.response.ts @@ -1,23 +1,18 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response"; -import { - GroupProjectAccessPolicyResponse, - UserProjectAccessPolicyResponse, -} from "./access-policy.response"; +import { GroupAccessPolicyResponse, UserAccessPolicyResponse } from "./access-policy.response"; export class ProjectPeopleAccessPoliciesResponse extends BaseResponse { - userAccessPolicies: UserProjectAccessPolicyResponse[]; - groupAccessPolicies: GroupProjectAccessPolicyResponse[]; + userAccessPolicies: UserAccessPolicyResponse[]; + groupAccessPolicies: GroupAccessPolicyResponse[]; constructor(response: any) { super(response); const userAccessPolicies = this.getResponseProperty("UserAccessPolicies"); - this.userAccessPolicies = userAccessPolicies.map( - (k: any) => new UserProjectAccessPolicyResponse(k), - ); + this.userAccessPolicies = userAccessPolicies.map((k: any) => new UserAccessPolicyResponse(k)); const groupAccessPolicies = this.getResponseProperty("GroupAccessPolicies"); this.groupAccessPolicies = groupAccessPolicies.map( - (k: any) => new GroupProjectAccessPolicyResponse(k), + (k: any) => new GroupAccessPolicyResponse(k), ); } } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/project-service-accounts-access-policies.response.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/project-service-accounts-access-policies.response.ts index f26a9996dd..f50be0ca9a 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/project-service-accounts-access-policies.response.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/project-service-accounts-access-policies.response.ts @@ -1,15 +1,15 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response"; -import { ServiceAccountProjectAccessPolicyResponse } from "./access-policy.response"; +import { ServiceAccountAccessPolicyResponse } from "./access-policy.response"; export class ProjectServiceAccountsAccessPoliciesResponse extends BaseResponse { - serviceAccountAccessPolicies: ServiceAccountProjectAccessPolicyResponse[]; + serviceAccountAccessPolicies: ServiceAccountAccessPolicyResponse[]; constructor(response: any) { super(response); const serviceAccountAccessPolicies = this.getResponseProperty("ServiceAccountAccessPolicies"); this.serviceAccountAccessPolicies = serviceAccountAccessPolicies.map( - (k: any) => new ServiceAccountProjectAccessPolicyResponse(k), + (k: any) => new ServiceAccountAccessPolicyResponse(k), ); } } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/secret-access-policies.response.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/secret-access-policies.response.ts new file mode 100644 index 0000000000..ccfcb02d1d --- /dev/null +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/secret-access-policies.response.ts @@ -0,0 +1,27 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +import { + GroupAccessPolicyResponse, + UserAccessPolicyResponse, + ServiceAccountAccessPolicyResponse, +} from "./access-policy.response"; + +export class SecretAccessPoliciesResponse extends BaseResponse { + userAccessPolicies: UserAccessPolicyResponse[]; + groupAccessPolicies: GroupAccessPolicyResponse[]; + serviceAccountAccessPolicies: ServiceAccountAccessPolicyResponse[]; + + constructor(response: any) { + super(response); + const userAccessPolicies = this.getResponseProperty("UserAccessPolicies"); + this.userAccessPolicies = userAccessPolicies.map((k: any) => new UserAccessPolicyResponse(k)); + const groupAccessPolicies = this.getResponseProperty("GroupAccessPolicies"); + this.groupAccessPolicies = groupAccessPolicies.map( + (k: any) => new GroupAccessPolicyResponse(k), + ); + const serviceAccountAccessPolicies = this.getResponseProperty("ServiceAccountAccessPolicies"); + this.serviceAccountAccessPolicies = serviceAccountAccessPolicies.map( + (k: any) => new ServiceAccountAccessPolicyResponse(k), + ); + } +} diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-granted-policies-permission-details.response.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-granted-policies-permission-details.response.ts index 858a59ff43..8925e92f88 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-granted-policies-permission-details.response.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-granted-policies-permission-details.response.ts @@ -1,15 +1,15 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response"; -import { ServiceAccountProjectPolicyPermissionDetailsResponse } from "./service-account-project-policy-permission-details.response"; +import { GrantedProjectAccessPolicyPermissionDetailsResponse } from "./service-account-project-policy-permission-details.response"; export class ServiceAccountGrantedPoliciesPermissionDetailsResponse extends BaseResponse { - grantedProjectPolicies: ServiceAccountProjectPolicyPermissionDetailsResponse[]; + grantedProjectPolicies: GrantedProjectAccessPolicyPermissionDetailsResponse[]; constructor(response: any) { super(response); const grantedProjectPolicies = this.getResponseProperty("GrantedProjectPolicies"); this.grantedProjectPolicies = grantedProjectPolicies.map( - (k: any) => new ServiceAccountProjectPolicyPermissionDetailsResponse(k), + (k: any) => new GrantedProjectAccessPolicyPermissionDetailsResponse(k), ); } } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-people-access-policies.response.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-people-access-policies.response.ts index ca134d9012..74796a4789 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-people-access-policies.response.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-people-access-policies.response.ts @@ -1,23 +1,18 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response"; -import { - GroupServiceAccountAccessPolicyResponse, - UserServiceAccountAccessPolicyResponse, -} from "./access-policy.response"; +import { GroupAccessPolicyResponse, UserAccessPolicyResponse } from "./access-policy.response"; export class ServiceAccountPeopleAccessPoliciesResponse extends BaseResponse { - userAccessPolicies: UserServiceAccountAccessPolicyResponse[]; - groupAccessPolicies: GroupServiceAccountAccessPolicyResponse[]; + userAccessPolicies: UserAccessPolicyResponse[]; + groupAccessPolicies: GroupAccessPolicyResponse[]; constructor(response: any) { super(response); const userAccessPolicies = this.getResponseProperty("UserAccessPolicies"); - this.userAccessPolicies = userAccessPolicies.map( - (k: any) => new UserServiceAccountAccessPolicyResponse(k), - ); + this.userAccessPolicies = userAccessPolicies.map((k: any) => new UserAccessPolicyResponse(k)); const groupAccessPolicies = this.getResponseProperty("GroupAccessPolicies"); this.groupAccessPolicies = groupAccessPolicies.map( - (k: any) => new GroupServiceAccountAccessPolicyResponse(k), + (k: any) => new GroupAccessPolicyResponse(k), ); } } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-project-policy-permission-details.response.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-project-policy-permission-details.response.ts index dbc4fe0727..9cbc6efed8 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-project-policy-permission-details.response.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/models/responses/service-account-project-policy-permission-details.response.ts @@ -1,9 +1,9 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response"; -import { ServiceAccountProjectAccessPolicyResponse } from "./access-policy.response"; +import { GrantedProjectAccessPolicyResponse } from "./access-policy.response"; -export class ServiceAccountProjectPolicyPermissionDetailsResponse extends BaseResponse { - accessPolicy: ServiceAccountProjectAccessPolicyResponse; +export class GrantedProjectAccessPolicyPermissionDetailsResponse extends BaseResponse { + accessPolicy: GrantedProjectAccessPolicyResponse; hasPermission: boolean; constructor(response: any) {