From e907ab8cc09e5c98c1ed5f0a862fe08c8fd70327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <michael@minelli.me> Date: Mon, 31 Jul 2023 23:45:07 +0200 Subject: [PATCH] Add Exercice authentification by secret --- ExpressAPI/src/controllers/Session.ts | 26 ++++++++++--------- ExpressAPI/src/managers/ExerciceManager.ts | 18 +++++++++++++ .../src/middlewares/ParamsCallbackManager.ts | 10 ++++++- .../src/middlewares/SecurityMiddleware.ts | 10 ++++--- ExpressAPI/src/types/ApiRequest.ts | 8 +++--- ExpressAPI/src/types/SecurityCheckType.ts | 1 + 6 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 ExpressAPI/src/managers/ExerciceManager.ts diff --git a/ExpressAPI/src/controllers/Session.ts b/ExpressAPI/src/controllers/Session.ts index 3abcc18..b8f9f18 100644 --- a/ExpressAPI/src/controllers/Session.ts +++ b/ExpressAPI/src/controllers/Session.ts @@ -5,7 +5,7 @@ import Config from '../config/Config'; import express from 'express'; import ApiRequest from '../types/ApiRequest'; import UserManager from '../managers/UserManager'; -import DojoResponse from '../shared/types/DojoResponse'; +import DojoResponse from '../shared/types/Dojo/DojoResponse'; import { User } from '../types/DatabaseTypes'; @@ -26,21 +26,23 @@ class Session { async initSession(req: ApiRequest) { const authorization = req.headers.authorization; if ( authorization ) { - const jwtToken = authorization.replace('Bearer ', ''); - - try { - const jwtData = jwt.verify(jwtToken, Config.jwtConfig.secret) as JwtPayload; - - if ( jwtData.profile ) { - this.profile = jwtData.profile; - this.profile = await UserManager.getById(this.profile.id); - } - } catch ( err ) { } + if ( authorization.startsWith('Bearer ') ) { + const jwtToken = authorization.replace('Bearer ', ''); + + try { + const jwtData = jwt.verify(jwtToken, Config.jwtConfig.secret) as JwtPayload; + + if ( jwtData.profile ) { + this.profile = jwtData.profile; + this.profile = await UserManager.getById(this.profile.id); + } + } catch ( err ) { } + } } } private static getToken(profileJson: any): string { - return profileJson.id === null ? null : jwt.sign({ profile: profileJson }, Config.jwtConfig.secret, Config.jwtConfig.expiresIn > 0 ? { expiresIn: Config.jwtConfig.expiresIn } : {}); + return profileJson === null ? null : jwt.sign({ profile: profileJson }, Config.jwtConfig.secret, Config.jwtConfig.expiresIn > 0 ? { expiresIn: Config.jwtConfig.expiresIn } : {}); } private async getResponse<T>(code: number, data: T, descriptionOverride?: string): Promise<DojoResponse<T>> { diff --git a/ExpressAPI/src/managers/ExerciceManager.ts b/ExpressAPI/src/managers/ExerciceManager.ts new file mode 100644 index 0000000..489a6e6 --- /dev/null +++ b/ExpressAPI/src/managers/ExerciceManager.ts @@ -0,0 +1,18 @@ +import { Prisma } from '@prisma/client'; +import { Enonce } from '../types/DatabaseTypes'; +import db from '../helpers/DatabaseHelper'; + + +class ExerciceManager { + get(id: string, include: Prisma.ExerciceInclude | undefined = undefined): Promise<Enonce | undefined> { + return db.exercice.findUnique({ + where : { + id: id + }, + include: include + }); + } +} + + +export default new ExerciceManager(); diff --git a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts index c0ccb39..358da8a 100644 --- a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts +++ b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts @@ -3,6 +3,7 @@ import ApiRequest from '../types/ApiRequest'; import express from 'express'; import { StatusCodes } from 'http-status-codes'; import EnonceManager from '../managers/EnonceManager'; +import ExerciceManager from '../managers/ExerciceManager'; class ParamsCallbackManager { @@ -24,7 +25,8 @@ class ParamsCallbackManager { initBoundParams(req: ApiRequest) { if ( !req.boundParams ) { req.boundParams = { - enonce: null + enonce : null, + exercice: null }; } } @@ -34,6 +36,12 @@ class ParamsCallbackManager { exercices: true, staff : true } ], 'enonce'); + + this.listenParam('exerciceId', backend, ExerciceManager.get.bind(ExerciceManager), [ { + enonce : true, + members: true, + results: true + } ], 'exercice'); } } diff --git a/ExpressAPI/src/middlewares/SecurityMiddleware.ts b/ExpressAPI/src/middlewares/SecurityMiddleware.ts index 85a6056..97a2299 100644 --- a/ExpressAPI/src/middlewares/SecurityMiddleware.ts +++ b/ExpressAPI/src/middlewares/SecurityMiddleware.ts @@ -11,7 +11,7 @@ class SecurityMiddleware { check(checkIfConnected: boolean, ...checkTypes: Array<SecurityCheckType>): (req: ApiRequest, res: express.Response, next: express.NextFunction) => void { return async (req: ApiRequest, res: express.Response, next: express.NextFunction) => { if ( checkIfConnected ) { - if ( req.session.profile.id === null ) { + if ( req.session.profile === null ) { return req.session.sendResponse(res, StatusCodes.UNAUTHORIZED); } } @@ -19,9 +19,9 @@ class SecurityMiddleware { let isAllowed = checkTypes.length === 0; if ( !isAllowed ) { - for ( let checkType of checkTypes ) { + for ( const checkType of checkTypes ) { try { - switch ( checkType ) { + switch ( String(checkType) ) { case SecurityCheckType.TEACHING_STAFF: isAllowed = isAllowed || req.session.profile.isTeachingStaff; break; @@ -31,8 +31,10 @@ class SecurityMiddleware { case SecurityCheckType.ENONCE_IS_PUBLISHED: isAllowed = isAllowed || req.boundParams.enonce.published; break; + case SecurityCheckType.EXERCICE_SECRET: + isAllowed = isAllowed || (req.headers.authorization && req.headers.authorization && req.headers.authorization.replace('ExerciceSecret ', '') === req.boundParams.exercice.secret); + break; default: - isAllowed = isAllowed || false; break; } } catch ( e ) { diff --git a/ExpressAPI/src/types/ApiRequest.ts b/ExpressAPI/src/types/ApiRequest.ts index 6d1549c..9a6c06d 100644 --- a/ExpressAPI/src/types/ApiRequest.ts +++ b/ExpressAPI/src/types/ApiRequest.ts @@ -1,11 +1,11 @@ -import express from 'express'; -import Session from '../controllers/Session'; -import { Enonce } from './DatabaseTypes'; +import express from 'express'; +import Session from '../controllers/Session'; +import { Enonce, Exercice } from './DatabaseTypes'; type ApiRequest = express.Request & { session: Session, boundParams: { - enonce: Enonce + enonce: Enonce, exercice: Exercice } } diff --git a/ExpressAPI/src/types/SecurityCheckType.ts b/ExpressAPI/src/types/SecurityCheckType.ts index fcb3a6d..b063ff9 100644 --- a/ExpressAPI/src/types/SecurityCheckType.ts +++ b/ExpressAPI/src/types/SecurityCheckType.ts @@ -2,6 +2,7 @@ enum SecurityCheckType { TEACHING_STAFF = 'teachingStaff', ENONCE_STAFF = 'enonceStaff', ENONCE_IS_PUBLISHED = 'enonceIsPublished', + EXERCICE_SECRET = 'exerciceSecret', } -- GitLab