From 0dc8e76de7fdcd8e243d76b18a694a8865dd1f77 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Minelli?= <michael@minelli.me>
Date: Wed, 28 Jun 2023 21:55:08 +0200
Subject: [PATCH] Add Enonce routes

---
 ExpressAPI/src/routes/ApiRoutesManager.ts |  2 +
 ExpressAPI/src/routes/EnonceRoutes.ts     | 87 +++++++++++++++++++++++
 2 files changed, 89 insertions(+)
 create mode 100644 ExpressAPI/src/routes/EnonceRoutes.ts

diff --git a/ExpressAPI/src/routes/ApiRoutesManager.ts b/ExpressAPI/src/routes/ApiRoutesManager.ts
index 64f4fdf..24bf091 100644
--- a/ExpressAPI/src/routes/ApiRoutesManager.ts
+++ b/ExpressAPI/src/routes/ApiRoutesManager.ts
@@ -2,6 +2,7 @@ import { Express }   from 'express-serve-static-core';
 import RoutesManager from '../express/RoutesManager';
 import BaseRoutes    from './BaseRoutes';
 import SessionRoutes from './SessionRoutes';
+import EnonceRoutes  from './EnonceRoutes';
 
 
 class AdminRoutesManager implements RoutesManager {
@@ -20,6 +21,7 @@ class AdminRoutesManager implements RoutesManager {
     registerOnBackend(backend: Express) {
         BaseRoutes.registerOnBackend(backend);
         SessionRoutes.registerOnBackend(backend);
+        EnonceRoutes.registerOnBackend(backend);
     }
 }
 
diff --git a/ExpressAPI/src/routes/EnonceRoutes.ts b/ExpressAPI/src/routes/EnonceRoutes.ts
new file mode 100644
index 0000000..0df2c54
--- /dev/null
+++ b/ExpressAPI/src/routes/EnonceRoutes.ts
@@ -0,0 +1,87 @@
+import { Express }               from 'express-serve-static-core';
+import express                   from 'express';
+import * as ExpressValidator     from 'express-validator';
+import { StatusCodes }           from 'http-status-codes';
+import RoutesManager             from '../express/RoutesManager';
+import ParamsValidatorMiddleware from '../middlewares/ParamsValidatorMiddleware';
+import ApiRequest                from '../models/ApiRequest';
+import SecurityMiddleware        from '../middlewares/SecurityMiddleware';
+import SecurityCheckType         from '../types/SecurityCheckType';
+import GitlabUser                from '../shared/types/Gitlab/GitlabUser';
+import GitlabHelper              from '../helpers/GitlabHelper';
+import Config                    from '../config/Config';
+import GitlabMember              from '../shared/types/Gitlab/GitlabMember';
+import GitlabAccessLevel         from '../shared/types/Gitlab/GitlabAccessLevel';
+import GitlabRepository          from '../shared/types/Gitlab/GitlabRepository';
+import UserManager               from '../managers/UserManager';
+import User                      from '../models/User';
+import Enonce                    from '../models/Enonce';
+import EnonceStaff               from '../models/EnonceStaff';
+
+
+class EnonceRoutes implements RoutesManager {
+    private static _instance: EnonceRoutes;
+
+    private constructor() { }
+
+    public static get instance(): EnonceRoutes {
+        if ( !EnonceRoutes._instance ) {
+            EnonceRoutes._instance = new EnonceRoutes();
+        }
+
+        return EnonceRoutes._instance;
+    }
+
+    private readonly enonceValidator: ExpressValidator.Schema = {
+        name   : {
+            trim    : true,
+            notEmpty: true
+        },
+        members: {
+            trim    : true,
+            notEmpty: true
+        }
+    };
+
+    registerOnBackend(backend: Express) {
+        backend.post('/enonces', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.enonceValidator), this.createEnonce);
+    }
+
+    private async createEnonce(req: ApiRequest, res: express.Response) {
+        const params: { name: string, members: string } = req.body;
+        const gitlabMembers: Array<GitlabUser> = JSON.parse(params.members) as Array<GitlabUser>;
+
+        const repository: GitlabRepository = await GitlabHelper.createRepository(params.name, Config.enonce.default.description.replace('{{ENONCE_NAME}}', params.name), Config.enonce.default.visibility, Config.enonce.default.initReadme, Config.gitlab.group.enonces, Config.enonce.default.sharedRunnersEnabled, Config.enonce.default.wikiEnabled, Config.enonce.default.template);
+        const members: Array<GitlabMember | false> = await Promise.all([ req.session.profile.userGitlabId, ...gitlabMembers.map(member => member.id) ].map(async (memberId: number): Promise<GitlabMember | false> => {
+            try {
+                return await GitlabHelper.addRepositoryMember(repository.id, memberId, GitlabAccessLevel.Maintainer);
+            } catch ( e ) {
+                return false;
+            }
+        }));
+
+        const enonce: Enonce = Enonce.createFromSql({
+                                                        enonceName              : repository.name,
+                                                        enonceGitlabId          : repository.id,
+                                                        enonceGitlabLink        : repository.web_url,
+                                                        enonceGitlabCreationInfo: JSON.stringify(repository),
+                                                        enonceGitlabLastInfo    : JSON.stringify(repository),
+                                                        enonceGitlabLastInfoTs  : new Date().getTime()
+                                                    });
+        await enonce.create();
+
+        let dojoUsers: Array<User> = [ req.session.profile, ...(await UserManager.getByGitlabIds(gitlabMembers.map(member => member.id))).filter(user => user) ]; // TODO: Remplacer le filter par une map qui créer l'utilisateur inconnu. 
+        dojoUsers = dojoUsers.reduce((unique, user) => (unique.findIndex(uniqueUser => uniqueUser.userID === user.userID) !== -1 ? unique : [ ...unique, user ]), Array<User>());
+        await Promise.all(dojoUsers.map(async (dojoUser: User) => {
+            return EnonceStaff.createFromSql({
+                                                 enonceID: enonce.enonceID,
+                                                 userID  : dojoUser.userID
+                                             });
+        }));
+
+        req.session.sendResponse(res, StatusCodes.OK, enonce);
+    }
+}
+
+
+export default EnonceRoutes.instance;
-- 
GitLab