diff --git a/src/common/enums/authorization.privilege.ts b/src/common/enums/authorization.privilege.ts index 9a97b27fa5..a48180b0e1 100644 --- a/src/common/enums/authorization.privilege.ts +++ b/src/common/enums/authorization.privilege.ts @@ -30,7 +30,6 @@ export enum AuthorizationPrivilege { UPDATE_INNOVATION_FLOW = 'update-innovation-flow', COMMUNITY_JOIN = 'community-join', COMMUNITY_APPLY = 'community-apply', - COMMUNITY_APPLY_ACCEPT = 'community-apply-accept', COMMUNITY_INVITE = 'community-invite', COMMUNITY_INVITE_ACCEPT = 'community-invite-accept', COMMUNITY_ADD_MEMBER = 'community-add-member', // only for global admins diff --git a/src/domain/access/application/application.service.authorization.ts b/src/domain/access/application/application.service.authorization.ts index 5f062aefc9..bf85939470 100644 --- a/src/domain/access/application/application.service.authorization.ts +++ b/src/domain/access/application/application.service.authorization.ts @@ -6,9 +6,6 @@ import { IAuthorizationPolicy } from '@domain/common/authorization-policy/author import { IApplication } from './application.interface'; import { IAuthorizationPolicyRuleCredential } from '@core/authorization/authorization.policy.rule.credential.interface'; import { CREDENTIAL_RULE_COMMUNITY_USER_APPLICATION } from '@common/constants/authorization/credential.rule.constants'; -import { AuthorizationPolicyRulePrivilege } from '@core/authorization/authorization.policy.rule.privilege'; -import { POLICY_RULE_COMMUNITY_APPROVE_APPLICATION } from '@common/constants'; - @Injectable() export class ApplicationAuthorizationService { constructor( @@ -26,10 +23,6 @@ export class ApplicationAuthorizationService { parentAuthorization ); - application.authorization = this.appendPrivilegeRules( - application.authorization - ); - application.authorization = await this.extendAuthorizationPolicy(application); @@ -45,6 +38,7 @@ export class ApplicationAuthorizationService { const user = await this.applicationService.getContributor(application.id); // also grant the user privileges to manage their own application + // Note: the GRANT privilege iS NOT assigned to the user; that is what is actually used to approve the application const userApplicationRule = this.authorizationPolicyService.createCredentialRule( [ @@ -67,19 +61,4 @@ export class ApplicationAuthorizationService { newRules ); } - - private appendPrivilegeRules( - authorization: IAuthorizationPolicy - ): IAuthorizationPolicy { - const approveApplicationPrivilege = new AuthorizationPolicyRulePrivilege( - [AuthorizationPrivilege.COMMUNITY_APPLY_ACCEPT], - AuthorizationPrivilege.GRANT, - POLICY_RULE_COMMUNITY_APPROVE_APPLICATION - ); - - return this.authorizationPolicyService.appendPrivilegeAuthorizationRules( - authorization, - [approveApplicationPrivilege] - ); - } } diff --git a/src/domain/access/application/application.service.lifecycle.ts b/src/domain/access/application/application.service.lifecycle.ts index e27f5f0644..7d02fdaf54 100644 --- a/src/domain/access/application/application.service.lifecycle.ts +++ b/src/domain/access/application/application.service.lifecycle.ts @@ -60,11 +60,11 @@ export const applicationLifecycleMachine: ILifecycleDefinition = { new: { on: { APPROVE: { - guards: 'hasApplicationAcceptPrivilege', + guard: 'hasGrantPrivilege', target: ApplicationLifecycleState.APPROVING, }, REJECT: { - guards: 'hasUpdatePrivilege', + guard: 'hasUpdatePrivilege', target: ApplicationLifecycleState.REJECTED, }, }, @@ -72,7 +72,7 @@ export const applicationLifecycleMachine: ILifecycleDefinition = { approving: { on: { APPROVED: { - guards: 'hasApplicationAcceptPrivilege', + guard: 'hasGrantPrivilege', target: ApplicationLifecycleState.APPROVED, }, }, @@ -83,11 +83,11 @@ export const applicationLifecycleMachine: ILifecycleDefinition = { rejected: { on: { REOPEN: { - guards: 'hasUpdatePrivilege', + guard: 'hasUpdatePrivilege', target: ApplicationLifecycleState.NEW, }, ARCHIVE: { - guards: 'hasUpdatePrivilege', + guard: 'hasUpdatePrivilege', target: ApplicationLifecycleState.ARCHIVED, }, }, diff --git a/src/domain/access/invitation/invitation.service.lifecycle.ts b/src/domain/access/invitation/invitation.service.lifecycle.ts index 6f67f7d7b1..92d0db07e7 100644 --- a/src/domain/access/invitation/invitation.service.lifecycle.ts +++ b/src/domain/access/invitation/invitation.service.lifecycle.ts @@ -61,11 +61,11 @@ export const invitationLifecycleMachine: ILifecycleDefinition = { invited: { on: { ACCEPT: { - guards: 'hasInvitationAcceptPrivilege', + guard: 'hasInvitationAcceptPrivilege', target: InvitationLifecycleState.ACCEPTING, }, REJECT: { - guards: 'hasUpdatePrivilege', + guard: 'hasUpdatePrivilege', target: InvitationLifecycleState.REJECTED, }, }, @@ -73,7 +73,7 @@ export const invitationLifecycleMachine: ILifecycleDefinition = { accepting: { on: { ACCEPTED: { - guards: 'hasInvitationAcceptPrivilege', + guard: 'hasInvitationAcceptPrivilege', target: InvitationLifecycleState.ACCEPTED, }, }, @@ -84,11 +84,11 @@ export const invitationLifecycleMachine: ILifecycleDefinition = { rejected: { on: { REINVITE: { - guards: 'hasUpdatePrivilege', + guard: 'hasUpdatePrivilege', target: InvitationLifecycleState.INVITED, }, ARCHIVE: { - guards: 'hasUpdatePrivilege', + guard: 'hasUpdatePrivilege', target: InvitationLifecycleState.ARCHIVED, }, }, diff --git a/src/domain/access/role-set/role.set.resolver.mutations.ts b/src/domain/access/role-set/role.set.resolver.mutations.ts index b1627bba01..5f1726b654 100644 --- a/src/domain/access/role-set/role.set.resolver.mutations.ts +++ b/src/domain/access/role-set/role.set.resolver.mutations.ts @@ -693,11 +693,11 @@ export class RoleSetResolverMutations { eventData.applicationID ); - //toDo fix this temporary fix. Patches the immediate issue but doesn't solve the design issue of guards not being triggered on transitions + // Assumption is that the user with the GRANT also has UPDATE this.authorizationService.grantAccessOrFail( agentInfo, application.authorization, - AuthorizationPrivilege.COMMUNITY_APPLY_ACCEPT, + AuthorizationPrivilege.UPDATE, `event on application: ${application.id}` ); diff --git a/src/domain/access/role-set/role.set.service.lifecycle.application.ts b/src/domain/access/role-set/role.set.service.lifecycle.application.ts index ac00819474..a687c4c5c0 100644 --- a/src/domain/access/role-set/role.set.service.lifecycle.application.ts +++ b/src/domain/access/role-set/role.set.service.lifecycle.application.ts @@ -24,6 +24,7 @@ export class RoleSetServiceLifecycleApplication { private getMachine(): AnyStateMachine { const machine = setup({ guards: { + // UPDATE privilege is used to manage lifecycle transitions, EXCEPT those related to approving which require GRANT hasUpdatePrivilege: ({ event }) => { const agentInfo: AgentInfo = event.agentInfo; const authorizationPolicy: IAuthorizationPolicy = event.authorization; @@ -33,13 +34,13 @@ export class RoleSetServiceLifecycleApplication { AuthorizationPrivilege.UPDATE ); }, - hasApplicationAcceptPrivilege: ({ event }) => { + hasGrantPrivilege: ({ event }) => { const agentInfo: AgentInfo = event.agentInfo; const authorizationPolicy: IAuthorizationPolicy = event.authorization; return this.authorizationService.isAccessGranted( agentInfo, authorizationPolicy, - AuthorizationPrivilege.COMMUNITY_APPLY_ACCEPT + AuthorizationPrivilege.GRANT ); }, }, diff --git a/src/domain/community/organization-verification/organization.verification.service.lifecycle.ts b/src/domain/community/organization-verification/organization.verification.service.lifecycle.ts index 4b71d3a107..4cdfc590f5 100644 --- a/src/domain/community/organization-verification/organization.verification.service.lifecycle.ts +++ b/src/domain/community/organization-verification/organization.verification.service.lifecycle.ts @@ -84,7 +84,7 @@ export class OrganizationVerificationLifecycleService { VERIFICATION_REQUEST: { target: OrganizationVerificationLifecycleState.VERIFICATION_PENDING, - guards: { + guard: { type: 'hasUpdatePrivilege', }, }, @@ -94,7 +94,7 @@ export class OrganizationVerificationLifecycleService { on: { MANUALLY_VERIFY: { target: OrganizationVerificationLifecycleState.MANUALLY_VERIFIED, - guards: 'hasGrantPrivilege', + guard: 'hasGrantPrivilege', }, REJECT: OrganizationVerificationLifecycleState.REJECTED, }, @@ -104,7 +104,7 @@ export class OrganizationVerificationLifecycleService { on: { RESET: { target: OrganizationVerificationLifecycleState.NOT_VERIFIED, - guards: 'hasGrantPrivilege', + guard: 'hasGrantPrivilege', }, }, }, @@ -112,11 +112,11 @@ export class OrganizationVerificationLifecycleService { on: { REOPEN: { target: OrganizationVerificationLifecycleState.NOT_VERIFIED, - guards: 'hasGrantPrivilege', + guard: 'hasGrantPrivilege', }, ARCHIVE: { target: OrganizationVerificationLifecycleState.ARCHIVED, - guards: 'hasGrantPrivilege', + guard: 'hasGrantPrivilege', }, }, },