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