Skip to content
Snippets Groups Projects
Select Git revision
  • adb405d77e6de91879c7b0cda4f3497eceb5ff86
  • main default protected
  • add_export_route
  • add_route_assignments
  • 4.1.0-dev
  • 4.0.0
  • 3.5.3
  • 3.5.3-dev
  • 3.5.2
  • 3.5.2-dev
  • 3.5.1
  • 3.5.1-dev
  • 3.5.0
  • 3.4.2
  • 3.4.1
  • 3.4.0
  • 3.3.0
  • 3.2.0
  • 3.1.3
  • 3.1.2
  • 3.1.1
  • 3.1.0
  • 3.0.1
  • 3.0.0
24 results

DojoValidators.ts

Blame
  • Forked from Dojo Project (HES-SO) / Projects / Backend / DojoBackendAPI
    Source project has a limited visibility.
    DojoValidators.ts 11.26 KiB
    import Config                                                       from '../config/Config.js';
    import { CustomValidator, ErrorMessage, FieldMessageFactory, Meta } from 'express-validator/src/base';
    import { BailOptions, ValidationChain }                             from 'express-validator/src/chain';
    import GitlabManager                                                from '../managers/GitlabManager.js';
    import express                                                      from 'express';
    import logger                                                       from '../shared/logging/WinstonLogger.js';
    import Json5FileValidator                                           from '../shared/helpers/Json5FileValidator.js';
    import ExerciseResultsFile                                          from '../shared/types/Dojo/ExerciseResultsFile.js';
    import ParamsCallbackManager                                        from '../middlewares/ParamsCallbackManager.js';
    import ExerciseManager                                              from '../managers/ExerciseManager.js';
    import Toolbox                                                      from '../shared/helpers/Toolbox.js';
    
    
    declare type DojoMeta = Meta & {
        req: express.Request
    };
    
    declare type DojoCustomValidator = (input: unknown, meta: DojoMeta) => unknown;
    
    declare type DojoCustomValidatorSchemaOptions = { errorMessage?: FieldMessageFactory | ErrorMessage, negated?: boolean, bail?: boolean | BailOptions, if?: CustomValidator | ValidationChain, options?: CustomValidator }
    
    
    class DojoValidators {
        private toValidatorSchemaOptions(arg: { errorMessage?: FieldMessageFactory | ErrorMessage, negated?: boolean, bail?: boolean | BailOptions, if?: DojoCustomValidator | ValidationChain, options?: DojoCustomValidator }) {
            // This is a hack to make the types work with req arg as express.Request instead of Request defined by express-validator
            return arg as unknown as DojoCustomValidatorSchemaOptions;
        }
    
        private getParamValue(req: express.Request, path: string): unknown {
            return 'body' in req && path in req.body ? req.body[path] : req.query[path];
        }
    
        readonly nullSanitizer = this.toValidatorSchemaOptions({
                                                                   options: value => {
                                                                       try {
                                                                           return value === 'null' || value === 'undefined' || value === '' ? null : value;
                                                                       } catch ( error ) {
                                                                           logger.error(`null sanitizer error: ${ JSON.stringify(error) }`);
    
                                                                           return value;
                                                                       }
                                                                   }
                                                               });
    
        readonly jsonSanitizer = this.toValidatorSchemaOptions({
                                                                   options: value => {
                                                                       try {
                                                                           return JSON.parse(value as string) as unknown;
                                                                       } catch ( e ) {
                                                                           return value;
                                                                       }
                                                                   }
                                                               });
    
        readonly templateUrlValidator = this.toValidatorSchemaOptions({
                                                                          bail        : true,
                                                                          errorMessage: 'Template doesn\'t exist or you don\'t have access to it',
                                                                          options     : (_value, {
                                                                              req,
                                                                              path
                                                                          }) => {
                                                                              return new Promise((resolve, reject) => {
                                                                                  const template = this.getParamValue(req, path) as string;
                                                                                  if ( template ) {
                                                                                      void GitlabManager.checkTemplateAccess(template, req).then(templateAccess => {
                                                                                          templateAccess ? resolve(true) : reject();
                                                                                      });
                                                                                  }
                                                                                  resolve(true);
                                                                              });
                                                                          }
                                                                      });
    
        readonly templateUrlSanitizer = this.toValidatorSchemaOptions({
                                                                          options: (value, {
                                                                              req,
                                                                              path
                                                                          }) => {
                                                                              try {
                                                                                  const template = this.getParamValue(req, path);
                                                                                  if ( template && Toolbox.isString(template) ) {
                                                                                      const gitlabUrlWithCredentials = Config.gitlab.urls[0].replace(/^([a-z]{3,5}:\/{2})?(.*)/, `$1${ Config.gitlab.account.username }:${ Config.gitlab.account.token }@$2`);
                                                                                      return `${ gitlabUrlWithCredentials }${ template }.git`;
                                                                                  } else {
                                                                                      return Config.assignment.default.template;
                                                                                  }
                                                                              } catch ( error ) {
                                                                                  logger.error(`Template url sanitizer error: ${ JSON.stringify(error) }`);
    
                                                                                  return value;
                                                                              }
                                                                          }
                                                                      });
    
        readonly exerciseResultsValidator = 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) as string;
                                                                                      if ( results ) {
                                                                                          Json5FileValidator.validateFile(ExerciseResultsFile, results, false).isValid ? resolve(true) : reject();
                                                                                      } else {
                                                                                          reject();
                                                                                      }
                                                                                  });
                                                                              }
                                                                          });
    
        readonly exerciseIdOrUrlValidator = this.toValidatorSchemaOptions({
                                                                              bail        : true,
                                                                              errorMessage: 'ExerciseIdOrUrl: not provided or invalid',
                                                                              options     : (_value, {
                                                                                  req,
                                                                                  path
                                                                              }) => {
                                                                                  return new Promise((resolve, reject) => {
                                                                                      const exerciseIdOrUrl = this.getParamValue(req, path) as string;
                                                                                      if ( exerciseIdOrUrl ) {
                                                                                          ParamsCallbackManager.initBoundParams(req);
    
                                                                                          ExerciseManager.get(exerciseIdOrUrl).then(exercise => {
                                                                                              req.boundParams.exercise = exercise;
    
                                                                                              exercise !== undefined ? resolve(true) : reject();
                                                                                          }).catch(() => {
                                                                                              reject();
                                                                                          });
                                                                                      } else {
                                                                                          reject();
                                                                                      }
                                                                                  });
                                                                              }
                                                                          });
    }
    
    
    export default new DojoValidators();