Skip to content

Commit

Permalink
fixed guard usage in XState machines; removed APPLICATION_ACCEPT whic…
Browse files Browse the repository at this point in the history
…h is equivalent to GRANT (#4675)

Co-authored-by: Valentin Yanakiev <[email protected]>
  • Loading branch information
techsmyth and valentinyanakiev authored Nov 6, 2024
1 parent e2431d7 commit 79375ae
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 42 deletions.
1 change: 0 additions & 1 deletion src/common/enums/authorization.privilege.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -26,10 +23,6 @@ export class ApplicationAuthorizationService {
parentAuthorization
);

application.authorization = this.appendPrivilegeRules(
application.authorization
);

application.authorization =
await this.extendAuthorizationPolicy(application);

Expand All @@ -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(
[
Expand All @@ -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]
);
}
}
10 changes: 5 additions & 5 deletions src/domain/access/application/application.service.lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,19 @@ export const applicationLifecycleMachine: ILifecycleDefinition = {
new: {
on: {
APPROVE: {
guards: 'hasApplicationAcceptPrivilege',
guard: 'hasGrantPrivilege',
target: ApplicationLifecycleState.APPROVING,
},
REJECT: {
guards: 'hasUpdatePrivilege',
guard: 'hasUpdatePrivilege',
target: ApplicationLifecycleState.REJECTED,
},
},
},
approving: {
on: {
APPROVED: {
guards: 'hasApplicationAcceptPrivilege',
guard: 'hasGrantPrivilege',
target: ApplicationLifecycleState.APPROVED,
},
},
Expand All @@ -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,
},
},
Expand Down
10 changes: 5 additions & 5 deletions src/domain/access/invitation/invitation.service.lifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,19 @@ export const invitationLifecycleMachine: ILifecycleDefinition = {
invited: {
on: {
ACCEPT: {
guards: 'hasInvitationAcceptPrivilege',
guard: 'hasInvitationAcceptPrivilege',
target: InvitationLifecycleState.ACCEPTING,
},
REJECT: {
guards: 'hasUpdatePrivilege',
guard: 'hasUpdatePrivilege',
target: InvitationLifecycleState.REJECTED,
},
},
},
accepting: {
on: {
ACCEPTED: {
guards: 'hasInvitationAcceptPrivilege',
guard: 'hasInvitationAcceptPrivilege',
target: InvitationLifecycleState.ACCEPTED,
},
},
Expand All @@ -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,
},
},
Expand Down
4 changes: 2 additions & 2 deletions src/domain/access/role-set/role.set.resolver.mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
);
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export class OrganizationVerificationLifecycleService {
VERIFICATION_REQUEST: {
target:
OrganizationVerificationLifecycleState.VERIFICATION_PENDING,
guards: {
guard: {
type: 'hasUpdatePrivilege',
},
},
Expand All @@ -94,7 +94,7 @@ export class OrganizationVerificationLifecycleService {
on: {
MANUALLY_VERIFY: {
target: OrganizationVerificationLifecycleState.MANUALLY_VERIFIED,
guards: 'hasGrantPrivilege',
guard: 'hasGrantPrivilege',
},
REJECT: OrganizationVerificationLifecycleState.REJECTED,
},
Expand All @@ -104,19 +104,19 @@ export class OrganizationVerificationLifecycleService {
on: {
RESET: {
target: OrganizationVerificationLifecycleState.NOT_VERIFIED,
guards: 'hasGrantPrivilege',
guard: 'hasGrantPrivilege',
},
},
},
rejected: {
on: {
REOPEN: {
target: OrganizationVerificationLifecycleState.NOT_VERIFIED,
guards: 'hasGrantPrivilege',
guard: 'hasGrantPrivilege',
},
ARCHIVE: {
target: OrganizationVerificationLifecycleState.ARCHIVED,
guards: 'hasGrantPrivilege',
guard: 'hasGrantPrivilege',
},
},
},
Expand Down

0 comments on commit 79375ae

Please sign in to comment.