From 9a1088da2c6aa10c90fd0fc764e95695738aaf31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <michael@minelli.me> Date: Thu, 23 Nov 2023 20:27:29 +0100 Subject: [PATCH] General => Adapt code for OpenAPI v3 specs --- ExpressAPI/src/express/API.ts | 14 ++++++++++++-- ...leware.ts => ClientVersionCheckerMiddleware.ts} | 4 ++-- .../src/middlewares/ParamsCallbackManager.ts | 2 +- ExpressAPI/src/middlewares/SecurityMiddleware.ts | 2 +- ExpressAPI/src/middlewares/SessionMiddleware.ts | 11 ++++++----- ExpressAPI/src/routes/AssignmentRoutes.ts | 12 ++++++++++-- ExpressAPI/src/routes/BaseRoutes.ts | 12 ++++++++++-- ExpressAPI/src/routes/SessionRoutes.ts | 6 +++++- 8 files changed, 47 insertions(+), 16 deletions(-) rename ExpressAPI/src/middlewares/{ClientVersionMiddleware.ts => ClientVersionCheckerMiddleware.ts} (94%) diff --git a/ExpressAPI/src/express/API.ts b/ExpressAPI/src/express/API.ts index 55d2fe4..de0be93 100644 --- a/ExpressAPI/src/express/API.ts +++ b/ExpressAPI/src/express/API.ts @@ -13,7 +13,7 @@ import logger from '../shared/logging/WinstonLogger'; import ParamsCallbackManager from '../middlewares/ParamsCallbackManager'; import ApiRoutesManager from '../routes/ApiRoutesManager'; import compression from 'compression'; -import ClientVersionMiddleware from '../middlewares/ClientVersionMiddleware'; +import ClientVersionCheckerMiddleware from '../middlewares/ClientVersionCheckerMiddleware'; class API implements WorkerTask { @@ -23,6 +23,16 @@ class API implements WorkerTask { constructor() { this.backend = express(); + this.initBaseMiddlewares(); + + this.backend.use(ClientVersionCheckerMiddleware.register()); + + ParamsCallbackManager.registerOnBackend(this.backend); + SessionMiddleware.registerOnBackend(this.backend); + ApiRoutesManager.registerOnBackend(this.backend); + } + + private initBaseMiddlewares() { this.backend.use(multer({ limits: { fieldSize: 100 * 1024 * 1024 } }).none()); //Used for extract params from body with format "form-data", The none is for say that we do not wait a file in params @@ -30,7 +40,7 @@ class API implements WorkerTask { this.backend.use(helmet()); //Help to secure express, https://helmetjs.github.io/ this.backend.use(cors()); //Allow CORS requests this.backend.use(compression()); //Compress responses - + } this.backend.use(ClientVersionMiddleware.register()); ParamsCallbackManager.register(this.backend); diff --git a/ExpressAPI/src/middlewares/ClientVersionMiddleware.ts b/ExpressAPI/src/middlewares/ClientVersionCheckerMiddleware.ts similarity index 94% rename from ExpressAPI/src/middlewares/ClientVersionMiddleware.ts rename to ExpressAPI/src/middlewares/ClientVersionCheckerMiddleware.ts index f4bed40..1503abd 100644 --- a/ExpressAPI/src/middlewares/ClientVersionMiddleware.ts +++ b/ExpressAPI/src/middlewares/ClientVersionCheckerMiddleware.ts @@ -6,7 +6,7 @@ import { HttpStatusCode } from 'axios'; import DojoStatusCode from '../shared/types/Dojo/DojoStatusCode'; -class ClientVersionMiddleware { +class ClientVersionCheckerMiddleware { register(): (req: express.Request, res: express.Response, next: express.NextFunction) => void { return async (req: express.Request, res: express.Response, next: express.NextFunction) => { if ( req.headers['client'] && req.headers['client-version'] ) { @@ -32,4 +32,4 @@ class ClientVersionMiddleware { } -export default new ClientVersionMiddleware(); \ No newline at end of file +export default new ClientVersionCheckerMiddleware(); \ No newline at end of file diff --git a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts index 9af8f19..cfcb275 100644 --- a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts +++ b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts @@ -33,7 +33,7 @@ class ParamsCallbackManager { } } - register(backend: Express) { + registerOnBackend(backend: Express) { this.listenParam('assignmentNameOrUrl', backend, (AssignmentManager.get as GetFunction).bind(AssignmentManager), [ { exercises: true, staff : true diff --git a/ExpressAPI/src/middlewares/SecurityMiddleware.ts b/ExpressAPI/src/middlewares/SecurityMiddleware.ts index cc7e067..ec5f388 100644 --- a/ExpressAPI/src/middlewares/SecurityMiddleware.ts +++ b/ExpressAPI/src/middlewares/SecurityMiddleware.ts @@ -31,7 +31,7 @@ class SecurityMiddleware { isAllowed = isAllowed || (req.boundParams.assignment?.published ?? false); break; case SecurityCheckType.EXERCISE_SECRET: - isAllowed = isAllowed || req.headers.authorization?.replace('ExerciseSecret ', '') === req.boundParams.exercise!.secret; + isAllowed = isAllowed || (req.headers.ExerciseSecret as string | undefined) === req.boundParams.exercise!.secret; break; default: break; diff --git a/ExpressAPI/src/middlewares/SessionMiddleware.ts b/ExpressAPI/src/middlewares/SessionMiddleware.ts index 8f87f7d..bf237bf 100644 --- a/ExpressAPI/src/middlewares/SessionMiddleware.ts +++ b/ExpressAPI/src/middlewares/SessionMiddleware.ts @@ -1,15 +1,16 @@ -import express from 'express'; -import Session from '../controllers/Session'; +import express from 'express'; +import Session from '../controllers/Session'; +import { Express } from 'express-serve-static-core'; class SessionMiddleware { - register(): (req: express.Request, res: express.Response, next: express.NextFunction) => void { - return async (req: express.Request, res: express.Response, next: express.NextFunction) => { + registerOnBackend(backend: Express) { + backend.use(async (req: express.Request, res: express.Response, next: express.NextFunction) => { req.session = new Session(); await req.session.initSession(req, res); return next(); - }; + }); } } diff --git a/ExpressAPI/src/routes/AssignmentRoutes.ts b/ExpressAPI/src/routes/AssignmentRoutes.ts index 025dc33..605bbc4 100644 --- a/ExpressAPI/src/routes/AssignmentRoutes.ts +++ b/ExpressAPI/src/routes/AssignmentRoutes.ts @@ -49,8 +49,8 @@ class AssignmentRoutes implements RoutesManager { backend.get('/assignments/:assignmentNameOrUrl', SecurityMiddleware.check(true), this.getAssignment); backend.post('/assignments', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.assignmentValidator), this.createAssignment); - backend.patch('/assignments/:assignmentNameOrUrl/publish', SecurityMiddleware.check(true, SecurityCheckType.ASSIGNMENT_STAFF), this.changeAssignmentPublishedStatus(true)); - backend.patch('/assignments/:assignmentNameOrUrl/unpublish', SecurityMiddleware.check(true, SecurityCheckType.ASSIGNMENT_STAFF), this.changeAssignmentPublishedStatus(false)); + backend.patch('/assignments/:assignmentNameOrUrl/publish', SecurityMiddleware.check(true, SecurityCheckType.ASSIGNMENT_STAFF), this.publishAssignment); + backend.patch('/assignments/:assignmentNameOrUrl/unpublish', SecurityMiddleware.check(true, SecurityCheckType.ASSIGNMENT_STAFF), this.unpublishAssignment); } // Get an assignment by its name or gitlab url @@ -167,6 +167,14 @@ class AssignmentRoutes implements RoutesManager { } } + private async publishAssignment(req: express.Request, res: express.Response) { + return this.changeAssignmentPublishedStatus(true)(req, res); + } + + private async unpublishAssignment(req: express.Request, res: express.Response) { + return this.changeAssignmentPublishedStatus(false)(req, res); + } + private changeAssignmentPublishedStatus(publish: boolean): (req: express.Request, res: express.Response) => Promise<void> { return async (req: express.Request, res: express.Response): Promise<void> => { if ( publish ) { diff --git a/ExpressAPI/src/routes/BaseRoutes.ts b/ExpressAPI/src/routes/BaseRoutes.ts index 0ef1eb0..c0ac80a 100644 --- a/ExpressAPI/src/routes/BaseRoutes.ts +++ b/ExpressAPI/src/routes/BaseRoutes.ts @@ -6,8 +6,16 @@ import RoutesManager from '../express/RoutesManager'; class BaseRoutes implements RoutesManager { registerOnBackend(backend: Express) { - backend.get('/', (req: express.Request, res: express.Response) => { res.status(StatusCodes.OK).end(); }); - backend.get('/health_check', (req: express.Request, res: express.Response) => { res.status(StatusCodes.OK).end(); }); + backend.get('/', this.homepage); + backend.get('/health_check', this.healthCheck); + } + + private async homepage(req: express.Request, res: express.Response) { + return req.session.sendResponse(res, StatusCodes.OK); + } + + private async healthCheck(req: express.Request, res: express.Response) { + return req.session.sendResponse(res, StatusCodes.OK); } } diff --git a/ExpressAPI/src/routes/SessionRoutes.ts b/ExpressAPI/src/routes/SessionRoutes.ts index 29ebdfb..a5bd42f 100644 --- a/ExpressAPI/src/routes/SessionRoutes.ts +++ b/ExpressAPI/src/routes/SessionRoutes.ts @@ -34,7 +34,7 @@ class SessionRoutes implements RoutesManager { registerOnBackend(backend: Express) { backend.post('/login', ParamsValidatorMiddleware.validate(this.loginValidator), this.login); backend.post('/refresh_tokens', ParamsValidatorMiddleware.validate(this.refreshTokensValidator), this.refreshTokens); - backend.get('/test_session', SecurityMiddleware.check(true), (req: express.Request, res: express.Response) => req.session.sendResponse(res, StatusCodes.OK)); + backend.get('/test_session', SecurityMiddleware.check(true), this.testSession); } private async login(req: express.Request, res: express.Response) { @@ -71,6 +71,10 @@ class SessionRoutes implements RoutesManager { req.session.sendResponse(res, StatusCodes.INTERNAL_SERVER_ERROR, {}, 'Unknown error while refresh tokens', DojoStatusCode.REFRESH_TOKENS_FAILED); } } + + private async testSession(req: express.Request, res: express.Response) { + req.session.sendResponse(res, StatusCodes.OK); + } } -- GitLab