From 9c66346c5e7b10330a423ede1633ce4abdef7e27 Mon Sep 17 00:00:00 2001
From: "vincent.steinman" <vincent.steinmann@etu.hesge.ch>
Date: Thu, 8 Feb 2024 16:29:47 +0100
Subject: [PATCH] Most of the structure

---
 ExpressAPI/prisma/schema.prisma               |  5 +++
 .../src/middlewares/ParamsCallbackManager.ts  | 13 +++++-
 .../src/middlewares/SecurityMiddleware.ts     |  2 +
 ExpressAPI/src/routes/TagsRoutes.ts           | 42 +++++++++++++++++--
 ExpressAPI/src/types/DatabaseTypes.ts         | 14 +++----
 ExpressAPI/src/types/express/index.d.ts       |  4 +-
 6 files changed, 67 insertions(+), 13 deletions(-)

diff --git a/ExpressAPI/prisma/schema.prisma b/ExpressAPI/prisma/schema.prisma
index b5725fc..8d0ffc7 100644
--- a/ExpressAPI/prisma/schema.prisma
+++ b/ExpressAPI/prisma/schema.prisma
@@ -72,3 +72,8 @@ model Result {
 
     @@id([exerciseId, dateTime])
 }
+
+model Tag {
+    name  String   @id @db.Char(36)
+    type  Json     @db.Json
+}
\ No newline at end of file
diff --git a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
index a1836d1..e087c98 100644
--- a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
+++ b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
@@ -3,6 +3,7 @@ import express           from 'express';
 import { StatusCodes }   from 'http-status-codes';
 import ExerciseManager   from '../managers/ExerciseManager.js';
 import AssignmentManager from '../managers/AssignmentManager.js';
+import TagsManager from 'src/managers/TagsManager';
 
 
 type GetFunction = (id: string | number, ...args: Array<unknown>) => Promise<unknown>
@@ -28,7 +29,8 @@ class ParamsCallbackManager {
         if ( !req.boundParams ) {
             req.boundParams = {
                 assignment: undefined,
-                exercise  : undefined
+                exercise  : undefined,
+                tag       : undefined 
             };
         }
     }
@@ -44,6 +46,15 @@ class ParamsCallbackManager {
             members   : true,
             results   : true
         } ], 'exercise');
+        
+        //Patch? Delete? à la place de .get
+        this.listenParam('tagId', backend, (TagsManager.get as GetFunction).bind(TagsManager), [ {
+
+        } ], 'tag');
+
+        this.listenParam('tagProposalName', backend, (TagsManager.get as GetFunction).bind(TagsManager), [ {
+ 
+        } ], 'tag');
     }
 }
 
diff --git a/ExpressAPI/src/middlewares/SecurityMiddleware.ts b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
index 02c54c1..6edc8be 100644
--- a/ExpressAPI/src/middlewares/SecurityMiddleware.ts
+++ b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
@@ -13,6 +13,8 @@ class SecurityMiddleware {
     private async checkType(checkType: SecurityCheckType, req: express.Request): Promise<boolean> {
         try {
             switch ( String(checkType) ) {
+                case SecurityCheckType.ADMIN.valueOf():
+                    return req.session.profile.isAdmin;
                 case SecurityCheckType.TEACHING_STAFF.valueOf():
                     return req.session.profile.isTeachingStaff;
                 case SecurityCheckType.ASSIGNMENT_STAFF.valueOf():
diff --git a/ExpressAPI/src/routes/TagsRoutes.ts b/ExpressAPI/src/routes/TagsRoutes.ts
index b88229c..148d7c7 100644
--- a/ExpressAPI/src/routes/TagsRoutes.ts
+++ b/ExpressAPI/src/routes/TagsRoutes.ts
@@ -25,7 +25,7 @@ import path                           from 'path';
 import SharedAssignmentHelper         from '../shared/helpers/Dojo/SharedAssignmentHelper';
 import GlobalHelper                   from '../helpers/GlobalHelper';
 import DojoStatusCode                 from '../shared/types/Dojo/DojoStatusCode';
-import TagsManager from 'src/managers/TagsManager';
+import TagsManager                    from 'src/managers/TagsManager';
 
 
 class TagRoutes implements RoutesManager {
@@ -33,12 +33,16 @@ class TagRoutes implements RoutesManager {
         name: {
             trim: true,
             notEmpty: true
+        },
+        type: {
+            trim: true,
+            notEmpty: true
         }
     };
 
     registerOnBackend(backend: Express) {
         backend.post('/tags', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.tagsValidator), this.addTag.bind(this));
-        backend.delete('/tags/:tagid', SecurityMiddleware.check(true, SecurityCheckType.ADMIN), ParamsValidatorMiddleware.validate(this.tagsValidator), this.deleteTag.bind(this));
+        backend.delete('/tags/:tagId', SecurityMiddleware.check(true, SecurityCheckType.ADMIN), ParamsValidatorMiddleware.validate(this.tagsValidator), this.deleteTag.bind(this));
         backend.get('/tags/proposals', SecurityMiddleware.check(true, SecurityCheckType.ADMIN), ParamsValidatorMiddleware.validate(this.tagsValidator), this.getSubmittedTag.bind(this));
         backend.post('/tags/proposals', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.tagsValidator), this.SubmitTag.bind(this));
         backend.patch('/tags/proposals/:tagProposalName', SecurityMiddleware.check(true, SecurityCheckType.ADMIN), ParamsValidatorMiddleware.validate(this.tagsValidator), this.validateTag.bind(this));
@@ -51,7 +55,39 @@ class TagRoutes implements RoutesManager {
         
     }
     private async getSubmittedTag(req: express.Request, res: express.Response) {
-        
+        const repoTree: Array<GitlabTreeFile> = await GitlabManager.getRepositoryTree(req.boundParams.exercise!.assignment.gitlabId);
+
+        let assignmentHjsonFile!: GitlabFile;
+        const immutableFiles: Array<GitlabFile> = await Promise.all(Config.assignment.baseFiles.map(async (baseFile: string) => {
+            const file = await GitlabManager.getFile(req.boundParams.exercise!.assignment.gitlabId, baseFile);
+
+            if ( baseFile === Config.assignment.filename ) {
+                assignmentHjsonFile = file;
+            }
+
+            return file;
+        }));
+
+        const dojoAssignmentFile: AssignmentFile = JSON5.parse(atob(assignmentHjsonFile.content)) as AssignmentFile;
+
+        const immutablePaths = dojoAssignmentFile.immutable.map(fileDescriptor => fileDescriptor.path);
+
+        await Promise.all(repoTree.map(async gitlabTreeFile => {
+            if ( gitlabTreeFile.type == GitlabTreeFileType.BLOB ) {
+                for ( const immutablePath of immutablePaths ) {
+                    if ( gitlabTreeFile.path.startsWith(immutablePath) ) {
+                        immutableFiles.push(await GitlabManager.getFile(req.boundParams.exercise!.assignment.gitlabId, gitlabTreeFile.path));
+                        break;
+                    }
+                }
+            }
+        }));
+
+        return req.session.sendResponse(res, StatusCodes.OK, {
+            assignment    : (req.boundParams.exercise as Exercise).assignment,
+            assignmentFile: dojoAssignmentFile,
+            immutable     : immutableFiles
+        });
     }
     private async SubmitTag(req: express.Request, res: express.Response) {
         
diff --git a/ExpressAPI/src/types/DatabaseTypes.ts b/ExpressAPI/src/types/DatabaseTypes.ts
index 716f30b..eadad92 100644
--- a/ExpressAPI/src/types/DatabaseTypes.ts
+++ b/ExpressAPI/src/types/DatabaseTypes.ts
@@ -24,12 +24,12 @@ const resultBase = Prisma.validator<Prisma.ResultDefaultArgs>()({
                                                                         exercise: true
                                                                     }
                                                                 });
-// const tagsBase = Prisma.validator<Prisma.TagsDefaultArgs>()({
-//                                                                     include: {
-//                                                                         name: true,
-//                                                                         type: true,
-//                                                                     }
-//                                                                 });
+const tagsBase = Prisma.validator<Prisma.TagsDefaultArgs>()({
+                                                                    include: {
+                                                                        name: true,
+                                                                        type: true,
+                                                                    }
+                                                                });
 
 
 export type User = Prisma.UserGetPayload<typeof userBase> & {
@@ -44,4 +44,4 @@ export type Assignment = Prisma.AssignmentGetPayload<typeof assignmentBase> & {
     corrections: LazyVal<Array<Exercise>>
 }
 export type Result = Prisma.ResultGetPayload<typeof resultBase>
-// export type Tags = Prisma.ResultGetPayload<typeof tagsBase>
\ No newline at end of file
+export type Tags = Prisma.TagGetPayload<typeof tagsBase>
\ No newline at end of file
diff --git a/ExpressAPI/src/types/express/index.d.ts b/ExpressAPI/src/types/express/index.d.ts
index 744609f..815c382 100644
--- a/ExpressAPI/src/types/express/index.d.ts
+++ b/ExpressAPI/src/types/express/index.d.ts
@@ -1,5 +1,5 @@
 import Session                  from '../../controllers/Session.js';
-import { Assignment, Exercise } from '../DatabaseTypes.js';
+import { Assignment, Exercise, Tags } from '../DatabaseTypes';
 
 // to make the file a module and avoid the TypeScript error
 export {};
@@ -9,7 +9,7 @@ declare global {
         export interface Request {
             session: Session,
             boundParams: {
-                assignment: Assignment | undefined, exercise: Exercise | undefined
+                assignment: Assignment | undefined, exercise: Exercise | undefined, tag: Tags | undefined
             }
         }
     }
-- 
GitLab