Skip to content
Snippets Groups Projects
Commit d25f1dc3 authored by michael.minelli's avatar michael.minelli
Browse files

ExerciceRoutes => Add create result route

parent 4c7fb3d6
No related branches found
No related tags found
No related merge requests found
...@@ -4,6 +4,7 @@ import { CustomValidator, ErrorMessage, FieldMessageFactory, Meta } from 'expres ...@@ -4,6 +4,7 @@ import { CustomValidator, ErrorMessage, FieldMessageFactory, Meta } from 'expres
import { BailOptions, ValidationChain } from 'express-validator/src/chain'; import { BailOptions, ValidationChain } from 'express-validator/src/chain';
import GitlabManager from '../managers/GitlabManager'; import GitlabManager from '../managers/GitlabManager';
import express from 'express'; import express from 'express';
import ExerciceHelper from '../shared/helpers/ExerciceHelper';
declare type DojoMeta = Meta & { declare type DojoMeta = Meta & {
...@@ -81,6 +82,24 @@ class DojoValidators { ...@@ -81,6 +82,24 @@ class DojoValidators {
return value; return value;
} }
}); });
readonly exerciceResultsValidator = this.toValidatorSchemaOptions({
bail : true,
errorMessage: 'Results: not provided or invalid format',
options : (value, {
req,
path
}) => {
return new Promise((resolve, reject) => {
const results = this.getParamValue(req, path);
if ( results ) {
ExerciceHelper.validateResultFile(results, false).isValid ? resolve(true) : reject();
} else {
reject();
}
});
}
});
} }
......
...@@ -24,6 +24,9 @@ import GitlabFile from '../shared/types/Gitlab/GitlabFile'; ...@@ -24,6 +24,9 @@ import GitlabFile from '../shared/types/Gitlab/GitlabFile';
import EnonceFile from '../shared/types/Dojo/EnonceFile'; import EnonceFile from '../shared/types/Dojo/EnonceFile';
import GitlabTreeFileType from '../shared/types/Gitlab/GitlabTreeFileType'; import GitlabTreeFileType from '../shared/types/Gitlab/GitlabTreeFileType';
import JSON5 from 'json5'; import JSON5 from 'json5';
import ExerciceResultsFile from '../shared/types/Dojo/ExerciceResultsFile';
import fs from 'fs';
import path from 'path';
class ExerciceRoutes implements RoutesManager { class ExerciceRoutes implements RoutesManager {
...@@ -35,10 +38,39 @@ class ExerciceRoutes implements RoutesManager { ...@@ -35,10 +38,39 @@ class ExerciceRoutes implements RoutesManager {
} }
}; };
private readonly resultValidator: ExpressValidator.Schema = {
exitCode : {
isInt: true,
toInt: true
},
commit : {
trim : true,
notEmpty : true,
customSanitizer: DojoValidators.jsonSanitizer
},
results : {
trim : true,
notEmpty : true,
custom : DojoValidators.exerciceResultsValidator,
customSanitizer: DojoValidators.jsonSanitizer
},
files : {
trim : true,
notEmpty : true,
customSanitizer: DojoValidators.jsonSanitizer
},
archiveBase64: {
isBase64: true,
notEmpty: true
}
};
registerOnBackend(backend: Express) { registerOnBackend(backend: Express) {
backend.post('/enonces/:enonceNameOrUrl/exercices', SecurityMiddleware.check(true, SecurityCheckType.ENONCE_IS_PUBLISHED), ParamsValidatorMiddleware.validate(this.exerciceValidator), this.createExercice.bind(this)); backend.post('/enonces/:enonceNameOrUrl/exercices', SecurityMiddleware.check(true, SecurityCheckType.ENONCE_IS_PUBLISHED), ParamsValidatorMiddleware.validate(this.exerciceValidator), this.createExercice.bind(this));
backend.get('/exercices/:exerciceId/enonce', SecurityMiddleware.check(false, SecurityCheckType.EXERCICE_SECRET), this.getEnonce.bind(this)); backend.get('/exercices/:exerciceId/enonce', SecurityMiddleware.check(false, SecurityCheckType.EXERCICE_SECRET), this.getEnonce.bind(this));
backend.post('/exercices/:exerciceId/results', SecurityMiddleware.check(false, SecurityCheckType.EXERCICE_SECRET), ParamsValidatorMiddleware.validate(this.resultValidator), this.createResult.bind(this));
} }
private getExerciceName(enonce: Enonce, members: Array<GitlabUser>, suffix: number): string { private getExerciceName(enonce: Enonce, members: Array<GitlabUser>, suffix: number): string {
...@@ -170,6 +202,26 @@ class ExerciceRoutes implements RoutesManager { ...@@ -170,6 +202,26 @@ class ExerciceRoutes implements RoutesManager {
immutable : immutableFiles immutable : immutableFiles
}); });
} }
private async createResult(req: express.Request, res: express.Response) {
const params: { exitCode: number, commit: any, results: ExerciceResultsFile, files: any, archiveBase64: string } = req.body;
const exercice: Exercice = req.boundParams.exercice!;
const result = await db.result.create({
data: {
exerciceId: exercice.id,
exitCode : params.exitCode,
success : params.results.success,
commit : params.commit,
results : params.results as unknown as Prisma.JsonObject,
files : params.files
}
});
fs.writeFileSync(path.join(Config.getResultsFolder(exercice), `${ result.dateTime.toISOString().replace(':', '-') }.tar.gz`), params.archiveBase64, 'base64');
req.session.sendResponse(res, StatusCodes.OK);
}
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment