From 7e1aba3368f4fa1cc934b6a3fb18e4d484a51b65 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Tue, 8 Apr 2014 09:16:16 +0200 Subject: [PATCH] Use signer's map_key when contacting sql-api Includes testcase. Fixes #188 --- NEWS.md | 1 + lib/cartodb/server_options.js | 30 +++++++++++++++++++++++++++--- test/acceptance/templates.js | 30 ++++++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index 4070d5af..e38dc4b4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,7 @@ Bug fixes: - Fix show_style tool broken since 1.8.1 + - Fix X-Cache-Channel of tiles accessed via signed token (#188) 1.10.1 -- 2014-03-21 -------------------- diff --git a/lib/cartodb/server_options.js b/lib/cartodb/server_options.js index ddcd7223..25468e8e 100644 --- a/lib/cartodb/server_options.js +++ b/lib/cartodb/server_options.js @@ -285,8 +285,31 @@ module.exports = function(){ } return [req.params.table]; } - var username = that.userByReq(req); - me.affectedTables(username, req.params.map_key, sql, this); + var user, key; + var next = this; + Step ( + function findUserKey() { + if ( req.params.hasOwnProperty('_authorizedBySigner') ) { + user = req.params._authorizedBySigner; + cartoData.getUserMapKey(user, this); + } else { + user = that.userByReq(req); + key = req.params.map_key || req.params.api_key; + return null; + } + }, + function getAffected(err, data) { + if ( err ) throw err; + if ( data ) { + if ( req.profiler ) req.profiler.done('getSignerMapKey'); + key = data; + } + me.affectedTables(user, key, sql, this); // in addCacheChannel + }, + function finish(err, data) { + next(err,data); + } + ); }, function buildCacheChannel(err, tableNames) { if ( err ) throw err; @@ -407,7 +430,7 @@ module.exports = function(){ Step( function getTables() { - me.affectedTables(usr, key, sql, this); + me.affectedTables(usr, key, sql, this); // in afterLayergroupCreate }, function getLastupdated(err, tableNames) { if (req.profiler) req.profiler.done('affectedTables'); @@ -671,6 +694,7 @@ module.exports = function(){ } // Authorized by "signed_by" ! + _.extend(req.params, { _authorizedBySigner: signed_by }); that.setDBAuth(signed_by, req.params, function(err) { if (req.profiler) req.profiler.done('setDBAuth'); callback(err, true); // authorized (or error) diff --git a/test/acceptance/templates.js b/test/acceptance/templates.js index d78ef637..5ee57016 100644 --- a/test/acceptance/templates.js +++ b/test/acceptance/templates.js @@ -20,7 +20,8 @@ var helper = require(__dirname + '/../support/test_helper'); var windshaft_fixtures = __dirname + '/../../node_modules/windshaft/test/fixtures'; var CartodbWindshaft = require(__dirname + '/../../lib/cartodb/cartodb_windshaft'); -var serverOptions = require(__dirname + '/../../lib/cartodb/server_options')(); +var ServerOptions = require(__dirname + '/../../lib/cartodb/server_options'); +var serverOptions = ServerOptions(); var server = new CartodbWindshaft(serverOptions); server.setMaxListeners(0); @@ -1167,12 +1168,37 @@ suite('template_api', function() { assert.response(server, get_request, {}, function(res) { next(null, res); }); }, - function checkTile(err, res) { + function checkTile_fetchOnRestart(err, res) { if ( err ) throw err; assert.equal(res.statusCode, 200, 'Unexpected error for authorized instance: ' + res.statusCode + ' -- ' + res.body); assert.equal(res.headers['content-type'], "application/json; charset=utf-8"); + var cc = res.headers['x-cache-channel']; + assert.ok(cc); + assert.ok(cc.match, /ciao/, cc); + // hack simulating restart... + serverOptions = ServerOptions(); // need to clean channel cache + server = new CartodbWindshaft(serverOptions); + var get_request = { + url: '/tiles/layergroup/' + layergroupid + ':cb1/0/0/0/1.json.torque?auth_token=valid1', + method: 'GET', + headers: {host: 'localhost' }, + encoding: 'binary' + } + var next = this; + assert.response(server, get_request, {}, + function(res) { next(null, res); }); + }, + function checkCacheChannel(err, res) { + if ( err ) throw err; + assert.equal(res.statusCode, 200, + 'Unexpected error for authorized instance: ' + + res.statusCode + ' -- ' + res.body); + assert.equal(res.headers['content-type'], "application/json; charset=utf-8"); + var cc = res.headers['x-cache-channel']; + assert.ok(cc, "Missing X-Cache-Channel on fetch-after-restart"); + assert.ok(cc.match, /ciao/, cc); return null; }, function deleteTemplate(err)