diff --git a/ExpressAPI/src/managers/UserManager.ts b/ExpressAPI/src/managers/UserManager.ts index e2919e3bd4618e7beb474739bfcb32694df0d021..8fe60b35520f3a1f575138151cc9d2862993f2ac 100644 --- a/ExpressAPI/src/managers/UserManager.ts +++ b/ExpressAPI/src/managers/UserManager.ts @@ -1,5 +1,6 @@ -import User from '../models/User'; -import db from '../helpers/DatabaseHelper'; +import User from '../models/User'; +import db from '../helpers/DatabaseHelper'; +import GitlabUser from '../shared/types/Gitlab/GitlabUser'; class UserManager { @@ -44,6 +45,23 @@ class UserManager { async getByGitlabIds(gitlabIds: Array<number>): Promise<Array<User | number>> { return Promise.all(gitlabIds.map(gitlabId => this.getByGitlabId(gitlabId))); } + + async getFromGitlabUser(gitlabUser: GitlabUser, createIfNotExist: boolean = false): Promise<User | number> { + let user = await this.getByGitlabId(gitlabUser.id); + + if ( typeof user === 'number' && createIfNotExist ) { + user = await User.createFromSql({ + userFirstName: gitlabUser.name, + userGitlabId : gitlabUser.id + }).create(); + } + + return user; + } + + async getFromGitlabUsers(gitlabUsers: Array<GitlabUser>, createIfNotExist: boolean = false): Promise<Array<User | number>> { + return Promise.all(gitlabUsers.map(gitlabUser => this.getFromGitlabUser(gitlabUser, createIfNotExist))); + } } diff --git a/ExpressAPI/src/routes/EnonceRoutes.ts b/ExpressAPI/src/routes/EnonceRoutes.ts index 0e5a9d0ed84ea226cadc40ce7974533a49f2e0ee..d194b06bccb042badd135d4007163e139e36ed3c 100644 --- a/ExpressAPI/src/routes/EnonceRoutes.ts +++ b/ExpressAPI/src/routes/EnonceRoutes.ts @@ -19,6 +19,7 @@ import Enonce from '../models/Enonce'; import EnonceStaff from '../models/EnonceStaff'; import { AxiosError } from 'axios'; import logger from '../shared/logging/WinstonLogger'; +import DojoValidators from '../helpers/DojoValidators'; class EnonceRoutes implements RoutesManager { @@ -40,39 +41,33 @@ class EnonceRoutes implements RoutesManager { notEmpty: true }, members : { - trim : true, - notEmpty: true + trim : true, + notEmpty : true, + customSanitizer: DojoValidators.arraySanitizer }, template: { - optional: true, - trim : true, - notEmpty: true + trim : true, + custom : DojoValidators.templateUrlValidator, + customSanitizer: DojoValidators.templateUrlSanitizer } }; registerOnBackend(backend: Express) { + backend.get('/enonces/:enonceNameOrUrl', SecurityMiddleware.check(true), this.getEnonce); backend.post('/enonces', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.enonceValidator), this.createEnonce); } + // Get an enonce by its name or gitlab url + private async getEnonce(req: ApiRequest, res: express.Response) { + return req.boundParams.enonce ? req.session.sendResponse(res, StatusCodes.OK, req.boundParams.enonce.toJsonObject()) : res.status(StatusCodes.NOT_FOUND).send(); + } + private async createEnonce(req: ApiRequest, res: express.Response) { - const params: { name: string, members: string, template: string | null } = req.body; - const gitlabMembers: Array<GitlabUser> = JSON.parse(params.members) as Array<GitlabUser>; - - let template: string = Config.enonce.default.template; - if ( params.template ) { - template = params.template; - const templateAccess = await GitlabHelper.checkTemplateAccess(template, req); - - if ( templateAccess !== StatusCodes.OK ) { - return res.status(templateAccess).send(); - } else { - template = `${ Config.gitlab.urls[0].replace(/^([a-z]{3,5}:\/{2})?(.*)/, `$1${ Config.gitlab.account.username }:${ Config.gitlab.account.token }@$2`) }${ template }.git`; - } - } + const params: { name: string, members: Array<GitlabUser>, template: string } = req.body; let repository: GitlabRepository; try { - repository = 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, template); + repository = 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, params.template); } catch ( error ) { if ( error instanceof AxiosError ) { if ( error.response.data.message.name && error.response.data.message.name == 'has already been taken' ) { @@ -82,11 +77,12 @@ class EnonceRoutes implements RoutesManager { return res.status(error.response.status).send(); } + logger.error(error); return res.status(StatusCodes.INTERNAL_SERVER_ERROR).send(); } try { - const members: Array<GitlabMember | false> = await Promise.all([ req.session.profile.userGitlabId, ...gitlabMembers.map(member => member.id) ].map(async (memberId: number): Promise<GitlabMember | false> => { + const members: Array<GitlabMember | false> = await Promise.all([ req.session.profile.userGitlabId, ...params.members.map(member => member.id) ].map(async (memberId: number): Promise<GitlabMember | false> => { try { return await GitlabHelper.addRepositoryMember(repository.id, memberId, GitlabAccessLevel.Maintainer); } catch ( e ) { @@ -94,48 +90,29 @@ class EnonceRoutes implements RoutesManager { } })); - 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 Promise.all((await UserManager.getByGitlabIds(gitlabMembers.map(member => member.id))).map(async (user: User | number) => { - if ( typeof user === 'number' ) { - const gitlabUser = gitlabMembers.find(member => member.id === user); - - user = User.createFromSql({ - userFirstName: gitlabUser.name, - userGitlabId : gitlabUser.id - }); - - await user.create(); - } + const enonce: Enonce = await Enonce.createFromSql({ + enonceName : repository.name, + enonceGitlabId : repository.id, + enonceGitlabLink : repository.web_url, + enonceGitlabCreationInfo: JSON.stringify(repository), + enonceGitlabLastInfo : JSON.stringify(repository), + enonceGitlabLastInfoTs : new Date().getTime() + }).create(); - return user as User; - }))) ]; + let dojoUsers: Array<User> = [ req.session.profile, ...(await UserManager.getFromGitlabUsers(params.members, true) as Array<User>) ]; 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) => { - const enonceStaff = EnonceStaff.createFromSql({ - enonceID: enonce.enonceID, - userID : dojoUser.userID - }); - - await enonceStaff.create(); - })); + await Promise.all(dojoUsers.map(dojoUser => EnonceStaff.createFromSql({ + enonceName: enonce.enonceName, + userID : dojoUser.userID + }).create())); return req.session.sendResponse(res, StatusCodes.OK, enonce.toJsonObject()); } catch ( error ) { if ( error instanceof AxiosError ) { return res.status(error.response.status).send(); - } else { - logger.error(error); } + logger.error(error); return res.status(StatusCodes.INTERNAL_SERVER_ERROR).send(); } }