Do not allow creating template with auth='token' and no valid tokens

Closes #128
Includes acceptance test for both creation and update
This commit is contained in:
Sandro Santilli
2014-02-06 12:24:14 +01:00
parent 752e9ec655
commit b4936ffafa
3 changed files with 175 additions and 2 deletions
+5
View File
@@ -143,6 +143,11 @@ o._checkInvalidTemplate = function(template) {
}
};
// Check certificate validity
var cert = this.getTemplateCertificate(template);
var err = this.signed_maps.checkInvalidCertificate(cert);
if ( err ) return err;
// TODO: run more checks over template format ?
};
+147 -2
View File
@@ -131,6 +131,153 @@ suite('template_api', function() {
);
});
// See https://github.com/CartoDB/Windshaft-cartodb/issues/128
test("cannot create template with auth='token' and no valid tokens", function(done) {
var tpl_id;
Step(
function postTemplate1()
{
// clone the valid one, and give it another name
var broken_template = JSON.parse(JSON.stringify(template_acceptance1));
broken_template.name = 'broken1';
// Set auth='token' and specify no tokens
broken_template.auth.method = 'token';
delete broken_template.auth.tokens;
var post_request_1 = {
url: '/tiles/template?api_key=1234',
method: 'POST',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(broken_template)
}
var next = this;
assert.response(server, post_request_1, {},
function(res) { next(null, res); });
},
function checkFailure1(err, res)
{
if ( err ) throw err;
assert.equal(res.statusCode, 400, res.body);
var parsedBody = JSON.parse(res.body);
assert.ok(parsedBody.hasOwnProperty('error'), res.body);
var re = RegExp(/invalid.*authentication.*missing/i);
assert.ok(parsedBody.error.match(re),
'Error for invalid authentication does not match ' + re + ': ' + parsedBody.error);
return null;
},
function postTemplate2(err)
{
if ( err ) throw err;
// clone the valid one and rename it
var broken_template = JSON.parse(JSON.stringify(template_acceptance1));
broken_template.name = 'broken1';
// Set auth='token' and specify no tokens
broken_template.auth.method = 'token';
broken_template.auth.tokens = [];
var post_request_1 = {
url: '/tiles/template?api_key=1234',
method: 'POST',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(broken_template)
}
var next = this;
assert.response(server, post_request_1, {},
function(res) { next(null, res); });
},
function checkFailure2(err, res)
{
if ( err ) throw err;
assert.equal(res.statusCode, 400, res.body);
var parsedBody = JSON.parse(res.body);
assert.ok(parsedBody.hasOwnProperty('error'), res.body);
var re = RegExp(/invalid.*authentication.*missing/i);
assert.ok(parsedBody.error.match(re),
'Error for invalid authentication does not match ' + re + ': ' + parsedBody.error);
return null;
},
function postTemplateValid(err)
{
if ( err ) throw err;
// clone the valid one and rename it
var broken_template = JSON.parse(JSON.stringify(template_acceptance1));
broken_template.name = 'broken1';
var post_request_1 = {
url: '/tiles/template?api_key=1234',
method: 'POST',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(broken_template)
}
var next = this;
assert.response(server, post_request_1, {},
function(res) { next(null, res); });
},
function putTemplateInvalid(err, res)
{
if ( err ) throw err;
assert.equal(res.statusCode, 200, res.body);
var parsed = JSON.parse(res.body);
assert.ok(parsed.hasOwnProperty('template_id'),
"Missing 'template_id' from response body: " + res.body);
tpl_id = parsed.template_id;
// clone the valid one and rename it
var broken_template = JSON.parse(JSON.stringify(template_acceptance1));
broken_template.name = 'broken1';
// Set auth='token' and specify no tokens
broken_template.auth.method = 'token';
broken_template.auth.tokens = [];
var put_request_1 = {
url: '/tiles/template/' + tpl_id + '/?api_key=1234',
method: 'PUT',
headers: {host: 'localhost', 'Content-Type': 'application/json' },
data: JSON.stringify(broken_template)
}
var next = this;
assert.response(server, put_request_1, {},
function(res) { next(null, res); });
},
function deleteTemplate(err, res)
{
if ( err ) throw err;
assert.equal(res.statusCode, 400, res.statusCode + ": " + res.body);
var parsed = JSON.parse(res.body);
assert.ok(parsed.hasOwnProperty('error'),
"Missing 'error' from response body: " + res.body);
var re = RegExp(/invalid.*authentication.*missing/i);
assert.ok(parsed.error.match(re),
'Error for invalid authentication on PUT does not match ' +
re + ': ' + parsed.error);
var del_request = {
url: '/tiles/template/' + tpl_id + '?api_key=1234',
method: 'DELETE',
headers: {host: 'localhost'}
}
var next = this;
assert.response(server, del_request, {},
function(res, err) { next(err, res); });
},
function checkDelete(err, res) {
if ( err ) throw err;
assert.equal(res.statusCode, 204, res.statusCode + ': ' + res.body);
assert.ok(!res.body, 'Unexpected body in DELETE /template response');
return null;
},
function finish(err) {
var errors = [];
if ( err ) errors.push(err);
redis_client.keys("map_*|localhost", function(err, keys) {
if ( err ) errors.push(err.message);
var todrop = _.map(keys, function(m) {
if ( m.match(/^map_(tpl|crt)|/) )
return m;
});
if ( todrop.length )
errors.push(new Error("Unexpected keys in redis: " + todrop));
if ( errors.length ) done(new Error(errors.join(',')));
else done();
});
}
);
});
test("instance endpoint should return CORS headers", function(done){
Step(function postTemplate1(err, res) {
var next = this;
@@ -1009,8 +1156,6 @@ suite('template_api', function() {
);
});
test("template instantiation raises mapviews counter", function(done) {
var layergroup = {
stat_tag: 'random_tag',
+23
View File
@@ -147,6 +147,28 @@ suite('template_maps', function() {
});
});
// See http://github.com/CartoDB/Windshaft-cartodb/issues/128
test('does not accept template with invalid token auth (undefined tokens)',
function(done) {
var tmap = new TemplateMaps(redis_pool, signed_maps);
assert.ok(tmap);
var tpl = { version:'0.0.1',
name: "invalid_auth1", placeholders: { },
auth: { method: 'token' }, layergroup: {} };
tmap.addTemplate('me', tpl, function(err) {
if ( ! err ) {
done(new Error("Unexpected success with invalid token auth (undefined tokens)"));
}
else if ( ! err.message.match(/invalid 'token' authentication/i) ) {
done(new Error("Unexpected error message with invalid token auth (undefined tokens): "
+ err));
}
else {
done();
}
});
});
test('add, get and delete a valid template', function(done) {
var tmap = new TemplateMaps(redis_pool, signed_maps);
assert.ok(tmap);
@@ -271,6 +293,7 @@ suite('template_maps', function() {
assert.ok(err);
tpl.name = 'first';
tpl.auth.method = 'token';
tpl.auth.valid_tokens = [ 'tok1' ];
tmap.updTemplate(owner, tpl_id, tpl, this);
},
function updateTemplateWithInvalid(err) {