From 890f0d1ef64046b7ffe199ada8e53bcf2b4e0afd Mon Sep 17 00:00:00 2001 From: Eneko Lakasta Date: Wed, 14 Feb 2018 17:31:05 +0100 Subject: [PATCH] add fallback for using metadata fallback --- lib/cartodb/api/auth_api.js | 23 ++- lib/cartodb/backends/pg_connection.js | 24 +++ .../acceptance/auth/authorization-fallback.js | 159 ++++++++++++++++++ test/support/prepare_db.sh | 13 ++ test/support/test_helper.js | 1 + 5 files changed, 216 insertions(+), 4 deletions(-) create mode 100644 test/acceptance/auth/authorization-fallback.js diff --git a/lib/cartodb/api/auth_api.js b/lib/cartodb/api/auth_api.js index ca4c2724..1ac2a1cc 100644 --- a/lib/cartodb/api/auth_api.js +++ b/lib/cartodb/api/auth_api.js @@ -1,3 +1,5 @@ +var _ = require('underscore'); // AUTH_FALLBACK + /** * * @param {PgConnection} pgConnection @@ -45,10 +47,10 @@ AuthApi.prototype.authorizedBySigner = function(res, callback) { }; function isValidApiKey(apikey) { - return apikey.type !== null && - apikey.user !== null && - apikey.databasePassword !== null && - apikey.databaseRole !== null; + return apikey.type && + apikey.user && + apikey.databasePassword && + apikey.databaseRole; } // Check if a request is authorized by api_key @@ -72,6 +74,19 @@ AuthApi.prototype.authorizedByAPIKey = function(user, req, callback) { if (err) { return callback(err); } + + //Remove this block when Auth fallback is not used anymore + // AUTH_FALLBACK + if (!apikey.databaseRole && apikey.user_id && global.environment.postgres_auth_user) { + apikey.databaseRole = _.template(global.environment.postgres_auth_user, apikey); + } + + //Remove this block when Auth fallback is not used anymore + // AUTH_FALLBACK + if (!apikey.databasePassword && global.environment.postgres.password) { + apikey.databasePassword = global.environment.postgres.password; + } + if ( !isValidApiKey(apikey)) { const error = new Error('Unauthorized'); error.type = 'auth'; diff --git a/lib/cartodb/backends/pg_connection.js b/lib/cartodb/backends/pg_connection.js index a145d0d2..d5d3ecdb 100644 --- a/lib/cartodb/backends/pg_connection.js +++ b/lib/cartodb/backends/pg_connection.js @@ -28,6 +28,12 @@ PgConnection.prototype.setDBAuth = function(username, params, apikeyType, callba params.dbuser = apikey.databaseRole; params.dbpassword = apikey.databasePassword; + //Remove this block when Auth fallback is not used anymore + // AUTH_FALLBACK + if (!params.dbuser && apikey.user_id && global.environment.postgres_auth_user) { + params.dbuser = _.template(global.environment.postgres_auth_user, apikey); + } + return callback(); }); } else if (apikeyType === 'regular') { @@ -39,6 +45,18 @@ PgConnection.prototype.setDBAuth = function(username, params, apikeyType, callba params.dbuser = apikey.databaseRole; params.dbpassword = apikey.databasePassword; + //Remove this block when Auth fallback is not used anymore + // AUTH_FALLBACK + if (!params.dbuser && apikey.user_id && apikey.type === 'master' && global.environment.postgres_auth_user) { + params.dbuser = _.template(global.environment.postgres_auth_user, apikey); + } + + //Remove this block when Auth fallback is not used anymore + // AUTH_FALLBACK + if (!params.dbpassword && global.environment.postgres.password) { + params.dbpassword = global.environment.postgres.password; + } + return callback(); }); } else if (apikeyType === 'default') { @@ -50,6 +68,12 @@ PgConnection.prototype.setDBAuth = function(username, params, apikeyType, callba params.dbuser = apikey.databaseRole; params.dbpassword = apikey.databasePassword; + //Remove this block when Auth fallback is not used anymore + // AUTH_FALLBACK + if (!params.dbpassword && global.environment.postgres.password) { + params.dbpassword = global.environment.postgres.password; + } + return callback(); }); } else { diff --git a/test/acceptance/auth/authorization-fallback.js b/test/acceptance/auth/authorization-fallback.js new file mode 100644 index 00000000..032a8d08 --- /dev/null +++ b/test/acceptance/auth/authorization-fallback.js @@ -0,0 +1,159 @@ +//Remove this file when Auth fallback is not used anymore +// AUTH_FALLBACK + +const assert = require('../../support/assert'); +const testHelper = require('../../support/test_helper'); +const CartodbWindshaft = require('../../../lib/cartodb/server'); +const serverOptions = require('../../../lib/cartodb/server_options'); +const server = new CartodbWindshaft(serverOptions); +var LayergroupToken = require('../../../lib/cartodb/models/layergroup-token'); + +function singleLayergroupConfig(sql, cartocss) { + return { + version: '1.7.0', + layers: [ + { + type: 'mapnik', + options: { + sql: sql, + cartocss: cartocss, + cartocss_version: '2.3.0' + } + } + ] + }; +} + +function createRequest(layergroup, userHost, apiKey) { + var url = layergroupUrl; + if (apiKey) { + url += '?api_key=' + apiKey; + } + return { + url: url, + method: 'POST', + headers: { + host: userHost || 'localhost', + 'Content-Type': 'application/json' + }, + data: JSON.stringify(layergroup) + }; +} + +var layergroupUrl = '/api/v1/map'; +var pointSqlMaster = "select * from test_table_private_1"; +var pointSqlPublic = "select * from test_table"; +var keysToDelete; + +describe('authorization fallback', function () { + beforeEach(function () { + keysToDelete = {}; + }); + + afterEach(function (done) { + testHelper.deleteRedisKeys(keysToDelete, done); + }); + + it("succeed with master", function (done) { + var layergroup = singleLayergroupConfig(pointSqlMaster, '#layer { marker-fill:red; }'); + + assert.response(server, + createRequest(layergroup, 'user_previous_to_project_auth', '4444'), + { + status: 200 + }, + function (res, err) { + assert.ifError(err); + + var parsed = JSON.parse(res.body); + assert.ok(parsed.layergroupid); + assert.equal(res.headers['x-layergroup-id'], parsed.layergroupid); + + keysToDelete['map_cfg|' + LayergroupToken.parse(parsed.layergroupid).token] = 0; + keysToDelete['user:user_previous_to_project_auth:mapviews:global'] = 5; + + done(); + } + ); + }); + + + it("succeed with default - sending default_public", function (done) { + var layergroup = singleLayergroupConfig(pointSqlPublic, '#layer { marker-fill:red; }'); + + assert.response(server, + createRequest(layergroup, 'user_previous_to_project_auth', 'default_public'), + { + status: 200 + }, + function (res, err) { + assert.ifError(err); + + var parsed = JSON.parse(res.body); + assert.ok(parsed.layergroupid); + assert.equal(res.headers['x-layergroup-id'], parsed.layergroupid); + + keysToDelete['map_cfg|' + LayergroupToken.parse(parsed.layergroupid).token] = 0; + keysToDelete['user:user_previous_to_project_auth:mapviews:global'] = 5; + + done(); + } + ); + }); + + + it("succeed with default - sending no api key token", function (done) { + var layergroup = singleLayergroupConfig(pointSqlPublic, '#layer { marker-fill:red; }'); + + assert.response(server, + createRequest(layergroup, 'user_previous_to_project_auth'), + { + status: 200 + }, + function (res, err) { + assert.ifError(err); + + var parsed = JSON.parse(res.body); + assert.ok(parsed.layergroupid); + assert.equal(res.headers['x-layergroup-id'], parsed.layergroupid); + + keysToDelete['map_cfg|' + LayergroupToken.parse(parsed.layergroupid).token] = 0; + keysToDelete['user:user_previous_to_project_auth:mapviews:global'] = 5; + + done(); + } + ); + }); + + it("fail with non-existent api key", function (done) { + var layergroup = singleLayergroupConfig(pointSqlMaster, '#layer { marker-fill:red; }'); + + assert.response(server, + createRequest(layergroup, 'user_previous_to_project_auth', 'THIS-API-KEY-DOESNT-EXIST'), + { + status: 401 + }, + function (res, err) { + assert.ifError(err); + + done(); + } + ); + }); + + it("fail with default", function (done) { + var layergroup = singleLayergroupConfig(pointSqlMaster, '#layer { marker-fill:red; }'); + + assert.response(server, + createRequest(layergroup, 'user_previous_to_project_auth', 'default_public'), + { + status: 403 + }, + function (res, err) { + assert.ifError(err); + + done(); + } + ); + }); +}); \ No newline at end of file diff --git a/test/support/prepare_db.sh b/test/support/prepare_db.sh index 56fcc3c9..59405389 100755 --- a/test/support/prepare_db.sh +++ b/test/support/prepare_db.sh @@ -131,6 +131,19 @@ HMSET rails:users:cartodb250user id ${TESTUSERID} \ map_key 4321 EOF + +# Remove this block when Auth fallback is not used anymore +# AUTH_FALLBACK + # A user to test auth fallback to no api keys mode + cat <