From 6ac6df75d7a9bd5ea58f5d8310f1b3e34abd2bde Mon Sep 17 00:00:00 2001 From: Addison Beck Date: Mon, 11 Jan 2021 17:01:39 -0500 Subject: [PATCH] Implemented Custom role and permissions (#237) * Implemented Custom role and permissions * converted Permissions interface into a class * formatting fix --- src/angular/components/add-edit.component.ts | 2 +- src/enums/organizationUserType.ts | 1 + src/enums/permissions.ts | 12 +++++ src/models/api/permissionsApi.ts | 33 ++++++++++++++ src/models/data/organizationData.ts | 3 ++ src/models/domain/organization.ts | 44 +++++++++++++++++++ .../request/organizationUserInviteRequest.ts | 6 ++- .../request/organizationUserUpdateRequest.ts | 6 ++- .../response/organizationUserResponse.ts | 10 +++-- .../response/profileOrganizationResponse.ts | 3 ++ 10 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 src/enums/permissions.ts create mode 100644 src/models/api/permissionsApi.ts diff --git a/src/angular/components/add-edit.component.ts b/src/angular/components/add-edit.component.ts index 567dbadb45..ede0b2f107 100644 --- a/src/angular/components/add-edit.component.ts +++ b/src/angular/components/add-edit.component.ts @@ -162,7 +162,7 @@ export class AddEditComponent implements OnInit { orgs.sort(Utils.getSortFunction(this.i18nService, 'name')).forEach((o) => { if (o.enabled && o.status === OrganizationUserStatusType.Confirmed) { this.ownershipOptions.push({ name: o.name, value: o.id }); - if (policies != null && o.usePolicies && !o.isAdmin && this.allowPersonal) { + if (policies != null && o.usePolicies && !o.canManagePolicies && this.allowPersonal) { for (const policy of policies) { if (policy.organizationId === o.id && policy.enabled) { this.allowPersonal = false; diff --git a/src/enums/organizationUserType.ts b/src/enums/organizationUserType.ts index de794fe690..632d22b01e 100644 --- a/src/enums/organizationUserType.ts +++ b/src/enums/organizationUserType.ts @@ -3,4 +3,5 @@ export enum OrganizationUserType { Admin = 1, User = 2, Manager = 3, + Custom = 4, } diff --git a/src/enums/permissions.ts b/src/enums/permissions.ts new file mode 100644 index 0000000000..bcf76c6080 --- /dev/null +++ b/src/enums/permissions.ts @@ -0,0 +1,12 @@ +export enum Permissions { + AccessBusinessPortal, + AccessEventLogs, + AccessImportExport, + AccessReports, + ManageAllCollections, + ManageAssignedCollections, + ManageGroups, + ManageOrganization, + ManagePolicies, + ManageUsers, +} diff --git a/src/models/api/permissionsApi.ts b/src/models/api/permissionsApi.ts new file mode 100644 index 0000000000..93e141982a --- /dev/null +++ b/src/models/api/permissionsApi.ts @@ -0,0 +1,33 @@ +import { BaseResponse } from '../response/baseResponse'; + +export class PermissionsApi extends BaseResponse { + accessBusinessPortal: boolean; + accessEventLogs: boolean; + accessImportExport: boolean; + accessReports: boolean; + manageAllCollections: boolean; + manageAssignedCollections: boolean; + manageCiphers: boolean; + manageGroups: boolean; + manageSso: boolean; + managePolicies: boolean; + manageUsers: boolean; + + constructor(data: any = null) { + super(data); + if (data == null) { + return this; + } + this.accessBusinessPortal = this.getResponseProperty('AccessBusinessPortal'); + this.accessEventLogs = this.getResponseProperty('AccessEventLogs'); + this.accessImportExport = this.getResponseProperty('AccessImportExport'); + this.accessReports = this.getResponseProperty('AccessReports'); + this.manageAllCollections = this.getResponseProperty('ManageAllCollections'); + this.manageAssignedCollections = this.getResponseProperty('ManageAssignedCollections'); + this.manageCiphers = this.getResponseProperty('ManageCiphers'); + this.manageGroups = this.getResponseProperty('ManageGroups'); + this.manageSso = this.getResponseProperty('ManageSso'); + this.managePolicies = this.getResponseProperty('ManagePolicies'); + this.manageUsers = this.getResponseProperty('ManageUsers'); + } +} diff --git a/src/models/data/organizationData.ts b/src/models/data/organizationData.ts index d6d10dbbd4..9470ab37a4 100644 --- a/src/models/data/organizationData.ts +++ b/src/models/data/organizationData.ts @@ -2,6 +2,7 @@ import { ProfileOrganizationResponse } from '../response/profileOrganizationResp import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType'; import { OrganizationUserType } from '../../enums/organizationUserType'; +import { PermissionsApi } from '../api/permissionsApi'; export class OrganizationData { id: string; @@ -25,6 +26,7 @@ export class OrganizationData { maxStorageGb?: number; ssoBound: boolean; identifier: string; + permissions: PermissionsApi; constructor(response: ProfileOrganizationResponse) { this.id = response.id; @@ -48,5 +50,6 @@ export class OrganizationData { this.maxStorageGb = response.maxStorageGb; this.ssoBound = response.ssoBound; this.identifier = response.identifier; + this.permissions = response.permissions; } } diff --git a/src/models/domain/organization.ts b/src/models/domain/organization.ts index f616f2e1c3..c3c24dfe88 100644 --- a/src/models/domain/organization.ts +++ b/src/models/domain/organization.ts @@ -2,6 +2,8 @@ import { OrganizationData } from '../data/organizationData'; import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType'; import { OrganizationUserType } from '../../enums/organizationUserType'; +import { PermissionsApi } from '../api/permissionsApi'; + export class Organization { id: string; @@ -25,6 +27,7 @@ export class Organization { maxStorageGb?: number; ssoBound: boolean; identifier: string; + permissions: PermissionsApi; constructor(obj?: OrganizationData) { if (obj == null) { @@ -52,6 +55,7 @@ export class Organization { this.maxStorageGb = obj.maxStorageGb; this.ssoBound = obj.ssoBound; this.identifier = obj.identifier; + this.permissions = obj.permissions; } get canAccess() { @@ -73,4 +77,44 @@ export class Organization { get isOwner() { return this.type === OrganizationUserType.Owner; } + + get canAccessBusinessPortal() { + return this.isAdmin || this.permissions.accessBusinessPortal; + } + + get canAccessEventLogs() { + return this.isAdmin || this.permissions.accessEventLogs; + } + + get canAccessImportExport() { + return this.isAdmin || this.permissions.accessImportExport; + } + + get canAccessReports() { + return this.isAdmin || this.permissions.accessReports; + } + + get canManageAllCollections() { + return this.isAdmin || this.permissions.manageAllCollections; + } + + get canManageAssignedCollections() { + return this.isManager || this.permissions.manageAssignedCollections; + } + + get canManageGroups() { + return this.isAdmin || this.permissions.manageGroups; + } + + get canManageSso() { + return this.isAdmin || this.permissions.manageSso; + } + + get canManagePolicies() { + return this.isAdmin || this.permissions.managePolicies; + } + + get canManageUsers() { + return this.isAdmin || this.permissions.manageUsers; + } } diff --git a/src/models/request/organizationUserInviteRequest.ts b/src/models/request/organizationUserInviteRequest.ts index 79371e99ed..4195eec85a 100644 --- a/src/models/request/organizationUserInviteRequest.ts +++ b/src/models/request/organizationUserInviteRequest.ts @@ -1,10 +1,12 @@ -import { OrganizationUserType } from '../../enums/organizationUserType'; - import { SelectionReadOnlyRequest } from './selectionReadOnlyRequest'; +import { OrganizationUserType } from '../../enums/organizationUserType'; +import { PermissionsApi } from '../api/permissionsApi'; + export class OrganizationUserInviteRequest { emails: string[] = []; type: OrganizationUserType; accessAll: boolean; collections: SelectionReadOnlyRequest[] = []; + permissions: PermissionsApi; } diff --git a/src/models/request/organizationUserUpdateRequest.ts b/src/models/request/organizationUserUpdateRequest.ts index 7b8c9cd237..80803cd650 100644 --- a/src/models/request/organizationUserUpdateRequest.ts +++ b/src/models/request/organizationUserUpdateRequest.ts @@ -1,9 +1,11 @@ -import { OrganizationUserType } from '../../enums/organizationUserType'; - import { SelectionReadOnlyRequest } from './selectionReadOnlyRequest'; +import { OrganizationUserType } from '../../enums/organizationUserType'; +import { PermissionsApi } from '../api/permissionsApi'; + export class OrganizationUserUpdateRequest { type: OrganizationUserType; accessAll: boolean; collections: SelectionReadOnlyRequest[] = []; + permissions: PermissionsApi; } diff --git a/src/models/response/organizationUserResponse.ts b/src/models/response/organizationUserResponse.ts index 444e27906b..08d3dbed98 100644 --- a/src/models/response/organizationUserResponse.ts +++ b/src/models/response/organizationUserResponse.ts @@ -1,15 +1,18 @@ -import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType'; -import { OrganizationUserType } from '../../enums/organizationUserType'; - import { BaseResponse } from './baseResponse'; import { SelectionReadOnlyResponse } from './selectionReadOnlyResponse'; +import { PermissionsApi } from '../api/permissionsApi'; + +import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType'; +import { OrganizationUserType } from '../../enums/organizationUserType'; + export class OrganizationUserResponse extends BaseResponse { id: string; userId: string; type: OrganizationUserType; status: OrganizationUserStatusType; accessAll: boolean; + permissions: PermissionsApi; constructor(response: any) { super(response); @@ -17,6 +20,7 @@ export class OrganizationUserResponse extends BaseResponse { this.userId = this.getResponseProperty('UserId'); this.type = this.getResponseProperty('Type'); this.status = this.getResponseProperty('Status'); + this.permissions = new PermissionsApi(this.getResponseProperty('Permissions')); this.accessAll = this.getResponseProperty('AccessAll'); } } diff --git a/src/models/response/profileOrganizationResponse.ts b/src/models/response/profileOrganizationResponse.ts index 91a4c350d6..9b8a15dae8 100644 --- a/src/models/response/profileOrganizationResponse.ts +++ b/src/models/response/profileOrganizationResponse.ts @@ -2,6 +2,7 @@ import { BaseResponse } from './baseResponse'; import { OrganizationUserStatusType } from '../../enums/organizationUserStatusType'; import { OrganizationUserType } from '../../enums/organizationUserType'; +import { PermissionsApi } from '../api/permissionsApi'; export class ProfileOrganizationResponse extends BaseResponse { id: string; @@ -26,6 +27,7 @@ export class ProfileOrganizationResponse extends BaseResponse { enabled: boolean; ssoBound: boolean; identifier: string; + permissions: PermissionsApi; constructor(response: any) { super(response); @@ -51,5 +53,6 @@ export class ProfileOrganizationResponse extends BaseResponse { this.enabled = this.getResponseProperty('Enabled'); this.ssoBound = this.getResponseProperty('SsoBound'); this.identifier = this.getResponseProperty('Identifier'); + this.permissions = new PermissionsApi(this.getResponseProperty('permissions')); } }