From dea427bdac9f2a1dba00a09ea591ace7f7b0ebfb Mon Sep 17 00:00:00 2001 From: "vincent.steinman" <vincent.steinmann@etu.hesge.ch> Date: Mon, 18 Mar 2024 17:25:56 +0100 Subject: [PATCH] fix shared --- .../migration.sql | 7 ++ .../20240309201554_tags/migration.sql | 1 + .../20240309204629_tag_type/migration.sql | 1 + .../20240311140413_tag_type/migration.sql | 1 + ExpressAPI/prisma/schema.prisma | 15 ++- ExpressAPI/prisma/seed.ts | 100 +++++++++--------- ExpressAPI/src/managers/TagManager.ts | 17 +++ ExpressAPI/src/managers/TagsManager.ts | 45 -------- ExpressAPI/src/routes/TagsRoutes.ts | 71 ++++++++++--- ExpressAPI/src/types/DatabaseTypes.ts | 6 +- 10 files changed, 151 insertions(+), 113 deletions(-) create mode 100644 ExpressAPI/prisma/migrations/20240309094026_add_correction_to_assignment/migration.sql create mode 100644 ExpressAPI/prisma/migrations/20240309201554_tags/migration.sql create mode 100644 ExpressAPI/prisma/migrations/20240309204629_tag_type/migration.sql create mode 100644 ExpressAPI/prisma/migrations/20240311140413_tag_type/migration.sql create mode 100644 ExpressAPI/src/managers/TagManager.ts delete mode 100644 ExpressAPI/src/managers/TagsManager.ts diff --git a/ExpressAPI/prisma/migrations/20240309094026_add_correction_to_assignment/migration.sql b/ExpressAPI/prisma/migrations/20240309094026_add_correction_to_assignment/migration.sql new file mode 100644 index 0000000..afb678b --- /dev/null +++ b/ExpressAPI/prisma/migrations/20240309094026_add_correction_to_assignment/migration.sql @@ -0,0 +1,7 @@ +-- CreateTable +CREATE TABLE `SubmissionTag` ( + `name` CHAR(36) NOT NULL, + `type` ENUM('LANGUAGE', 'FRAMEWORK', 'THEME', 'USERDEFINED') NOT NULL, + + PRIMARY KEY (`name`) +) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/ExpressAPI/prisma/migrations/20240309201554_tags/migration.sql b/ExpressAPI/prisma/migrations/20240309201554_tags/migration.sql new file mode 100644 index 0000000..af5102c --- /dev/null +++ b/ExpressAPI/prisma/migrations/20240309201554_tags/migration.sql @@ -0,0 +1 @@ +-- This is an empty migration. \ No newline at end of file diff --git a/ExpressAPI/prisma/migrations/20240309204629_tag_type/migration.sql b/ExpressAPI/prisma/migrations/20240309204629_tag_type/migration.sql new file mode 100644 index 0000000..af5102c --- /dev/null +++ b/ExpressAPI/prisma/migrations/20240309204629_tag_type/migration.sql @@ -0,0 +1 @@ +-- This is an empty migration. \ No newline at end of file diff --git a/ExpressAPI/prisma/migrations/20240311140413_tag_type/migration.sql b/ExpressAPI/prisma/migrations/20240311140413_tag_type/migration.sql new file mode 100644 index 0000000..af5102c --- /dev/null +++ b/ExpressAPI/prisma/migrations/20240311140413_tag_type/migration.sql @@ -0,0 +1 @@ +-- This is an empty migration. \ No newline at end of file diff --git a/ExpressAPI/prisma/schema.prisma b/ExpressAPI/prisma/schema.prisma index 57139d4..452ec47 100644 --- a/ExpressAPI/prisma/schema.prisma +++ b/ExpressAPI/prisma/schema.prisma @@ -13,13 +13,19 @@ enum UserRole { ADMIN } -enum Type{ +enum TagType { LANGUAGE FRAMEWORK THEME USERDEFINED } +enum SubmissionStatus{ + PENDINGAPPROVAL + DECLINED + APPROVED +} + model User { id Int @id /// The user's id is the same as their gitlab id name String? @@ -84,8 +90,13 @@ model Result { model Tag { name String @id @db.Char(36) - type Type + type TagType assignment Assignment[] exercise Exercise[] +} + +model SubmissionTag { + name String @id @db.Char(36) + type TagType } \ No newline at end of file diff --git a/ExpressAPI/prisma/seed.ts b/ExpressAPI/prisma/seed.ts index cf91fde..6ac1a5d 100644 --- a/ExpressAPI/prisma/seed.ts +++ b/ExpressAPI/prisma/seed.ts @@ -6,12 +6,12 @@ import SharedConfig from '../src/shared/config/SharedConfig.js'; import { UserRole } from '@prisma/client'; import logger from '../src/shared/logging/WinstonLogger.js'; import db from '../src/helpers/DatabaseHelper.js'; -import TagsManager from '../src/managers/TagsManager'; - +import TagManager from '../src/managers/TagManager'; +import { TagType } from '@prisma/client'; async function main() { await users(); - await assignments();s + await assignments(); await exercises(); await results(); await tag(); @@ -1590,7 +1590,7 @@ async function tag() { update: {}, create: { name : 'C', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE } }); await db.tag.upsert({ @@ -1598,7 +1598,7 @@ async function tag() { update: {}, create: { name : 'Java', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1606,7 +1606,7 @@ async function tag() { update: {}, create: { name : 'Scala', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1614,7 +1614,7 @@ async function tag() { update: {}, create: { name : 'Kotlin', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1622,7 +1622,7 @@ async function tag() { update: {}, create: { name : 'Rust', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1630,7 +1630,7 @@ async function tag() { update: {}, create: { name : 'JavaScript', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1638,7 +1638,7 @@ async function tag() { update: {}, create: { name : 'TypeScript', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1646,7 +1646,7 @@ async function tag() { update: {}, create: { name : 'Python', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1654,7 +1654,7 @@ async function tag() { update: {}, create: { name : 'HTML', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1662,7 +1662,7 @@ async function tag() { update: {}, create: { name : 'CSS', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1670,7 +1670,7 @@ async function tag() { update: {}, create: { name : 'C++', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1678,7 +1678,7 @@ async function tag() { update: {}, create: { name : 'Go', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1686,7 +1686,7 @@ async function tag() { update: {}, create: { name : 'PHP', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1694,7 +1694,7 @@ async function tag() { update: {}, create: { name : 'C#', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1702,7 +1702,7 @@ async function tag() { update: {}, create: { name : 'Swift', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1710,7 +1710,7 @@ async function tag() { update: {}, create: { name : 'Matlab', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1718,7 +1718,7 @@ async function tag() { update: {}, create: { name : 'SQL', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1726,7 +1726,7 @@ async function tag() { update: {}, create: { name : 'Assembly', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1734,7 +1734,7 @@ async function tag() { update: {}, create: { name : 'Ruby', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1742,7 +1742,7 @@ async function tag() { update: {}, create: { name : 'Fortran', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1750,7 +1750,7 @@ async function tag() { update: {}, create: { name : 'Pascal', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1758,7 +1758,7 @@ async function tag() { update: {}, create: { name : 'Visual Basic', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1766,7 +1766,7 @@ async function tag() { update: {}, create: { name : 'R', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1774,7 +1774,7 @@ async function tag() { update: {}, create: { name : 'Objective-C', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1782,7 +1782,7 @@ async function tag() { update: {}, create: { name : 'Lua', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1790,7 +1790,7 @@ async function tag() { update: {}, create: { name : 'Ada', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1798,7 +1798,7 @@ async function tag() { update: {}, create: { name : 'Haskell', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1806,7 +1806,7 @@ async function tag() { update: {}, create: { name : 'Shell/PowerShell', - type : TagsManager.TagType.Language, + type : TagType.LANGUAGE, } }); await db.tag.upsert({ @@ -1814,7 +1814,7 @@ async function tag() { update: {}, create: { name : 'Express', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1822,7 +1822,7 @@ async function tag() { update: {}, create: { name : 'Django', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1830,7 +1830,7 @@ async function tag() { update: {}, create: { name : 'Ruby on Rails', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1838,7 +1838,7 @@ async function tag() { update: {}, create: { name : 'Angular', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1846,7 +1846,7 @@ async function tag() { update: {}, create: { name : 'React', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1854,7 +1854,7 @@ async function tag() { update: {}, create: { name : 'Flutter', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1862,7 +1862,7 @@ async function tag() { update: {}, create: { name : 'Ionic', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1870,7 +1870,7 @@ async function tag() { update: {}, create: { name : 'Flask', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1878,7 +1878,7 @@ async function tag() { update: {}, create: { name : 'React Native', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1886,7 +1886,7 @@ async function tag() { update: {}, create: { name : 'Xamarin', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1894,7 +1894,7 @@ async function tag() { update: {}, create: { name : 'Laravel', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1902,7 +1902,7 @@ async function tag() { update: {}, create: { name : 'Spring', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1910,7 +1910,7 @@ async function tag() { update: {}, create: { name : 'Play', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1918,7 +1918,7 @@ async function tag() { update: {}, create: { name : 'Symfony', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1926,7 +1926,7 @@ async function tag() { update: {}, create: { name : 'ASP.NET', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1934,7 +1934,7 @@ async function tag() { update: {}, create: { name : 'Meteor', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1942,7 +1942,7 @@ async function tag() { update: {}, create: { name : 'Vue.js', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1950,7 +1950,7 @@ async function tag() { update: {}, create: { name : 'Svelte', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); await db.tag.upsert({ @@ -1958,7 +1958,7 @@ async function tag() { update: {}, create: { name : 'Express.js', - type : TagsManager.TagType.Framework, + type : TagType.FRAMEWORK } }); } diff --git a/ExpressAPI/src/managers/TagManager.ts b/ExpressAPI/src/managers/TagManager.ts new file mode 100644 index 0000000..51d2320 --- /dev/null +++ b/ExpressAPI/src/managers/TagManager.ts @@ -0,0 +1,17 @@ +import { Prisma } from '@prisma/client'; +import { Assignment, User } from '../types/DatabaseTypes'; +import db from '../helpers/DatabaseHelper'; + +enum TagType{ + Language, + Framework, + Theme, + UserDefined +} + +class TagManager { + +} + + +export default new TagManager(); diff --git a/ExpressAPI/src/managers/TagsManager.ts b/ExpressAPI/src/managers/TagsManager.ts deleted file mode 100644 index 884459c..0000000 --- a/ExpressAPI/src/managers/TagsManager.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Prisma } from '@prisma/client'; -import { Assignment, User } from '../types/DatabaseTypes'; -import db from '../helpers/DatabaseHelper'; - -enum TagType{ - Language, - Framework, - Theme, - UserDefined -} - -class TagsManager { - async isUserAllowedToAccessTag(tag: Tags, user: User): Promise<boolean> { - if ( !tag.staff ) { - tag.staff = await db.assignment.findUnique({ - where: { - name: tag.name - } - }).staff() ?? []; - } - return tag.staff.findIndex(staff => staff.id === user.id) !== -1; - } - - async getByName(name: string, include: Prisma.TagInclude | undefined = undefined): Promise<Tag | undefined> { - return await db.assignment.findUnique({ - where : { - name: name - }, include: include - }) as unknown as Tag ?? undefined; - } - - getByGitlabLink(gitlabLink: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> { - const name = gitlabLink.replace('.git', '').split('/').pop()!; - - return this.getByName(name, include); - } - - get(nameOrUrl: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> { - // We can use the same function for both name and url because the name is the last part of the url and the name extraction from the url doesn't corrupt the name - return this.getByGitlabLink(nameOrUrl, include); - } -} - - -export default new TagManager(); diff --git a/ExpressAPI/src/routes/TagsRoutes.ts b/ExpressAPI/src/routes/TagsRoutes.ts index f7174dc..d8bc764 100644 --- a/ExpressAPI/src/routes/TagsRoutes.ts +++ b/ExpressAPI/src/routes/TagsRoutes.ts @@ -17,7 +17,7 @@ import logger from '../shared/logging/WinstonLogger'; import DojoValidators from '../helpers/DojoValidators'; import { Prisma } from '@prisma/client'; import db from '../helpers/DatabaseHelper'; -import { Assignment } from '../types/DatabaseTypes'; +import { Tags } from '../types/DatabaseTypes'; import AssignmentManager from '../managers/AssignmentManager'; import GitlabVisibility from '../shared/types/Gitlab/GitlabVisibility'; import fs from 'fs'; @@ -25,7 +25,15 @@ 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 '../managers/TagsManager'; +import TagsManager from '../managers/TagManager'; +import { TagType } from '@prisma/client'; + + +enum SubmitStatus{ + PendingApproval, + Declined, + Approved +} class TagRoutes implements RoutesManager { private readonly tagsValidator: ExpressValidator.Schema = { @@ -42,16 +50,16 @@ class TagRoutes implements RoutesManager { 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.get('/tags/proposals', SecurityMiddleware.check(true, SecurityCheckType.ADMIN), ParamsValidatorMiddleware.validate(this.tagsValidator), this.getSubmittedTag.bind(this)); + backend.get('/tags/proposals/state?', 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)); } private async addTag(req: express.Request, res: express.Response) { - let tagName = req.body.name + const tagName = req.body.name const tagType = req.body.type - if(tagType != TagsManager.TagType.UserDefined && !req.session.profile.isAdmin) { + if(tagType != TagType.USERDEFINED && !req.session.profile.isAdmin) { return req.session.sendResponse(res, StatusCodes.FORBIDDEN); } @@ -63,6 +71,10 @@ class TagRoutes implements RoutesManager { type : tagType, } }) + return req.session.sendResponse(res, StatusCodes.OK, { + tag : (req.boundParams.tag as Tags), + name : req.body.name + }, "Tag ajouté avec succès"); } private async deleteTag(req: express.Request, res: express.Response) { let tagName = req.body.name @@ -70,22 +82,55 @@ class TagRoutes implements RoutesManager { db.tag.delete({ where : { name: tagName } }) - + return req.session.sendResponse(res, StatusCodes.OK, "Tag supprimé avec succès"); } private async getSubmittedTag(req: express.Request, res: express.Response) { - - + let tagState = req.body.state + if(req.body.state == null){ + tagState = tagState.PendingApproval + } + //TODO Here? return req.session.sendResponse(res, StatusCodes.OK, { - assignment : (req.boundParams.exercise as Exercise).assignment, - assignmentFile: dojoAssignmentFile, - immutable : immutableFiles + name : req.body.name, + tag : (req.boundParams.tag as Tags) }); } private async SubmitTag(req: express.Request, res: express.Response) { - + const tagName = req.body.name + const tagType = req.body.type + + db.tag.upsert({ + where : { name: tagName }, + update: {}, + create: { + name : tagName, + type : tagType, + } + }) + + return req.session.sendResponse(res, StatusCodes.OK, { + name : req.body.name, + tag : (req.boundParams.tag as Tags) + }); } private async validateTag(req: express.Request, res: express.Response) { - + if(req.body.state == SubmitStatus.PendingApproval){ + return req.session.sendResponse(res, StatusCodes.OK, "Approbation toujours en attente"); + } else if (req.body.state == SubmitStatus.Declined){ + return req.session.sendResponse(res, StatusCodes.OK, req.body.details); + } else{ + let tagName = req.params.tagProposalName + let tagType = req.body.type + db.tag.upsert({ + where : { name: tagName }, + update: {}, + create: { + name : tagName, + type : tagType, + } + }) + } + return req.session.sendResponse(res, StatusCodes.OK, "Tag accepté"); } } diff --git a/ExpressAPI/src/types/DatabaseTypes.ts b/ExpressAPI/src/types/DatabaseTypes.ts index 1636dd7..24b8721 100644 --- a/ExpressAPI/src/types/DatabaseTypes.ts +++ b/ExpressAPI/src/types/DatabaseTypes.ts @@ -26,10 +26,10 @@ const resultBase = Prisma.validator<Prisma.ResultDefaultArgs>()({ exercise: true } }); -const tagsBase = Prisma.validator<Prisma.TagsDefaultArgs>()({ +const tagsBase = Prisma.validator<Prisma.TagDefaultArgs>()({ include: { - exercises: true, - assignments: true, + exercise: true, + assignment: true, } }); -- GitLab