diff --git a/lib/cartodb/controllers/named_maps_admin.js b/lib/cartodb/controllers/named_maps_admin.js index 0f54ddf3..a4d05467 100644 --- a/lib/cartodb/controllers/named_maps_admin.js +++ b/lib/cartodb/controllers/named_maps_admin.js @@ -1,10 +1,6 @@ -var step = require('step'); -var assert = require('assert'); -var templateName = require('../backends/template_maps').templateName; - -var cors = require('../middleware/cors'); -var userMiddleware = require('../middleware/user'); - +const { templateName } = require('../backends/template_maps'); +const cors = require('../middleware/cors'); +const userMiddleware = require('../middleware/user'); /** * @param {AuthApi} authApi @@ -20,211 +16,189 @@ function NamedMapsAdminController(authApi, templateMaps) { module.exports = NamedMapsAdminController; NamedMapsAdminController.prototype.register = function (app) { + const { base_url_templated } = app; + app.post( - app.base_url_templated + '/', + `${base_url_templated}/`, cors(), userMiddleware, - this.create.bind(this) + this.checkContentType('POST', 'POST TEMPLATE'), + this.authorizedByAPIKey('create', 'POST TEMPLATE'), + this.create() ); app.put( - app.base_url_templated + '/:template_id', + `${base_url_templated}/:template_id`, cors(), userMiddleware, - this.update.bind(this) + this.checkContentType('PUT', 'PUT TEMPLATE'), + this.authorizedByAPIKey('update', 'PUT TEMPLATE'), + this.update() ); app.get( - app.base_url_templated + '/:template_id', + `${base_url_templated}/:template_id`, cors(), userMiddleware, - this.retrieve.bind(this) + this.authorizedByAPIKey('get', 'GET TEMPLATE'), + this.retrieve() ); app.delete( - app.base_url_templated + '/:template_id', + `${base_url_templated}/:template_id`, cors(), userMiddleware, - this.destroy.bind(this) + this.authorizedByAPIKey('delete', 'DELETE TEMPLATE'), + this.destroy() ); app.get( - app.base_url_templated + '/', + `${base_url_templated}/`, cors(), userMiddleware, - this.list.bind(this) + this.authorizedByAPIKey('list', 'GET TEMPLATE LIST'), + this.list() ); app.options( - app.base_url_templated + '/:template_id', + `${base_url_templated}/:template_id`, cors('Content-Type') ); }; -NamedMapsAdminController.prototype.create = function(req, res, next) { - var self = this; +NamedMapsAdminController.prototype.authorizedByAPIKey = function (action, label) { + return function authorizedByAPIKeyMiddleware (req, res, next) { + const { user } = res.locals; - var cdbuser = res.locals.user; + this.authApi.authorizedByAPIKey(user, req, (err, authenticated) => { + if (err) { + return next(err); + } - step( - function checkPerms(){ - self.authApi.authorizedByAPIKey(cdbuser, req, this); - }, - function addTemplate(err, authenticated) { - assert.ifError(err); - ifUnauthenticated(authenticated, 'Only authenticated users can get template maps'); - ifInvalidContentType(req, 'template POST data must be of type application/json'); - var cfg = req.body; - self.templateMaps.addTemplate(cdbuser, cfg, this); - }, - function prepareResponse(err, tpl_id){ - assert.ifError(err); - return { template_id: tpl_id }; - }, - finishFn(self, req, res, 'POST TEMPLATE', null, next) - ); + if (!authenticated) { + const error = new Error(`Only authenticated user can ${action} templated maps`); + error.http_status = 403; + error.label = label; + return next(error); + } + + next(); + }); + }.bind(this); }; -NamedMapsAdminController.prototype.update = function(req, res, next) { - var self = this; - - var cdbuser = res.locals.user; - var template; - var tpl_id; - - step( - function checkPerms(){ - self.authApi.authorizedByAPIKey(cdbuser, req, this); - }, - function updateTemplate(err, authenticated) { - assert.ifError(err); - ifUnauthenticated(authenticated, 'Only authenticated user can update templated maps'); - ifInvalidContentType(req, 'template PUT data must be of type application/json'); - - template = req.body; - tpl_id = templateName(req.params.template_id); - self.templateMaps.updTemplate(cdbuser, tpl_id, template, this); - }, - function prepareResponse(err){ - assert.ifError(err); - - return { template_id: tpl_id }; - }, - finishFn(self, req, res, 'PUT TEMPLATE', null, next) - ); +NamedMapsAdminController.prototype.checkContentType = function (action, label) { + return function checkContentTypeMiddleware (req, res, next) { + if (!req.is('application/json')) { + const error = new Error(`template ${action} data must be of type application/json`); + error.label = label; + return next(error); + } + next(); + }; }; -NamedMapsAdminController.prototype.retrieve = function(req, res, next) { - var self = this; +NamedMapsAdminController.prototype.create = function () { + return function createTemplateMiddleware (req, res, next) { + const { user } = res.locals; + const template = req.body; - req.profiler.start('windshaft-cartodb.get_template'); + this.templateMaps.addTemplate(user, template, (err, templateId) => { + if (err) { + return next(err); + } - var cdbuser = res.locals.user; - var tpl_id; - step( - function checkPerms(){ - self.authApi.authorizedByAPIKey(cdbuser, req, this); - }, - function getTemplate(err, authenticated) { - assert.ifError(err); - ifUnauthenticated(authenticated, 'Only authenticated users can get template maps'); + res.status(200); - tpl_id = templateName(req.params.template_id); - self.templateMaps.getTemplate(cdbuser, tpl_id, this); - }, - function prepareResponse(err, tpl_val) { - assert.ifError(err); - if ( ! tpl_val ) { - err = new Error("Cannot find template '" + tpl_id + "' of user '" + cdbuser + "'"); - err.http_status = 404; - throw err; + const method = req.query.callback ? 'jsonp' : 'json'; + res[method]({ template_id: templateId }); + }); + }.bind(this); +}; + +NamedMapsAdminController.prototype.update = function () { + return function updateTemplateMiddleware (req, res, next) { + const { user } = res.locals; + const template = req.body; + const templateId = templateName(req.params.template_id); + + this.templateMaps.updTemplate(user, templateId, template, (err) => { + if (err) { + return next(err); + } + + res.status(200); + + const method = req.query.callback ? 'jsonp' : 'json'; + res[method]({ template_id: templateId }); + }); + }.bind(this); +}; + +NamedMapsAdminController.prototype.retrieve = function () { + return function retrieveTemplateMiddleware (req, res, next) { + req.profiler.start('windshaft-cartodb.get_template'); + + const { user } = res.locals; + const templateId = templateName(req.params.template_id); + + this.templateMaps.getTemplate(user, templateId, (err, template) => { + if (err) { + return next(err); + } + + if (!template) { + const error = new Error(`Cannot find template '${templateId}' of user '${user}'`); + error.http_status = 404; + return next(error); } // auth_id was added by ourselves, // so we remove it before returning to the user - delete tpl_val.auth_id; - return { template: tpl_val }; - }, - finishFn(self, req, res, 'GET TEMPLATE', null, next) - ); + delete template.auth_id; + + res.status(200); + + const method = req.query.callback ? 'jsonp' : 'json'; + res[method]({ template }); + }); + }.bind(this); }; -NamedMapsAdminController.prototype.destroy = function(req, res, next) { - var self = this; +NamedMapsAdminController.prototype.destroy = function () { + return function destroyTemplateMiddleware (req, res, next) { + req.profiler.start('windshaft-cartodb.delete_template'); - req.profiler.start('windshaft-cartodb.delete_template'); + const { user } = res.locals; + const templateId = templateName(req.params.template_id); - var cdbuser = res.locals.user; - var tpl_id; - step( - function checkPerms(){ - self.authApi.authorizedByAPIKey(cdbuser, req, this); - }, - function deleteTemplate(err, authenticated) { - assert.ifError(err); - ifUnauthenticated(authenticated, 'Only authenticated users can delete template maps'); - - tpl_id = templateName(req.params.template_id); - self.templateMaps.delTemplate(cdbuser, tpl_id, this); - }, - function prepareResponse(err/*, tpl_val*/){ - assert.ifError(err); - return ''; - }, - finishFn(self, req, res, 'DELETE TEMPLATE', 204, next) - ); -}; - -NamedMapsAdminController.prototype.list = function(req, res, next) { - var self = this; - req.profiler.start('windshaft-cartodb.get_template_list'); - - var cdbuser = res.locals.user; - - step( - function checkPerms(){ - self.authApi.authorizedByAPIKey(cdbuser, req, this); - }, - function listTemplates(err, authenticated) { - assert.ifError(err); - ifUnauthenticated(authenticated, 'Only authenticated user can list templated maps'); - - self.templateMaps.listTemplates(cdbuser, this); - }, - function prepareResponse(err, tpl_ids){ - assert.ifError(err); - return { template_ids: tpl_ids }; - }, - finishFn(self, req, res, 'GET TEMPLATE LIST', null, next) - ); -}; - -function finishFn(controller, req, res, description, status, next) { - return function finish(err, body){ - if (err) { - err.label = description; - next(err); - } else { - res.status(status || 200); - - if (req.query && req.query.callback) { - res.jsonp(body); - } else { - res.json(body); + this.templateMaps.delTemplate(user, templateId, (err/* , tpl_val */) => { + if (err) { + return next(err); } - } - }; -} -function ifUnauthenticated(authenticated, description) { - if (!authenticated) { - var err = new Error(description); - err.http_status = 403; - throw err; - } -} + res.status(204); -function ifInvalidContentType(req, description) { - if (!req.is('application/json')) { - throw new Error(description); - } -} + const method = req.query.callback ? 'jsonp' : 'json'; + res[method](''); + }); + }.bind(this); +}; + +NamedMapsAdminController.prototype.list = function () { + return function listTemplatesMiddleware (req, res, next) { + req.profiler.start('windshaft-cartodb.get_template_list'); + + const { user } = res.locals; + + this.templateMaps.listTemplates(user, (err, templateIds) => { + if (err) { + return next(err); + } + + res.status(200); + + const method = req.query.callback ? 'jsonp' : 'json'; + res[method]({ template_ids: templateIds }); + }); + }.bind(this); +};