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