'use strict'; const Controller = require('../controller'); const eventType = require('../../event-type'); const NameExistsError = require('../../error/name-exists-error'); const extractUser = require('../../extract-user'); const strategySchema = require('./strategy-schema'); const { handleErrors } = require('./util'); const { DELETE_STRATEGY, CREATE_STRATEGY, UPDATE_STRATEGY, } = require('../../permissions'); const version = 1; class StrategyController extends Controller { constructor(config) { super(config); this.logger = config.getLogger('/admin-api/strategy.js'); this.strategyStore = config.stores.strategyStore; this.eventStore = config.stores.eventStore; this.get('/', this.getAllStratgies); this.get('/:name', this.getStrategy); this.delete('/:name', this.removeStrategy, DELETE_STRATEGY); this.post('/', this.createStrategy, CREATE_STRATEGY); this.put('/:strategyName', this.updateStrategy, UPDATE_STRATEGY); } async getAllStratgies(req, res) { const strategies = await this.strategyStore.getStrategies(); res.json({ version, strategies }); } async getStrategy(req, res) { try { const { name } = req.params; const strategy = await this.strategyStore.getStrategy(name); res.json(strategy).end(); } catch (err) { res.status(404).json({ error: 'Could not find strategy' }); } } async removeStrategy(req, res) { const strategyName = req.params.name; try { const strategy = await this.strategyStore.getStrategy(strategyName); await this._validateEditable(strategy); await this.eventStore.store({ type: eventType.STRATEGY_DELETED, createdBy: extractUser(req), data: { name: strategyName, }, }); res.status(200).end(); } catch (error) { handleErrors(res, this.logger, error); } } async createStrategy(req, res) { try { const value = await strategySchema.validateAsync(req.body); await this._validateStrategyName(value); await this.eventStore.store({ type: eventType.STRATEGY_CREATED, createdBy: extractUser(req), data: value, }); res.status(201).end(); } catch (error) { handleErrors(res, this.logger, error); } } async updateStrategy(req, res) { const input = req.body; try { const value = await strategySchema.validateAsync(input); const strategy = await this.strategyStore.getStrategy(input.name); await this._validateEditable(strategy); await this.eventStore.store({ type: eventType.STRATEGY_UPDATED, createdBy: extractUser(req), data: value, }); res.status(200).end(); } catch (error) { handleErrors(res, this.logger, error); } } // This check belongs in the store. async _validateStrategyName(data) { return new Promise((resolve, reject) => { this.strategyStore .getStrategy(data.name) .then(() => reject( new NameExistsError( `Strategy with name ${data.name} already exist!`, ), ), ) .catch(() => resolve(data)); }); } // This check belongs in the store. _validateEditable(strategy) { if (strategy.editable === false) { throw new Error(`Cannot edit strategy ${strategy.name}`); } } } module.exports = StrategyController;