mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Add schema validation for strategies
This commit is contained in:
		
							parent
							
								
									ba5810506f
								
							
						
					
					
						commit
						c8a9b39f27
					
				
							
								
								
									
										20
									
								
								lib/routes/strategy-schema.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								lib/routes/strategy-schema.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| 
 | ||||
| const strategySchema = joi.object().keys({ | ||||
|     name: joi.string() | ||||
|         .regex(/^[a-zA-Z0-9\\.\\-]{3,30}$/) | ||||
|         .required(), | ||||
|     description: joi.string(), | ||||
|     parameters: joi.array() | ||||
|         .required() | ||||
|         .items(joi.object().keys({ | ||||
|             name: joi.string().required(), | ||||
|             type: joi.string().required(), | ||||
|             description: joi.string(), | ||||
|             required: joi.boolean(), | ||||
|         })), | ||||
| }); | ||||
| 
 | ||||
| module.exports = strategySchema; | ||||
| @ -1,29 +1,28 @@ | ||||
| 'use strict'; | ||||
| 
 | ||||
| const joi = require('joi'); | ||||
| const eventType = require('../event-type'); | ||||
| const logger = require('../logger'); | ||||
| const NameExistsError = require('../error/name-exists-error'); | ||||
| const ValidationError = require('../error/validation-error.js'); | ||||
| const NotFoundError = require('../error/notfound-error'); | ||||
| const validateRequest = require('../error/validate-request'); | ||||
| const extractUser = require('../extract-user'); | ||||
| const strategySchema = require('./strategy-schema'); | ||||
| const version = 1; | ||||
| 
 | ||||
| const handleError = (req, res, error) => { | ||||
|     switch (error.constructor) { | ||||
|         case NotFoundError: | ||||
|     switch (error.name) { | ||||
|         case 'NotFoundError': | ||||
|             return res | ||||
|                 .status(404) | ||||
|                 .end(); | ||||
|         case NameExistsError: | ||||
|         case 'NameExistsError': | ||||
|             return res | ||||
|                 .status(403) | ||||
|                 .json([{ msg: `A strategy named '${req.body.name}' already exists.` }]) | ||||
|                 .end(); | ||||
|         case ValidationError: | ||||
|         case 'ValidationError': | ||||
|             return res | ||||
|                 .status(400) | ||||
|                 .json(req.validationErrors()) | ||||
|                 .json(error) | ||||
|                 .end(); | ||||
|         default: | ||||
|             logger.error('Could perfom operation', error); | ||||
| @ -64,14 +63,10 @@ module.exports = function (app, config) { | ||||
|     }); | ||||
| 
 | ||||
|     app.post('/strategies', (req, res) => { | ||||
|         req.checkBody('name', 'Name is required').notEmpty(); | ||||
|         req.checkBody('name', 'Name must match format ^[0-9a-zA-Z\\.\\-]+$').matches(/^[0-9a-zA-Z\\.\\-]+$/i); | ||||
| 
 | ||||
|         const newStrategy = req.body; | ||||
| 
 | ||||
|         validateRequest(req) | ||||
|         const data = req.body; | ||||
|         validateInput(data) | ||||
|             .then(validateStrategyName) | ||||
|             .then(() => eventStore.store({ | ||||
|             .then((newStrategy) => eventStore.store({ | ||||
|                 type: eventType.STRATEGY_CREATED, | ||||
|                 createdBy: extractUser(req), | ||||
|                 data: newStrategy, | ||||
| @ -80,11 +75,22 @@ module.exports = function (app, config) { | ||||
|             .catch(error => handleError(req, res, error)); | ||||
|     }); | ||||
| 
 | ||||
|     function validateStrategyName (req) { | ||||
|     function validateStrategyName (data) { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             strategyStore.getStrategy(req.body.name) | ||||
|             strategyStore.getStrategy(data.name) | ||||
|                 .then(() => reject(new NameExistsError('Feature name already exist'))) | ||||
|                 .catch(() => resolve(req)); | ||||
|                 .catch(() => resolve(data)); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     function validateInput (data) { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             joi.validate(data, strategySchema, (err, cleaned) => { | ||||
|                 if (err) { | ||||
|                     return reject(err); | ||||
|                 } | ||||
|                 return resolve(cleaned); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| 
 | ||||
| const { getInstance } = require('db-migrate'); | ||||
| const parseDbUrl = require('parse-database-url'); | ||||
| require('db-migrate-shared').log.silence(true); | ||||
| 
 | ||||
| function migrateDb ({ databaseUrl, databaseSchema = 'public' }) { | ||||
|     const custom = parseDbUrl(databaseUrl); | ||||
|  | ||||
| @ -42,7 +42,7 @@ test.serial('creates a new strategy', async (t) => { | ||||
|     const { request, destroy } = await setupApp('strategy_api_serial'); | ||||
|     return request | ||||
|         .post('/api/strategies') | ||||
|         .send({ name: 'myCustomStrategy', description: 'Best strategy ever.' }) | ||||
|         .send({ name: 'myCustomStrategy', description: 'Best strategy ever.', parameters: [] }) | ||||
|         .set('Content-Type', 'application/json') | ||||
|         .expect(201) | ||||
|         .then(destroy); | ||||
| @ -62,7 +62,7 @@ test.serial('refuses to create a strategy with an existing name', async (t) => { | ||||
|     const { request, destroy } = await setupApp('strategy_api_serial'); | ||||
|     return request | ||||
|         .post('/api/strategies') | ||||
|         .send({ name: 'default' }) | ||||
|         .send({ name: 'default', parameters: [] }) | ||||
|         .set('Content-Type', 'application/json') | ||||
|         .expect(403) | ||||
|         .then(destroy); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user