diff --git a/lib/db/strategy-store.js b/lib/db/strategy-store.js index bee8e41fd3..6eaa15193b 100644 --- a/lib/db/strategy-store.js +++ b/lib/db/strategy-store.js @@ -7,7 +7,7 @@ const { } = require('../event-type'); const logger = require('../logger'); const NotFoundError = require('../error/notfound-error'); -const STRATEGY_COLUMNS = ['name', 'description', 'parameters']; +const STRATEGY_COLUMNS = ['name', 'description', 'parameters', 'built_in']; const TABLE = 'strategies'; class StrategyStore { @@ -46,9 +46,9 @@ class StrategyStore { if (!row) { throw new NotFoundError('No strategy found'); } - return { name: row.name, + editable: row.built_in !== 1, description: row.description, parameters: row.parameters, }; diff --git a/lib/routes/admin-api/strategy-schema.js b/lib/routes/admin-api/strategy-schema.js index ef910fe7c7..2b73711caf 100644 --- a/lib/routes/admin-api/strategy-schema.js +++ b/lib/routes/admin-api/strategy-schema.js @@ -4,6 +4,7 @@ const joi = require('joi'); const strategySchema = joi.object().keys({ name: joi.string().regex(/^[a-zA-Z0-9\\.\\-]{3,100}$/).required(), + editable: joi.boolean().default(true), description: joi.string(), parameters: joi.array().required().items( joi.object().keys({ diff --git a/lib/routes/admin-api/strategy.js b/lib/routes/admin-api/strategy.js index 9f19125032..7375946004 100644 --- a/lib/routes/admin-api/strategy.js +++ b/lib/routes/admin-api/strategy.js @@ -33,6 +33,28 @@ const handleError = (req, res, error) => { } }; +function validateEditable(strategyName) { + return strategy => { + if (strategy.editable === false) { + throw new Error( + `Cannot edit strategy ${strategyName}, editable is false` + ); + } + return strategy; + }; +} + +function validateInput(data) { + return new Promise((resolve, reject) => { + joi.validate(data, strategySchema, (err, cleaned) => { + if (err) { + return reject(err); + } + return resolve(cleaned); + }); + }); +} + exports.router = function(config) { const { strategyStore, eventStore } = config.stores; const router = Router(); @@ -57,6 +79,7 @@ exports.router = function(config) { strategyStore .getStrategy(strategyName) + .then(validateEditable(strategyName)) .then(() => eventStore.store({ type: eventType.STRATEGY_DELETED, @@ -70,6 +93,17 @@ exports.router = function(config) { .catch(error => handleError(req, res, error)); }); + function validateStrategyName(data) { + return new Promise((resolve, reject) => { + strategyStore + .getStrategy(data.name) + .then(() => + reject(new NameExistsError('Feature name already exist')) + ) + .catch(() => resolve(data)); + }); + } + router.post('/', (req, res) => { const data = req.body; validateInput(data) @@ -93,6 +127,7 @@ exports.router = function(config) { strategyStore .getStrategy(strategyName) + .then(validateEditable(strategyName)) .then(() => validateInput(updatedStrategy)) .then(() => eventStore.store({ @@ -105,27 +140,5 @@ exports.router = function(config) { .catch(error => handleError(req, res, error)); }); - function validateStrategyName(data) { - return new Promise((resolve, reject) => { - strategyStore - .getStrategy(data.name) - .then(() => - reject(new NameExistsError('Feature name already exist')) - ) - .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); - }); - }); - } - return router; };