Changes authentication to start using public user if it is defined in redis.
This commit is contained in:
parent
080ef555a4
commit
572f8c59b7
@ -195,7 +195,6 @@ function handleQuery(req, res) {
|
|||||||
var params = _.extend({}, req.query, body); // clone so don't modify req.params or req.body so oauth is not broken
|
var params = _.extend({}, req.query, body); // clone so don't modify req.params or req.body so oauth is not broken
|
||||||
var sql = params.q;
|
var sql = params.q;
|
||||||
var api_key = params.api_key;
|
var api_key = params.api_key;
|
||||||
var database = params.database; // TODO: Deprecate
|
|
||||||
var limit = parseInt(params.rows_per_page);
|
var limit = parseInt(params.rows_per_page);
|
||||||
var offset = parseInt(params.page);
|
var offset = parseInt(params.page);
|
||||||
var orderBy = params.order_by;
|
var orderBy = params.order_by;
|
||||||
@ -203,7 +202,6 @@ function handleQuery(req, res) {
|
|||||||
var requestedFormat = params.format;
|
var requestedFormat = params.format;
|
||||||
var format = _.isArray(requestedFormat) ? _.last(requestedFormat) : requestedFormat;
|
var format = _.isArray(requestedFormat) ? _.last(requestedFormat) : requestedFormat;
|
||||||
var requestedFilename = params.filename;
|
var requestedFilename = params.filename;
|
||||||
var cache_policy = params.cache_policy;
|
|
||||||
var filename = requestedFilename;
|
var filename = requestedFilename;
|
||||||
var requestedSkipfields = params.skipfields;
|
var requestedSkipfields = params.skipfields;
|
||||||
var skipfields;
|
var skipfields;
|
||||||
@ -240,7 +238,6 @@ function handleQuery(req, res) {
|
|||||||
format = (format === "" || _.isUndefined(format)) ? 'json' : format.toLowerCase();
|
format = (format === "" || _.isUndefined(format)) ? 'json' : format.toLowerCase();
|
||||||
filename = (filename === "" || _.isUndefined(filename)) ? 'cartodb-query' : sanitize_filename(filename);
|
filename = (filename === "" || _.isUndefined(filename)) ? 'cartodb-query' : sanitize_filename(filename);
|
||||||
sql = (sql === "" || _.isUndefined(sql)) ? null : sql;
|
sql = (sql === "" || _.isUndefined(sql)) ? null : sql;
|
||||||
database = (database === "" || _.isUndefined(database)) ? null : database;
|
|
||||||
limit = (!_.isNaN(limit)) ? limit : null;
|
limit = (!_.isNaN(limit)) ? limit : null;
|
||||||
offset = (!_.isNaN(offset)) ? offset * limit : null;
|
offset = (!_.isNaN(offset)) ? offset * limit : null;
|
||||||
|
|
||||||
@ -258,10 +255,13 @@ function handleQuery(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//if ( -1 === supportedFormats.indexOf(format) )
|
//if ( -1 === supportedFormats.indexOf(format) )
|
||||||
if ( ! formats.hasOwnProperty(format) )
|
if ( ! formats.hasOwnProperty(format) ) {
|
||||||
throw new Error("Invalid format: " + format);
|
throw new Error("Invalid format: " + format);
|
||||||
|
}
|
||||||
|
|
||||||
if (!_.isString(sql)) throw new Error("You must indicate a sql query");
|
if (!_.isString(sql)) {
|
||||||
|
throw new Error("You must indicate a sql query");
|
||||||
|
}
|
||||||
|
|
||||||
// initialise MD5 key of sql for cache lookups
|
// initialise MD5 key of sql for cache lookups
|
||||||
var sql_md5 = generateMD5(sql);
|
var sql_md5 = generateMD5(sql);
|
||||||
@ -289,79 +289,70 @@ function handleQuery(req, res) {
|
|||||||
// 4. Setup headers
|
// 4. Setup headers
|
||||||
// 5. Send formatted results back
|
// 5. Send formatted results back
|
||||||
Step(
|
Step(
|
||||||
function getDatabaseName() {
|
function getDatabaseConnectionParams() {
|
||||||
checkAborted('getDatabaseName');
|
checkAborted('getDatabaseConnectionParams');
|
||||||
if (_.isNull(database)) {
|
Meta.getUserDBConnectionParams(cdbuser, this);
|
||||||
Meta.getUserDBName(cdbuser, this);
|
|
||||||
} else {
|
|
||||||
// database hardcoded in query string (deprecated??): don't use redis
|
|
||||||
return database;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
function setDBGetUser(err, data) {
|
function setDBConnectionParams(err, dbParams) {
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
// If the database could not be found, the user is non-existant
|
|
||||||
if ( err.message.match('missing') ) {
|
|
||||||
err.message = "Sorry, we can't find CartoDB user '" + cdbuser
|
|
||||||
+ "'. Please check that you have entered the correct domain.";
|
|
||||||
err.http_status = 404;
|
err.http_status = 404;
|
||||||
}
|
err.message = "Sorry, we can't find CartoDB user '" + cdbuser
|
||||||
throw err;
|
+ "'. Please check that you have entered the correct domain.";
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
if ( req.profiler ) req.profiler.done('getDatabaseName');
|
dbopts.host = dbParams.dbhost;
|
||||||
|
dbopts.dbname = dbParams.dbname;
|
||||||
|
dbopts.user = (!!dbParams.dbuser) ? dbParams.dbuser : global.settings.db_pubuser;
|
||||||
|
|
||||||
database = (data === "" || _.isNull(data) || _.isUndefined(data)) ? database : data;
|
return null;
|
||||||
dbopts.dbname = database;
|
},
|
||||||
|
function authenticate(err) {
|
||||||
if(api_key) {
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
if (api_key) {
|
||||||
apiKeyAuth.verifyRequest(req, this);
|
apiKeyAuth.verifyRequest(req, this);
|
||||||
} else {
|
} else {
|
||||||
oAuth.verifyRequest(req, this, requestProtocol);
|
oAuth.verifyRequest(req, this, requestProtocol);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
function setUserGetDBHost(err, data){
|
function setUserGetDBPassword(err, userId) {
|
||||||
if (err) throw err;
|
if (err) {
|
||||||
if ( req.profiler ) req.profiler.done('verifyRequest_' + ( api_key ? 'apikey' : 'oauth' ) );
|
throw err;
|
||||||
user_id = data;
|
}
|
||||||
authenticated = ! _.isNull(user_id);
|
authenticated = userId !== null;
|
||||||
|
if (authenticated) {
|
||||||
var dbuser = user_id ?
|
user_id = userId;
|
||||||
_.template(global.settings.db_user, {user_id: user_id})
|
dbopts.user = _.template(global.settings.db_user, {user_id: userId});
|
||||||
:
|
Meta.getUserDBPass(cdbuser, this);
|
||||||
global.settings.db_pubuser;
|
} else {
|
||||||
|
return null
|
||||||
dbopts.user = dbuser;
|
}
|
||||||
|
|
||||||
Meta.getUserDBHost(cdbuser, this);
|
|
||||||
},
|
},
|
||||||
function setDBHostGetPassword(err, data){
|
function setPassword(err, password) {
|
||||||
if (err) throw err;
|
if (err) {
|
||||||
if ( req.profiler ) req.profiler.done('getUserDBHost');
|
throw err;
|
||||||
|
}
|
||||||
dbopts.host = data || global.settings.db_host;
|
if ( authenticated ) {
|
||||||
|
if ( global.settings.hasOwnProperty('db_user_pass') ) {
|
||||||
// by-pass redis lookup for password if not authenticated
|
dbopts.pass = _.template(global.settings.db_user_pass, {
|
||||||
if ( ! authenticated ) return null;
|
user_id: user_id,
|
||||||
|
user_password: password
|
||||||
Meta.getUserDBPass(cdbuser, this);
|
});
|
||||||
|
} else {
|
||||||
|
delete dbopts.pass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
function queryExplain(err, data){
|
function queryExplain(err){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
if ( req.profiler ) req.profiler.done('getUserDBPass');
|
if ( req.profiler ) req.profiler.done('getUserDBPass');
|
||||||
checkAborted('queryExplain');
|
checkAborted('queryExplain');
|
||||||
|
|
||||||
if ( authenticated ) {
|
|
||||||
if ( global.settings.hasOwnProperty('db_user_pass') ) {
|
|
||||||
dbopts.pass = _.template(global.settings.db_user_pass, {
|
|
||||||
user_id: user_id,
|
|
||||||
user_password: data
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else delete dbopts.pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
pg = new PSQL(dbopts);
|
pg = new PSQL(dbopts);
|
||||||
// get all the tables from Cache or SQL
|
// get all the tables from Cache or SQL
|
||||||
tableCacheItem = tableCache.get(sql_md5);
|
tableCacheItem = tableCache.get(sql_md5);
|
||||||
@ -446,7 +437,7 @@ function handleQuery(req, res) {
|
|||||||
|
|
||||||
// Only set an X-Cache-Channel for responses we want Varnish to cache.
|
// Only set an X-Cache-Channel for responses we want Varnish to cache.
|
||||||
if ( tableCacheItem && ! tableCacheItem.may_write ) {
|
if ( tableCacheItem && ! tableCacheItem.may_write ) {
|
||||||
res.header('X-Cache-Channel', generateCacheKey(database, tableCacheItem, authenticated));
|
res.header('X-Cache-Channel', generateCacheKey(dbopts.dbname, tableCacheItem, authenticated));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Last-Modified header
|
// Set Last-Modified header
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
"underscore.string": "~1.1.6",
|
"underscore.string": "~1.1.6",
|
||||||
"pg": "git://github.com/CartoDB/node-postgres.git#2.6.2-cdb1",
|
"pg": "git://github.com/CartoDB/node-postgres.git#2.6.2-cdb1",
|
||||||
"express": "~2.5.11",
|
"express": "~2.5.11",
|
||||||
"cartodb-redis": "~0.3.0",
|
"cartodb-redis": "~0.5.0",
|
||||||
"step": "0.0.x",
|
"step": "0.0.x",
|
||||||
"topojson": "0.0.8",
|
"topojson": "0.0.8",
|
||||||
"oauth-client": "0.2.0",
|
"oauth-client": "0.2.0",
|
||||||
|
@ -109,6 +109,7 @@ test('OPTIONS /api/x/sql', function(done){
|
|||||||
test('GET /api/v1/sql with SQL parameter on SELECT only. No oAuth included ', function(done){
|
test('GET /api/v1/sql with SQL parameter on SELECT only. No oAuth included ', function(done){
|
||||||
assert.response(app, {
|
assert.response(app, {
|
||||||
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db',
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db',
|
||||||
|
headers: {host: 'vizzuality.cartodb.com'},
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
},{ }, function(res) {
|
},{ }, function(res) {
|
||||||
assert.equal(res.statusCode, 200, res.body);
|
assert.equal(res.statusCode, 200, res.body);
|
||||||
@ -122,6 +123,7 @@ test('GET /api/v1/sql with SQL parameter on SELECT only. No oAuth included ', fu
|
|||||||
test('cache_policy=persist', function(done){
|
test('cache_policy=persist', function(done){
|
||||||
assert.response(app, {
|
assert.response(app, {
|
||||||
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db&cache_policy=persist',
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db&cache_policy=persist',
|
||||||
|
headers: {host: 'vizzuality.cartodb.com'},
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
},{ }, function(res) {
|
},{ }, function(res) {
|
||||||
assert.equal(res.statusCode, 200, res.body);
|
assert.equal(res.statusCode, 200, res.body);
|
||||||
@ -334,6 +336,7 @@ test('POST /api/v1/sql with SQL parameter on SELECT only. no database param, jus
|
|||||||
test('GET /api/v1/sql with INSERT. oAuth not used, so public user - should fail', function(done){
|
test('GET /api/v1/sql with INSERT. oAuth not used, so public user - should fail', function(done){
|
||||||
assert.response(app, {
|
assert.response(app, {
|
||||||
url: "/api/v1/sql?q=INSERT%20INTO%20untitle_table_4%20(cartodb_id)%20VALUES%20(1e4)&database=cartodb_test_user_1_db",
|
url: "/api/v1/sql?q=INSERT%20INTO%20untitle_table_4%20(cartodb_id)%20VALUES%20(1e4)&database=cartodb_test_user_1_db",
|
||||||
|
headers: {host: 'vizzuality.cartodb.com'},
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
},{
|
},{
|
||||||
}, function(res) {
|
}, function(res) {
|
||||||
@ -350,6 +353,7 @@ test('GET /api/v1/sql with INSERT. oAuth not used, so public user - should fail'
|
|||||||
test('GET /api/v1/sql with DROP TABLE. oAuth not used, so public user - should fail', function(done){
|
test('GET /api/v1/sql with DROP TABLE. oAuth not used, so public user - should fail', function(done){
|
||||||
assert.response(app, {
|
assert.response(app, {
|
||||||
url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4&database=cartodb_test_user_1_db",
|
url: "/api/v1/sql?q=DROP%20TABLE%20untitle_table_4&database=cartodb_test_user_1_db",
|
||||||
|
headers: {host: 'vizzuality.cartodb.com'},
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
},{
|
},{
|
||||||
}, function(res) {
|
}, function(res) {
|
||||||
@ -1392,6 +1396,7 @@ test('notice and warning info in JSON output', function(done){
|
|||||||
test('GET /api/v1/sql with SQL parameter on SELECT only should return CORS headers ', function(done){
|
test('GET /api/v1/sql with SQL parameter on SELECT only should return CORS headers ', function(done){
|
||||||
assert.response(app, {
|
assert.response(app, {
|
||||||
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db',
|
url: '/api/v1/sql?q=SELECT%20*%20FROM%20untitle_table_4&database=cartodb_test_user_1_db',
|
||||||
|
headers: {host: 'vizzuality.cartodb.com'},
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
},{ }, function(res) {
|
},{ }, function(res) {
|
||||||
assert.equal(res.statusCode, 200, res.body);
|
assert.equal(res.statusCode, 200, res.body);
|
||||||
|
@ -232,7 +232,7 @@ test('KML format, unauthenticated, concurrent requests', function(done){
|
|||||||
for (var i=0; i<concurrency; ++i) {
|
for (var i=0; i<concurrency; ++i) {
|
||||||
//console.log("Sending request");
|
//console.log("Sending request");
|
||||||
var req = http.request({
|
var req = http.request({
|
||||||
host: '127.0.0.1',
|
host: 'localhost',
|
||||||
port: port,
|
port: port,
|
||||||
path: '/api/v1/sql?' + query,
|
path: '/api/v1/sql?' + query,
|
||||||
headers: {host: 'vizzuality.cartodb.com'},
|
headers: {host: 'vizzuality.cartodb.com'},
|
||||||
|
@ -86,6 +86,11 @@ if test x"$PREPARE_REDIS" = xyes; then
|
|||||||
|
|
||||||
echo "preparing redis..."
|
echo "preparing redis..."
|
||||||
|
|
||||||
|
# delete previous publicuser
|
||||||
|
cat <<EOF | redis-cli -p ${REDIS_PORT} -n 5
|
||||||
|
HDEL rails:users:vizzuality database_publicuser
|
||||||
|
EOF
|
||||||
|
|
||||||
cat <<EOF | redis-cli -p ${REDIS_PORT} -n 5
|
cat <<EOF | redis-cli -p ${REDIS_PORT} -n 5
|
||||||
HMSET rails:users:vizzuality \
|
HMSET rails:users:vizzuality \
|
||||||
id 1 \
|
id 1 \
|
||||||
|
Loading…
Reference in New Issue
Block a user