Skip to content

Commit

Permalink
Only get roles for current initiative
Browse files Browse the repository at this point in the history
  • Loading branch information
kyle1morel committed Jul 22, 2024
1 parent b34d2a4 commit 136deed
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 5 deletions.
6 changes: 4 additions & 2 deletions app/src/middleware/authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Problem from 'api-problem';
import { userService, yarsService } from '../services';

import type { NextFunction, Request, Response } from '../interfaces/IExpress';
import { Scope } from '../utils/enums/application';
import { Initiative, Scope } from '../utils/enums/application';
import { getCurrentIdentity } from '../utils/utils';
import { NIL } from 'uuid';

Expand Down Expand Up @@ -33,7 +33,9 @@ export const hasPermission = (resource: string, action: string) => {
const roles = await yarsService.getIdentityRoles((req.currentUser?.tokenPayload as any).preferred_username);

const permissions = await Promise.all(
roles.map((x) => yarsService.getRolePermissionDetails(x.roleId, resource, action))
roles.map((x) =>
yarsService.getRolePermissionDetails(x.roleId, req.currentUser?.initiative as Initiative, resource, action)
)
).then((x) => x.flat());

if (!permissions || permissions.length === 0) {
Expand Down
34 changes: 34 additions & 0 deletions app/src/middleware/initiative.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// @ts-expect-error api-problem lacks a defined interface; code still works fine
import Problem from 'api-problem';

import { Initiative } from '../utils/enums/application';

import type { NextFunction, Request, Response } from '../interfaces/IExpress';

/**
* @function setInitiative
* Injects the given initiative into the currentUser
* @param {string} initiative An initiative code
* @returns {function} Express middleware function
* @throws The error encountered upon failure
*/
export const setInitiative = (initiative: Initiative) => {
return async (req: Request, res: Response, next: NextFunction) => {
try {
if (req.currentUser) {
req.currentUser.initiative = initiative;
} else {
throw new Problem(403, {
detail: 'Unable to determine initiative',
instance: req.originalUrl
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
return next(new Problem(403, { detail: err.message, instance: req.originalUrl }));
}

// Continue middleware
next();
};
};
3 changes: 3 additions & 0 deletions app/src/routes/v1/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import express from 'express';

import { currentUser } from '../../middleware/authentication';
import { setInitiative } from '../../middleware/initiative';

import document from './document';
import enquiry from './enquiry';
Expand All @@ -10,9 +11,11 @@ import roadmap from './roadmap';
import sso from './sso';
import submission from './submission';
import user from './user';
import { Initiative } from '../../utils/enums/application';

const router = express.Router();
router.use(currentUser);
router.use(setInitiative(Initiative.HOUSING));

// Base v1 Responder
router.get('/', (_req, res) => {
Expand Down
1 change: 1 addition & 0 deletions app/src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { default as comsService } from './coms';
export { default as documentService } from './document';
export { default as emailService } from './email';
export { default as enquiryService } from './enquiry';
export { default as initiativeService } from './initiative';
export { default as noteService } from './note';
export { default as permitService } from './permit';
export { default as ssoService } from './sso';
Expand Down
22 changes: 22 additions & 0 deletions app/src/services/initiative.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import prisma from '../db/dataConnection';

import { Initiative } from '../utils/enums/application';

const service = {
/**
* @function getInitiative
* Create an activity for the given initiative with a unique identifier
* @param {string} initiative The initiative ID
* @returns {Promise<Activity | null>} The result of running the findFirst operation
*/
getInitiative: async (initiative: Initiative) => {
const result = await prisma.initiative.findFirstOrThrow({
where: {
code: initiative
}
});
return { initiativeId: result.initiative_id, code: result.code, label: result.label };
}
};

export default service;
9 changes: 8 additions & 1 deletion app/src/services/yars.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable no-useless-catch */

import prisma from '../db/dataConnection';
import { Initiative } from '../utils/enums/application';

const service = {
/**
Expand All @@ -23,11 +24,17 @@ const service = {
}
},

getRolePermissionDetails: async (roleId: number, resourceName: string, actionName: string) => {
getRolePermissionDetails: async (
roleId: number,
initiativeName: Initiative,
resourceName: string,
actionName: string
) => {
try {
const result = await prisma.role_permission_vw.findMany({
where: {
role_id: roleId,
initiative_name: initiativeName.toLowerCase(),
resource_name: resourceName,
action_name: actionName
}
Expand Down
5 changes: 3 additions & 2 deletions app/src/types/CurrentUser.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import jwt from 'jsonwebtoken';

import { ApiScope } from './ApiScope';
import { AuthType } from '../utils/enums/application';
import { AuthType, Initiative } from '../utils/enums/application';

export type CurrentUser = {
authType: AuthType;
apiScope: ApiScope;
apiScope?: ApiScope;
initiative?: Initiative;
tokenPayload: string | jwt.JwtPayload | null;
};

0 comments on commit 136deed

Please sign in to comment.