add fallback for using metadata fallback

This commit is contained in:
Eneko Lakasta 2018-02-14 17:31:05 +01:00
parent 32986e3ebd
commit 890f0d1ef6
5 changed files with 216 additions and 4 deletions

View File

@ -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';

View File

@ -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 {

View File

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

View File

@ -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 <<EOF | redis-cli -p ${REDIS_PORT} -n 5
HMSET rails:users:user_previous_to_project_auth id ${TESTUSERID} \
database_name "${TEST_DB}" \
database_host "localhost" \
database_password "${TESTPASS}" \
database_publicuser "${PUBLICUSER}"\
map_key 4444
EOF
cat <<EOF | redis-cli -p ${REDIS_PORT} -n 0
HSET rails:${TEST_DB}:my_table infowindow "this, that, the other"
HSET rails:${TEST_DB}:test_table_private_1 privacy "0"

View File

@ -114,6 +114,7 @@ afterEach(function(done) {
'rails:users:localhost:map_key': true,
'rails:users:cartodb250user': true,
'rails:users:localhost': true,
'rails:users:user_previous_to_project_auth': true, // AUTH_FALLBACK
'api_keys:localhost:1234': true,
'api_keys:localhost:default_public': true,
'api_keys:cartodb250user:4321': true,