Merge pull request #833 from CartoDB/middlewarify-named-map-admin-controller

Middlewarify named map admin controller
This commit is contained in:
Daniel 2018-01-03 13:20:14 +01:00 committed by GitHub
commit 788bc302a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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);
};