Skip to content

Commit

Permalink
Merge pull request #1375 from sofyalaski/split-casl
Browse files Browse the repository at this point in the history
refactor(casl-ability): split factory function
  • Loading branch information
sofyalaski authored Aug 21, 2024
2 parents 9216dea + 43e2185 commit 3e4dc8b
Show file tree
Hide file tree
Showing 16 changed files with 1,091 additions and 835 deletions.
1,579 changes: 892 additions & 687 deletions src/casl/casl-ability.factory.ts

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/casl/decorators/check-policies.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import { PolicyHandler } from "../interfaces/policy-handler.interface";

export const CHECK_POLICIES_KEY = "check_policy";

export const CheckPolicies = (...handlers: PolicyHandler[]) =>
SetMetadata(CHECK_POLICIES_KEY, handlers);
export const CheckPolicies = (endpoint: string, ...handlers: PolicyHandler[]) =>
SetMetadata(CHECK_POLICIES_KEY, { endpoint, handlers });
19 changes: 12 additions & 7 deletions src/casl/guards/policies.guard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,27 @@ export class PoliciesGuard implements CanActivate {
) {}

async canActivate(context: ExecutionContext): Promise<boolean> {
const policyHandlers =
this.reflector.get<PolicyHandler[]>(
CHECK_POLICIES_KEY,
context.getHandler(),
) || [];
const policyData = this.reflector.get<{
endpoint: string;
handlers: PolicyHandler[];
}>(CHECK_POLICIES_KEY, context.getHandler());

if (!policyData) {
return false;
}

const policyHandlers = policyData["handlers"];
const endpoint = policyData["endpoint"];
const req = context.switchToHttp().getRequest();
const user = req.user;
const ability = this.caslAbilityFactory.createForUser(user);

const ability = this.caslAbilityFactory.endpointAccess(endpoint, user);
return policyHandlers.every((handler) =>
this.execPolicyHandler(handler, ability),
);
}

private execPolicyHandler(handler: PolicyHandler, ability: AppAbility) {
//console.log('PoliciesGuard:execPolicyHandler ', handler, ability)
if (typeof handler === "function") {
const res = handler(ability);
//console.log("PoliciesGuard:execPolicyHandler ", res);
Expand Down
78 changes: 39 additions & 39 deletions src/datasets/datasets.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class DatasetsController {
): IFilters<DatasetDocument, IDatasetFields> {
const user: JWTUser = request.user as JWTUser;

const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass);
const canViewOwner = ability.can(Action.DatasetReadManyOwner, DatasetClass);
const canViewAccess = ability.can(
Expand Down Expand Up @@ -205,7 +205,7 @@ export class DatasetsController {
const datasetInstance =
await this.generateDatasetInstanceForPermissions(dataset);

const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);

let canDoAction = false;

Expand Down Expand Up @@ -290,7 +290,7 @@ export class DatasetsController {
const datasetInstance =
await this.generateDatasetInstanceForPermissions(dataset);

const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
const canView =
ability.can(Action.DatasetReadAny, DatasetClass) ||
ability.can(Action.DatasetReadOneOwner, datasetInstance) ||
Expand Down Expand Up @@ -355,7 +355,7 @@ export class DatasetsController {
const datasetInstance =
await this.generateDatasetInstanceForPermissions(dataset);
// instantiate the casl matrix for the user
const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
// check if he/she can create this dataset
const canCreate =
ability.can(Action.DatasetCreateAny, DatasetClass) ||
Expand Down Expand Up @@ -389,7 +389,7 @@ export class DatasetsController {

// POST /datasets
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetCreate, DatasetClass),
)
@UseInterceptors(
Expand Down Expand Up @@ -510,7 +510,7 @@ export class DatasetsController {
}

@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetCreate, DatasetClass),
)
@UseInterceptors(
Expand Down Expand Up @@ -568,7 +568,7 @@ export class DatasetsController {

// GET /datasets
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetRead, DatasetClass),
)
@UseInterceptors(MainDatasetsPublicInterceptor)
Expand Down Expand Up @@ -650,7 +650,7 @@ export class DatasetsController {

// GET /datasets/fullquery
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetRead, DatasetClass),
)
@UseInterceptors(SubDatasetsPublicInterceptor, FullQueryInterceptor)
Expand Down Expand Up @@ -691,7 +691,7 @@ export class DatasetsController {
const user: JWTUser = request.user as JWTUser;
const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}");

const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass);

if (!canViewAny && !fields.isPublished) {
Expand Down Expand Up @@ -729,7 +729,7 @@ export class DatasetsController {

// GET /fullfacets
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetRead, DatasetClass),
)
@UseInterceptors(SubDatasetsPublicInterceptor)
Expand Down Expand Up @@ -769,7 +769,7 @@ export class DatasetsController {
const user: JWTUser = request.user as JWTUser;
const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}");

const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass);

if (!canViewAny && !fields.isPublished) {
Expand Down Expand Up @@ -811,7 +811,7 @@ export class DatasetsController {

// GET /datasets/metadataKeys
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetRead, DatasetClass),
)
@UseInterceptors(SubDatasetsPublicInterceptor)
Expand Down Expand Up @@ -850,7 +850,7 @@ export class DatasetsController {
const user: JWTUser = request.user as JWTUser;
const fields: IDatasetFields = JSON.parse(filters.fields ?? "{}");

const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
const canViewAny = ability.can(Action.DatasetReadAny, DatasetClass);

if (!canViewAny && !fields.isPublished) {
Expand Down Expand Up @@ -890,7 +890,7 @@ export class DatasetsController {

// GET /datasets/findOne
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetRead, DatasetClass),
)
@Get("/findOne")
Expand Down Expand Up @@ -961,7 +961,7 @@ export class DatasetsController {

// GET /datasets/count
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetRead, DatasetClass),
)
@Get("/count")
Expand Down Expand Up @@ -1001,7 +1001,7 @@ export class DatasetsController {
// GET /datasets/:id
//@UseGuards(PoliciesGuard)
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetRead, DatasetClass),
)
@Get("/:pid")
Expand Down Expand Up @@ -1032,7 +1032,7 @@ export class DatasetsController {
// PATCH /datasets/:id
// body: modified fields
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetUpdate, DatasetClass),
)
@UseInterceptors(
Expand Down Expand Up @@ -1098,7 +1098,7 @@ export class DatasetsController {

// instantiate the casl matrix for the user
const user: JWTUser = request.user as JWTUser;
const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
// check if he/she can create this dataset
const canUpdate =
ability.can(Action.DatasetUpdateAny, DatasetClass) ||
Expand All @@ -1113,7 +1113,7 @@ export class DatasetsController {

// PUT /datasets/:id
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetUpdate, DatasetClass),
)
@UseInterceptors(
Expand Down Expand Up @@ -1177,7 +1177,7 @@ export class DatasetsController {

// instantiate the casl matrix for the user
const user: JWTUser = request.user as JWTUser;
const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
// check if he/she can create this dataset
const canUpdate =
ability.can(Action.DatasetUpdateAny, DatasetClass) ||
Expand All @@ -1195,7 +1195,7 @@ export class DatasetsController {

// DELETE /datasets/:id
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetDelete, DatasetClass),
)
@Delete("/:pid")
Expand Down Expand Up @@ -1227,7 +1227,7 @@ export class DatasetsController {

// instantiate the casl matrix for the user
const user: JWTUser = request.user as JWTUser;
const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
// check if he/she can create this dataset
const canUpdate =
ability.can(Action.DatasetDeleteAny, DatasetClass) ||
Expand All @@ -1241,7 +1241,7 @@ export class DatasetsController {
}

@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetUpdate, DatasetClass),
)
@Post("/:pid/appendToArrayField")
Expand Down Expand Up @@ -1278,7 +1278,7 @@ export class DatasetsController {
@Query("data") data: string,
): Promise<DatasetClass | null> {
const user: JWTUser = request.user as JWTUser;
const ability = this.caslAbilityFactory.createForUser(user);
const ability = this.caslAbilityFactory.datasetInstanceAccess(user);
const datasetToUpdate = await this.datasetsService.findOne({
where: { pid: pid },
});
Expand Down Expand Up @@ -1312,7 +1312,7 @@ export class DatasetsController {

// GET /datasets/:id/thumbnail
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetRead, DatasetClass),
)
// @UseGuards(PoliciesGuard)
Expand Down Expand Up @@ -1356,7 +1356,7 @@ export class DatasetsController {

// POST /datasets/:id/attachments
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetAttachmentCreate, DatasetClass),
)
@HttpCode(HttpStatus.CREATED)
Expand Down Expand Up @@ -1406,7 +1406,7 @@ export class DatasetsController {

// GET /datasets/:id/attachments
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetAttachmentRead, DatasetClass),
)
@Get("/:pid/attachments")
Expand Down Expand Up @@ -1443,7 +1443,7 @@ export class DatasetsController {

// PATCH /datasets/:id/attachments/:fk
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetAttachmentUpdate, DatasetClass),
)
@Put("/:pid/attachments/:aid")
Expand Down Expand Up @@ -1490,7 +1490,7 @@ export class DatasetsController {

// DELETE /datasets/:pid/attachments/:aid
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetAttachmentDelete, DatasetClass),
)
@Delete("/:pid/attachments/:aid")
Expand Down Expand Up @@ -1534,7 +1534,7 @@ export class DatasetsController {

// POST /datasets/:id/origdatablocks
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) => {
@CheckPolicies("datasets", (ability: AppAbility) => {
return ability.can(Action.DatasetOrigdatablockCreate, DatasetClass);
})
@UseInterceptors(
Expand Down Expand Up @@ -1600,7 +1600,7 @@ export class DatasetsController {

// POST /datasets/:id/origdatablocks/isValid
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) => {
@CheckPolicies("datasets", (ability: AppAbility) => {
return ability.can(Action.DatasetOrigdatablockCreate, DatasetClass);
})
@HttpCode(HttpStatus.OK)
Expand Down Expand Up @@ -1649,7 +1649,7 @@ export class DatasetsController {

// GET /datasets/:id/origdatablocks
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) => {
@CheckPolicies("datasets", (ability: AppAbility) => {
return ability.can(Action.DatasetOrigdatablockRead, DatasetClass);
})
@Get("/:pid/origdatablocks")
Expand Down Expand Up @@ -1686,7 +1686,7 @@ export class DatasetsController {

// PATCH /datasets/:id/origdatablocks/:fk
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) => {
@CheckPolicies("datasets", (ability: AppAbility) => {
return ability.can(Action.DatasetOrigdatablockUpdate, DatasetClass);
})
@UseInterceptors(
Expand Down Expand Up @@ -1757,7 +1757,7 @@ export class DatasetsController {

// DELETE /datasets/:id/origdatablocks/:fk
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetOrigdatablockDelete, DatasetClass),
)
@Delete("/:pid/origdatablocks/:oid")
Expand Down Expand Up @@ -1819,7 +1819,7 @@ export class DatasetsController {

// POST /datasets/:id/datablocks
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetDatablockCreate, DatasetClass),
)
@UseInterceptors(
Expand Down Expand Up @@ -1880,7 +1880,7 @@ export class DatasetsController {

// GET /datasets/:id/datablocks
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetDatablockRead, DatasetClass),
)
@Get("/:pid/datablocks")
Expand Down Expand Up @@ -1917,7 +1917,7 @@ export class DatasetsController {

// PATCH /datasets/:id/datablocks/:fk
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetDatablockUpdate, DatasetClass),
)
@UseInterceptors(
Expand Down Expand Up @@ -1987,7 +1987,7 @@ export class DatasetsController {

// DELETE /datasets/:id/datablocks/:fk
@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetDatablockDelete, DatasetClass),
)
@Delete("/:pid/datablocks/:did")
Expand Down Expand Up @@ -2056,7 +2056,7 @@ export class DatasetsController {
}

@UseGuards(PoliciesGuard)
@CheckPolicies((ability: AppAbility) =>
@CheckPolicies("datasets", (ability: AppAbility) =>
ability.can(Action.DatasetLogbookRead, DatasetClass),
)
@Get("/:pid/logbook")
Expand Down
Loading

0 comments on commit 3e4dc8b

Please sign in to comment.