Merge pull request #290 from CartoDB/simplify-template-names

Simplify template names
This commit is contained in:
Raul Ochoa
2015-04-23 12:19:21 +02:00
3 changed files with 84 additions and 156 deletions
+77 -147
View File
@@ -1,4 +1,5 @@
var step = require('step');
var assert = require('assert');
var _ = require('underscore');
var CdbRequest = require('../models/cdb_request');
@@ -42,34 +43,17 @@ TemplateMapsController.prototype.create = function(req, res) {
self.serverOptions.authorizedByAPIKey(req, this);
},
function addTemplate(err, authenticated) {
if ( err ) throw err;
if (authenticated !== 1) {
err = new Error("Only authenticated user can create templated maps");
err.http_status = 403;
throw err;
}
if ( ! req.headers['content-type'] || req.headers['content-type'].split(';')[0] != 'application/json' )
throw new Error('template POST data must be of type application/json');
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){
if ( err ) throw err;
// NOTE: might omit "cdbuser" if == dbowner ...
return { template_id: cdbuser + '@' + tpl_id };
assert.ifError(err);
return { template_id: tpl_id };
},
function finish(err, response){
if (err){
response = { error: ''+err };
var statusCode = 400;
if ( ! _.isUndefined(err.http_status) ) {
statusCode = err.http_status;
}
self.app.sendError(res, response, statusCode, 'POST TEMPLATE', err);
} else {
self.app.sendResponse(res, [response, 200]);
}
}
finishFn(self.app, res, 'POST TEMPLATE')
);
};
@@ -87,42 +71,20 @@ TemplateMapsController.prototype.update = function(req, res) {
self.serverOptions.authorizedByAPIKey(req, this);
},
function updateTemplate(err, authenticated) {
if ( err ) throw err;
if (authenticated !== 1) {
err = new Error("Only authenticated user can list templated maps");
err.http_status = 403;
throw err;
}
if ( ! req.headers['content-type'] || req.headers['content-type'].split(';')[0] != 'application/json' )
throw new Error('template PUT data must be of type application/json');
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 = req.params.template_id.split('@');
if ( tpl_id.length > 1 ) {
if ( tpl_id[0] != cdbuser ) {
err = new Error("Invalid template id '" + req.params.template_id + "' for user '" + cdbuser + "'");
err.http_status = 404;
throw err;
}
tpl_id = tpl_id[1];
}
tpl_id = templateName(req.params.template_id);
self.templateMaps.updTemplate(cdbuser, tpl_id, template, this);
},
function prepareResponse(err){
if ( err ) throw err;
return { template_id: cdbuser + '@' + tpl_id };
assert.ifError(err);
return { template_id: tpl_id };
},
function finish(err, response){
if (err){
var statusCode = 400;
response = { error: ''+err };
if ( ! _.isUndefined(err.http_status) ) {
statusCode = err.http_status;
}
self.app.sendError(res, response, statusCode, 'PUT TEMPLATE', err);
} else {
self.app.sendResponse(res, [response, 200]);
}
}
finishFn(self.app, res, 'PUT TEMPLATE')
);
};
@@ -143,25 +105,13 @@ TemplateMapsController.prototype.retrieve = function(req, res) {
self.serverOptions.authorizedByAPIKey(req, this);
},
function updateTemplate(err, authenticated) {
if ( err ) throw err;
if (authenticated !== 1) {
err = new Error("Only authenticated users can get template maps");
err.http_status = 403;
throw err;
}
tpl_id = req.params.template_id.split('@');
if ( tpl_id.length > 1 ) {
if ( tpl_id[0] != cdbuser ) {
var templateNotFoundErr = new Error("Cannot get template id '" + req.params.template_id +
"' for user '" + cdbuser + "'");
templateNotFoundErr.http_status = 404;
throw templateNotFoundErr;
}
tpl_id = tpl_id[1];
}
assert.ifError(err);
ifUnauthenticated(authenticated, 'Only authenticated users can get template maps');
tpl_id = templateName(req.params.template_id);
self.templateMaps.getTemplate(cdbuser, tpl_id, this);
},
function prepareResponse(err, tpl_val){
function prepareResponse(err, tpl_val) {
if ( err ) throw err;
if ( ! tpl_val ) {
err = new Error("Cannot find template '" + tpl_id + "' of user '" + cdbuser + "'");
@@ -173,18 +123,7 @@ TemplateMapsController.prototype.retrieve = function(req, res) {
delete tpl_val.auth_id;
return { template: tpl_val };
},
function finish(err, response){
if (err){
var statusCode = 400;
response = { error: ''+err };
if ( ! _.isUndefined(err.http_status) ) {
statusCode = err.http_status;
}
self.app.sendError(res, response, statusCode, 'GET TEMPLATE', err);
} else {
self.app.sendResponse(res, [response, 200]);
}
}
finishFn(self.app, res, 'GET TEMPLATE')
);
};
@@ -204,40 +143,17 @@ TemplateMapsController.prototype.destroy = function(req, res) {
self.serverOptions.authorizedByAPIKey(req, this);
},
function updateTemplate(err, authenticated) {
if ( err ) throw err;
if (authenticated !== 1) {
err = new Error("Only authenticated users can delete template maps");
err.http_status = 403;
throw err;
}
tpl_id = req.params.template_id.split('@');
if ( tpl_id.length > 1 ) {
if ( tpl_id[0] != cdbuser ) {
var templateNotFoundErr = new Error("Cannot find template id '" + req.params.template_id +
"' for user '" + cdbuser + "'");
templateNotFoundErr.http_status = 404;
throw templateNotFoundErr;
}
tpl_id = tpl_id[1];
}
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*/){
if ( err ) throw err;
return { status: 'ok' };
},
function finish(err, response){
if (err){
var statusCode = 400;
response = { error: ''+err };
if ( ! _.isUndefined(err.http_status) ) {
statusCode = err.http_status;
}
self.app.sendError(res, response, statusCode, 'DELETE TEMPLATE', err);
} else {
self.app.sendResponse(res, ['', 204]);
}
}
finishFn(self.app, res, 'DELETE TEMPLATE', ['', 204])
);
};
@@ -256,32 +172,16 @@ TemplateMapsController.prototype.list = function(req, res) {
self.serverOptions.authorizedByAPIKey(req, this);
},
function listTemplates(err, authenticated) {
if ( err ) throw err;
if (authenticated !== 1) {
err = new Error("Only authenticated user can list templated maps");
err.http_status = 403;
throw err;
}
assert.ifError(err);
ifUnauthenticated(authenticated, 'Only authenticated user can list templated maps');
self.templateMaps.listTemplates(cdbuser, this);
},
function prepareResponse(err, tpl_ids){
if ( err ) throw err;
// NOTE: might omit "cbduser" if == dbowner ...
var ids = _.map(tpl_ids, function(id) { return cdbuser + '@' + id; });
return { template_ids: ids };
assert.ifError(err);
return { template_ids: tpl_ids };
},
function finish(err, response){
var statusCode = 200;
if (err){
response = { error: ''+err };
if ( ! _.isUndefined(err.http_status) ) {
statusCode = err.http_status;
}
self.app.sendError(res, response, statusCode, 'GET TEMPLATE LIST', err);
} else {
self.app.sendResponse(res, [response, statusCode]);
}
}
finishFn(self.app, res, 'GET TEMPLATE LIST')
);
};
@@ -293,9 +193,8 @@ TemplateMapsController.prototype.instantiate = function(req, res) {
}
step(
function() {
if ( ! req.headers['content-type'] || req.headers['content-type'].split(';')[0] != 'application/json') {
throw new Error('template POST data must be of type application/json, it is instead ');
}
ifInvalidContentType(req, 'template POST data must be of type application/json');
self.instantiateTemplate(req, res, req.body, this);
}, function(err, response) {
self.finish_instantiation(err, response, res);
@@ -350,17 +249,7 @@ TemplateMapsController.prototype.instantiateTemplate = function(req, res, templa
var fakereq; // used for call to createLayergroup
var cdbuser = cdbRequest.userByReq(req);
// Format of template_id: [<template_owner>]@<template_id>
var tpl_id = req.params.template_id.split('@');
if ( tpl_id.length > 1 ) {
if ( tpl_id[0] && tpl_id[0] != cdbuser ) {
var err = new Error('Cannot instanciate map of user "' + tpl_id[0] + '" on database of user "' + cdbuser +
'"');
err.http_status = 403;
callback(err);
return;
}
tpl_id = tpl_id[1];
}
var tpl_id = templateName(req.params.template_id);
var auth_token = req.query.auth_token;
step(
function getTemplate(){
@@ -468,3 +357,44 @@ TemplateMapsController.prototype.setDBParams = function(cdbuser, params, callbac
}
);
};
function finishFn(app, res, description, okResponse) {
return function finish(err, response){
var statusCode = 200;
if (err) {
statusCode = 400;
response = { error: '' + err };
if ( ! _.isUndefined(err.http_status) ) {
statusCode = err.http_status;
}
app.sendError(res, response, statusCode, description, err);
} else {
app.sendResponse(res, okResponse || [response, statusCode]);
}
};
}
function ifUnauthenticated(authenticated, description) {
if (authenticated !== 1) {
var err = new Error(description);
err.http_status = 403;
throw err;
}
}
function ifInvalidContentType(req, description) {
if ( ! req.headers['content-type'] || req.headers['content-type'].split(';')[0] != 'application/json' ) {
throw new Error(description);
}
}
function templateName(templateId) {
var templateIdTokens = templateId.split('@');
var name = templateIdTokens[0];
if (templateIdTokens.length > 1) {
name = templateIdTokens[1];
}
return name;
}
+1 -1
View File
@@ -23,7 +23,7 @@ describe('templates surrogate keys', function() {
var templateOwner = 'localhost',
templateName = 'acceptance',
expectedTemplateId = templateOwner + '@' + templateName,
expectedTemplateId = templateName,
template = {
version: '0.0.1',
name: templateName,
+6 -8
View File
@@ -69,7 +69,7 @@ describe('template_api', function() {
it("can add template, returning id", function(done) {
var errors = [];
var expected_tpl_id = "localhost@acceptance1";
var expected_tpl_id = "acceptance1";
var post_request_1 = {
url: '/api/v1/map/named',
method: 'POST',
@@ -801,7 +801,7 @@ describe('template_api', function() {
);
});
it("can instanciate a template by id", function(done) {
it("can instanciate a template by id wadus", function(done) {
// This map fetches data from a private table
var template_acceptance2 = {
@@ -880,12 +880,10 @@ describe('template_api', function() {
function instanciateAuth(err, res)
{
if ( err ) throw err;
assert.equal(res.statusCode, 403, res.statusCode + ': ' + res.body);
assert.equal(res.statusCode, 404, res.statusCode + ': ' + res.body);
var parsed = JSON.parse(res.body);
assert.ok(parsed.hasOwnProperty('error'),
"Missing 'error' from response body: " + res.body);
assert.ok(parsed.error.match(/cannot instanciate/i),
'Unexpected error for forbidden instance : ' + parsed.error);
assert.ok(parsed.hasOwnProperty('error'), "Missing 'error' from response body: " + res.body);
assert.ok(parsed.error.match(/not found/i), 'Unexpected error for forbidden instance : ' + parsed.error);
var post_request = {
url: '/api/v1/map/named/' + tpl_id + '?auth_token=valid2',
method: 'POST',
@@ -1907,7 +1905,7 @@ describe('template_api', function() {
var template_params = {};
var errors = [];
var expectedTemplateId = username + '@' + httpTemplateName;
var expectedTemplateId = httpTemplateName;
var layergroupid;
step(
function createTemplate()