Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task #215826 Task #215928 Addition of AclGuard permissions to the modules #938

Open
wants to merge 17 commits into
base: feat-acl
Choose a base branch
from
Open
242 changes: 238 additions & 4 deletions src/src/common/helpers/acl.helper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Inject, Injectable } from '@nestjs/common';
import { Cache } from 'cache-manager';
import * as fs from 'fs';
import { UserService } from 'src/user/user.service';
import { HasuraService as HasuraServiceFromServices } from '../../services/hasura/hasura.service';

Expand All @@ -23,7 +22,10 @@ export class AclHelper {

if (cachedRoleToActionMapping) {
roleActions = cachedRoleToActionMapping;
console.log('### Using Cache for roleActions: ' + JSON.stringify(roleActions));
console.log(
'### Using Cache for roleActions: ' +
JSON.stringify(roleActions),
);
Comment on lines +25 to +28
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace console.log with a more robust logging mechanism.

- console.log(...)
+ // Consider replacing console.log with a more robust logging mechanism

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
console.log(
'### Using Cache for roleActions: ' +
JSON.stringify(roleActions),
);
// Consider replacing console.log with a more robust logging mechanism
console.log(
'### Using Cache for roleActions: ' +
JSON.stringify(roleActions),
);

} else {
// Get roles, actions from DB
let query = {
Expand Down Expand Up @@ -237,7 +239,6 @@ export class AclHelper {
// @TODO - update code above
return true;
}

private async doIHaveCampAccess(req: any, camp_id: number) {
const user_roles = req.mw_roles;

Expand Down Expand Up @@ -295,7 +296,216 @@ export class AclHelper {
return false;
}
}
private async doIHaveKitMaterialAccess(req, camp_id) {
const user_roles = req.mw_roles;
let gqlQuery;
if (user_roles.includes('program_owners')) {
return true;
}
if (user_roles.includes('facilitator')) {
gqlQuery = {
query: `query MyQuery {
kit_materials_checklist_aggregate(where: {camp_id: {_eq: ${camp_id}}, user_id: {_eq: ${req.mw_userid}}}) {
aggregate {
count
}
}
}
`,
};
console.log(gqlQuery.query);

const result = await this.hasuraServiceFromService.getData(
gqlQuery,
);
if (
result?.data &&
result.data.kit_materials_checklist_aggregate.aggregate.count >
0
) {
return true;
} else {
return false;
}
}
}
private async doIHaveReferenceAccess(req: any, entity_id: any) {
const user_roles = req.mw_roles;
let gqlquery;
if (user_roles.includes('program_owner')) {
return true;
}
if (
user_roles.includes('facilitator') ||
user_roles.includes('staff')
) {
gqlquery = {
query: `query MyQuery {
references_aggregate(where: {context_id: {_eq: ${req.mw_userid}}, id: {_eq: ${entity_id}}}) {
aggregate {
count
}
}
}
`,
};
console.log(gqlquery.query);

const result = await this.hasuraServiceFromService.getData(
gqlquery,
);
if (
result?.data &&
result.data.references_aggregate.aggregate.count > 0
) {
return true;
} else {
return false;
}
}
}

private async doIHavePcrScoreAccess(request, entity, entity_id) {
const user_roles = request.mw_roles;
let gqlQuery;
if (user_roles.includes('program_owner')) {
return true;
}
let filterQuery;
if (entity.hasOwnProperty('user_id')) {
filterQuery = `user_id: {_eq: ${entity_id}},`;
} else if (entity.hasOwnProperty('id')) {
filterQuery = `id: {_eq: ${entity_id}},`;
} else {
filterQuery = ``;
}

if (user_roles.includes('facilitator')) {
gqlQuery = {
query: `query MyQuery {
pcr_scores_aggregate(where: {${filterQuery} updated_by: {_eq: ${request.mw_userid}}}) {
aggregate {
count
}
}
}
`,
};
console.log(gqlQuery.query);

const result = await this.hasuraServiceFromService.getData(
gqlQuery,
);
if (
result?.data &&
result.data.kit_materials_checklist_aggregate.aggregate.count >
0
) {
return true;
} else {
return false;
}
}
}

private async doIHaveSessionAccess(request, entity_id) {
const user_roles = request.mw_roles;
let gqlquery;
if (user_roles.includes('program_owner')) {
return true;
}
console.log(request.params);

if (user_roles.includes('facilitator')) {
gqlquery = {
query: `query MyQuery {
learning_sessions_tracker_aggregate(where: {updated_by: {_eq: ${request.mw_userid}}, id: {_eq: ${entity_id}}}) {
aggregate {
count
}
}
}
`,
};
}
console.log(gqlquery.query);

const result = await this.hasuraServiceFromService.getData(gqlquery);
if (
result?.data &&
result.data.learning_sessions_tracker_aggregate.aggregate.count > 0
) {
return true;
} else {
return false;
}
}

private async doIHaveUploadFileAccess(request, entity_id) {
const user_roles = request.mw_roles;
let gqlquery;

if (user_roles.includes('program_owner')) {
return true;
}
if (
user_roles.includes('staff') ||
user_roles.includes('facilitator')
) {
gqlquery = {
query: `query MyQuery {
documents_aggregate(where: {user_id: {_eq: ${request.mw_userid}}, id: {_eq: ${entity_id}}}) {
aggregate {
count
}
}
}
`,
};
}
console.log(gqlquery.query);

const result = await this.hasuraServiceFromService.getData(gqlquery);
if (
result?.data &&
result.data.documents_aggregate.aggregate.count > 0
) {
return true;
} else {
return false;
}
}

private async doIHaveEditRequestAccess(request, entity_id) {
const user_roles = request.mw_roles;
let gqlquery;
if (user_roles.includes('program_owner')) {
return true;
}
if (user_roles.includes('staff')) {
gqlquery = {
query: `query MyQuery {
edit_requests_aggregate(where: {id: {_eq: ${entity_id}}, edit_req_approved_by: {_eq: ${request.mw_userid}}}) {
aggregate {
count
}
}
}
`,
};
}
console.log(gqlquery.query);

const result = await this.hasuraServiceFromService.getData(gqlquery);
if (
result?.data &&
result.data.edit_requests_aggregate.aggregate.count > 0
) {
return true;
} else {
return false;
}
}
public async doIHaveAccess(
request: any,
entity: string,
Expand All @@ -313,7 +523,31 @@ export class AclHelper {
case 'camp': {
return await this.doIHaveCampAccess(request, entity_id);
}
case 'kit-material': {
return await this.doIHaveKitMaterialAccess(request, entity_id);
}
case 'pcrscore': {
console.log(request.params);

return await this.doIHavePcrScoreAccess(
request,
request?.params,
entity_id,
);
}

case 'reference': {
return await this.doIHaveReferenceAccess(request, entity_id);
}
case 'session': {
return await this.doIHaveSessionAccess(request, entity_id);
}
case 'upload-file': {
return await this.doIHaveUploadFileAccess(request, entity_id);
}
case 'edit-request': {
return await this.doIHaveEditRequestAccess(request, entity_id);
}
default:
return false;
}
Expand Down Expand Up @@ -364,9 +598,9 @@ export class AclHelper {
if (!ownershipCheckRequired) {
return true;
}

if (entity_id) {
// 4 - Validate ownership

const iHaveAccess = await this.doIHaveAccess(
request,
entity,
Expand Down
42 changes: 39 additions & 3 deletions src/src/kit-materials/kit-materials.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,62 @@ import {
} from '@nestjs/common';
import { AuthGuard } from 'src/modules/auth/auth.guard';
import { KitMaterialsService } from './kit-materials.service';
import { AclGuard } from 'src/common/guards/acl.guard';
import { AclGuardData } from 'src/common/decorators/aclguarddata.decorator';
import { AclHelper } from 'src/common/helpers/acl.helper';

@Controller('kitmaterials')
@UseGuards(AuthGuard)
export class KitMaterialsController {
constructor(private readonly kitMaterialsService: KitMaterialsService) {}
constructor(
private readonly kitMaterialsService: KitMaterialsService,
private aclHelper: AclHelper,
) {}

@Post('/create')
@UseGuards(AuthGuard)
create(@Req() request: any, @Body() body: any, @Res() response: any) {
@UseGuards(AclGuard)
@AclGuardData('kit-material', ['create'])
async create(@Req() request: any, @Body() body: any, @Res() response: any) {
if (
!(await this.aclHelper.doIHaveAccess(
request,
'kit-material',
body.camp_id,
))
) {
return response.status(403).json({
success: false,
message: 'FORBIDDEN',
data: {},
});
manojLondhe marked this conversation as resolved.
Show resolved Hide resolved
}
return this.kitMaterialsService.create(body, request, response);
}

@Get('/list/:camp_id')
@UseGuards(AuthGuard)
list(
@UseGuards(AclGuard)
@AclGuardData('kit-material', ['read.own'])
async list(
@Req() request: any,
@Body() body: any,
@Res() response: any,
@Param('camp_id') camp_id: number,
) {
if (
!(await this.aclHelper.doIHaveAccess(
request,
'kit-material',
camp_id,
))
) {
return response.status(403).json({
success: false,
message: 'FORBIDDEN',
data: {},
});
}
Comment on lines +48 to +68
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the create method, the list method correctly uses AclGuard and AclGuardData. Again, consider abstracting repetitive access control checks.

return this.kitMaterialsService.List(body, request, response, camp_id);
}
}
6 changes: 4 additions & 2 deletions src/src/kit-materials/kit-materials.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import { KitMaterialsCoreService } from '../kit-materials/kit-materials.core.ser
import { HasuraModule as HasuraModuleFromServices } from '../services/hasura/hasura.module';
import { KitMaterialsController } from './kit-materials.controller';
import { KitMaterialsService } from './kit-materials.service';
import { AclHelper } from 'src/common/helpers/acl.helper';
import { UserModule } from 'src/user/user.module';

@Module({
imports: [HasuraModule, HasuraModuleFromServices],
imports: [HasuraModule, HasuraModuleFromServices, UserModule],
controllers: [KitMaterialsController],
providers: [KitMaterialsService, KitMaterialsCoreService],
providers: [KitMaterialsService, KitMaterialsCoreService, AclHelper],
exports: [KitMaterialsCoreService],
})
export class KitMaterialsModule {}
Loading