Skip to content

Commit

Permalink
added helper method to make it easier to add privilege rule; reverted…
Browse files Browse the repository at this point in the history
… lookup to check for READ; added privilege rule to Profile, Context + Document to map READ_ABOUT to READ; made addition of READ_ABOUT on Space cascade
  • Loading branch information
techsmyth committed Dec 13, 2024
1 parent edf550a commit 7713b34
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import { ProfileAuthorizationService } from '@domain/common/profile/profile.serv
import { AuthorizationPrivilege, LogContext } from '@common/enums';
import { IAuthorizationPolicyRuleCredential } from '@core/authorization/authorization.policy.rule.credential.interface';
import { EntityNotInitializedException } from '@common/exceptions/entity.not.initialized.exception';
import { IAuthorizationPolicyRulePrivilege } from '@core/authorization/authorization.policy.rule.privilege.interface';
import { AuthorizationPolicyRulePrivilege } from '@core/authorization/authorization.policy.rule.privilege';
import { PRIVILEGE_RULE_TYPES_INNOVATION_FLOW_UPDATE } from '@common/constants/authorization/policy.rule.constants';
import { RelationshipNotFoundException } from '@common/exceptions/relationship.not.found.exception';

Expand Down Expand Up @@ -41,9 +39,13 @@ export class InnovationFlowAuthorizationService {
innovationFlow.authorization = this.appendCredentialRules(
innovationFlow.authorization
);
innovationFlow.authorization = this.appendPrivilegeRules(
innovationFlow.authorization
);
innovationFlow.authorization =
this.authorizationPolicyService.appendPrivilegeAuthorizationRuleMapping(
innovationFlow.authorization,
AuthorizationPrivilege.CREATE,
[AuthorizationPrivilege.UPDATE_INNOVATION_FLOW],
PRIVILEGE_RULE_TYPES_INNOVATION_FLOW_UPDATE
);
updatedAuthorizations.push(innovationFlow.authorization);

const profileAuthorizations =
Expand Down Expand Up @@ -78,27 +80,4 @@ export class InnovationFlowAuthorizationService {

return rules;
}

private appendPrivilegeRules(
authorization: IAuthorizationPolicy | undefined
): IAuthorizationPolicy {
if (!authorization)
throw new EntityNotInitializedException(
'Authorization definition not found',
LogContext.SPACES
);
const privilegeRules: IAuthorizationPolicyRulePrivilege[] = [];

const createPrivilege = new AuthorizationPolicyRulePrivilege(
[AuthorizationPrivilege.UPDATE_INNOVATION_FLOW],
AuthorizationPrivilege.CREATE,
PRIVILEGE_RULE_TYPES_INNOVATION_FLOW_UPDATE
);
privilegeRules.push(createPrivilege);

return this.authorizationPolicyService.appendPrivilegeAuthorizationRules(
authorization,
privilegeRules
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { ICredentialDefinition } from '@domain/agent/credential/credential.defin
import { AuthorizationPolicyType } from '@common/enums/authorization.policy.type';
import { ConfigService } from '@nestjs/config';
import { AlkemioConfig } from '@src/types';
import { AuthorizationPolicyRulePrivilege } from '@core/authorization/authorization.policy.rule.privilege';

@Injectable()
export class AuthorizationPolicyService {
Expand Down Expand Up @@ -289,6 +290,27 @@ export class AuthorizationPolicyService {
return auth;
}

public appendPrivilegeAuthorizationRuleMapping(
authorization: IAuthorizationPolicy | undefined,
sourcePrivilege: AuthorizationPrivilege,
grantedPrivileges: AuthorizationPrivilege[],
name: string
): IAuthorizationPolicy {
const auth = this.validateAuthorization(authorization);
const existingRules = this.authorizationService.convertPrivilegeRulesStr(
auth.privilegeRules
);
const newPrivilegeRule = new AuthorizationPolicyRulePrivilege(
grantedPrivileges,
sourcePrivilege,
name
);
existingRules.push(newPrivilegeRule);

auth.privilegeRules = JSON.stringify(existingRules);
return auth;
}

appendVerifiedCredentialAuthorizationRules(
authorization: IAuthorizationPolicy | undefined,
additionalRules: AuthorizationPolicyRuleVerifiedCredential[]
Expand Down
28 changes: 9 additions & 19 deletions src/domain/common/profile/profile.service.authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { VisualAuthorizationService } from '../visual/visual.service.authorizati
import { StorageBucketAuthorizationService } from '@domain/storage/storage-bucket/storage.bucket.service.authorization';
import { LogContext } from '@common/enums/logging.context';
import { RelationshipNotFoundException } from '@common/exceptions';
import { AuthorizationPolicyRulePrivilege } from '@core/authorization/authorization.policy.rule.privilege';
import { AuthorizationPrivilege } from '@common/enums/authorization.privilege';
import { POLICY_RULE_READ_ABOUT } from '@common/constants/authorization/policy.rule.constants';

Expand Down Expand Up @@ -94,9 +93,15 @@ export class ProfileAuthorizationService {
profile.authorization,
parentAuthorization
);
profile.authorization = this.appendPrivilegeRuleReadAbout(
profile.authorization
);
// If can READ_ABOUT on Profile, then also allow general READ
profile.authorization =
this.authorizationPolicyService.appendPrivilegeAuthorizationRuleMapping(
profile.authorization,
AuthorizationPrivilege.READ_ABOUT,
[AuthorizationPrivilege.READ],
POLICY_RULE_READ_ABOUT
);

updatedAuthorizations.push(profile.authorization);

for (const reference of profile.references) {
Expand Down Expand Up @@ -135,19 +140,4 @@ export class ProfileAuthorizationService {

return updatedAuthorizations;
}

private appendPrivilegeRuleReadAbout(
authorization: IAuthorizationPolicy
): IAuthorizationPolicy {
const readAboutPrivilege = new AuthorizationPolicyRulePrivilege(
[AuthorizationPrivilege.READ_ABOUT],
AuthorizationPrivilege.READ,
POLICY_RULE_READ_ABOUT
);

return this.authorizationPolicyService.appendPrivilegeAuthorizationRules(
authorization,
[readAboutPrivilege]
);
}
}
28 changes: 9 additions & 19 deletions src/domain/context/context/context.service.authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { IContext } from '@domain/context/context';
import { EcosystemModelAuthorizationService } from '@domain/context/ecosystem-model/ecosystem-model.service.authorization';
import { IAuthorizationPolicy } from '@domain/common/authorization-policy';
import { AuthorizationPolicyService } from '@domain/common/authorization-policy/authorization.policy.service';
import { AuthorizationPolicyRulePrivilege } from '@core/authorization/authorization.policy.rule.privilege';
import { AuthorizationPrivilege } from '@common/enums/authorization.privilege';
import { POLICY_RULE_READ_ABOUT } from '@common/constants/authorization/policy.rule.constants';
@Injectable()
Expand All @@ -26,9 +25,15 @@ export class ContextAuthorizationService {
context.authorization,
parentAuthorization
);
context.authorization = this.appendPrivilegeRuleReadAbout(
context.authorization
);

// If can READ_ABOUT on Context, then also allow general READ
context.authorization =
this.authorizationPolicyService.appendPrivilegeAuthorizationRuleMapping(
context.authorization,
AuthorizationPrivilege.READ_ABOUT,
[AuthorizationPrivilege.READ],
POLICY_RULE_READ_ABOUT
);
updatedAuthorizations.push(context.authorization);

// cascade
Expand All @@ -43,19 +48,4 @@ export class ContextAuthorizationService {

return updatedAuthorizations;
}

private appendPrivilegeRuleReadAbout(
authorization: IAuthorizationPolicy
): IAuthorizationPolicy {
const readAboutPrivilege = new AuthorizationPolicyRulePrivilege(
[AuthorizationPrivilege.READ_ABOUT],
AuthorizationPrivilege.READ,
POLICY_RULE_READ_ABOUT
);

return this.authorizationPolicyService.appendPrivilegeAuthorizationRules(
authorization,
[readAboutPrivilege]
);
}
}
56 changes: 17 additions & 39 deletions src/domain/space/space/space.service.authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import {
CREDENTIAL_RULE_SPACE_MEMBERS_READ_ABOUT_SUBSPACES,
} from '@common/constants';
import { IAuthorizationPolicyRuleCredential } from '@core/authorization/authorization.policy.rule.credential.interface';
import { AuthorizationPolicyRulePrivilege } from '@core/authorization/authorization.policy.rule.privilege';
import { ICredentialDefinition } from '@domain/agent/credential/credential.definition.interface';
import { SpaceSettingsService } from '../space.settings/space.settings.service';
import { SpaceLevel } from '@common/enums/space.level';
Expand Down Expand Up @@ -181,12 +180,22 @@ export class SpaceAuthorizationService {
break;
}

space.authorization = this.appendPrivilegeRuleReadAbout(
space.authorization
);
space.authorization = this.appendPrivilegeRuleCreateSubspace(
space.authorization
);
// If can READ, then can of course READ_ABOUT
space.authorization =
this.authorizationPolicyService.appendPrivilegeAuthorizationRuleMapping(
space.authorization,
AuthorizationPrivilege.READ,
[AuthorizationPrivilege.READ_ABOUT],
POLICY_RULE_READ_ABOUT
);
// Ensure that CREATE also allows CREATE_CHALLENGE
space.authorization =
this.authorizationPolicyService.appendPrivilegeAuthorizationRuleMapping(
space.authorization,
AuthorizationPrivilege.CREATE,
[AuthorizationPrivilege.CREATE_SUBSPACE],
POLICY_RULE_SPACE_CREATE_SUBSPACE
);

// Save before proparagating to child entities
space.authorization = await this.authorizationPolicyService.save(
Expand Down Expand Up @@ -350,6 +359,7 @@ export class SpaceAuthorizationService {
parentRoleSetMemberCredentials,
CREDENTIAL_RULE_SPACE_MEMBERS_READ_ABOUT_SUBSPACES
);
readAboutSubspaces.cascade = true; // means whole tree under context + profile have READ_ABOUT
clonedAuthorization =
this.authorizationPolicyService.appendCredentialAuthorizationRules(
clonedAuthorization,
Expand Down Expand Up @@ -544,36 +554,4 @@ export class SpaceAuthorizationService {
newRules
);
}

private appendPrivilegeRuleReadAbout(
authorization: IAuthorizationPolicy
): IAuthorizationPolicy {
const readAboutPrivilege = new AuthorizationPolicyRulePrivilege(
[AuthorizationPrivilege.READ_ABOUT],
AuthorizationPrivilege.READ,
POLICY_RULE_READ_ABOUT
);

return this.authorizationPolicyService.appendPrivilegeAuthorizationRules(
authorization,
[readAboutPrivilege]
);
}

private appendPrivilegeRuleCreateSubspace(
authorization: IAuthorizationPolicy
): IAuthorizationPolicy {
// Ensure that CREATE also allows CREATE_CHALLENGE
const createSubspacePrivilege = new AuthorizationPolicyRulePrivilege(
[AuthorizationPrivilege.CREATE_SUBSPACE],
AuthorizationPrivilege.CREATE,
POLICY_RULE_SPACE_CREATE_SUBSPACE
);
this.authorizationPolicyService.appendPrivilegeAuthorizationRules(
authorization,
[createSubspacePrivilege]
);

return authorization;
}
}
9 changes: 9 additions & 0 deletions src/domain/storage/document/document.service.authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { IAuthorizationPolicyRuleCredential } from '@core/authorization/authorization.policy.rule.credential.interface';
import { CREDENTIAL_RULE_DOCUMENT_CREATED_BY } from '@common/constants/authorization/credential.rule.constants';
import { RelationshipNotFoundException } from '@common/exceptions/relationship.not.found.exception';
import { POLICY_RULE_READ_ABOUT } from '@common/constants/authorization/policy.rule.constants';
@Injectable()
export class DocumentAuthorizationService {
constructor(private authorizationPolicyService: AuthorizationPolicyService) {}
Expand All @@ -32,6 +33,14 @@ export class DocumentAuthorizationService {
document.authorization,
parentAuthorization
);
// If can READ_ABOUT on Document, then also allow general READ
document.authorization =
this.authorizationPolicyService.appendPrivilegeAuthorizationRuleMapping(
document.authorization,
AuthorizationPrivilege.READ_ABOUT,
[AuthorizationPrivilege.READ],
POLICY_RULE_READ_ABOUT
);

// Extend to give the user creating the document more rights
document.authorization = this.appendCredentialRules(document);
Expand Down
22 changes: 9 additions & 13 deletions src/services/api/lookup/lookup.resolver.fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,14 @@ export class LookupResolverFields {
nullable: true,
description: 'Lookup the specified Space',
})
async space(
@CurrentUser() agentInfo: AgentInfo,
@Args('ID', { type: () => UUID }) id: string
): Promise<ISpace> {
async space(@Args('ID', { type: () => UUID }) id: string): Promise<ISpace> {
const space = await this.spaceService.getSpaceOrFail(id);
this.authorizationService.grantAccessOrFail(
agentInfo,
space.authorization,
AuthorizationPrivilege.READ_ABOUT,
`lookup Space: ${space.id}`
);
// this.authorizationService.grantAccessOrFail(
// agentInfo,
// space.authorization,
// AuthorizationPrivilege.READ_ABOUT,
// `lookup Space: ${space.id}`
// );

return space;
}
Expand Down Expand Up @@ -150,7 +147,6 @@ export class LookupResolverFields {
description: 'Lookup the specified RoleSet',
})
async roleSet(
@CurrentUser() agentInfo: AgentInfo,
@Args('ID', { type: () => UUID }) id: string
): Promise<IRoleSet> {
const roleSet = await this.roleSetService.getRoleSetOrFail(id);
Expand Down Expand Up @@ -500,7 +496,7 @@ export class LookupResolverFields {
this.authorizationService.grantAccessOrFail(
agentInfo,
context.authorization,
AuthorizationPrivilege.READ_ABOUT,
AuthorizationPrivilege.READ,
`lookup Context: ${context.id}`
);

Expand Down Expand Up @@ -539,7 +535,7 @@ export class LookupResolverFields {
this.authorizationService.grantAccessOrFail(
agentInfo,
profile.authorization,
AuthorizationPrivilege.READ_ABOUT,
AuthorizationPrivilege.READ,
`lookup Profile: ${profile.id}`
);

Expand Down

0 comments on commit 7713b34

Please sign in to comment.