2018-10-24 00:39:02 +08:00
|
|
|
'use strict';
|
|
|
|
|
2015-03-24 00:54:37 +08:00
|
|
|
var assert = require('assert');
|
|
|
|
var _ = require('underscore');
|
2012-07-18 17:00:24 +08:00
|
|
|
|
2015-09-17 00:09:39 +08:00
|
|
|
var RedisPool = require('redis-mpool');
|
|
|
|
var cartodbRedis = require('cartodb-redis');
|
2019-10-07 17:29:07 +08:00
|
|
|
var PgConnection = require('../../lib/backends/pg-connection');
|
|
|
|
var AuthBackend = require('../../lib/backends/auth');
|
|
|
|
var TemplateMaps = require('../../lib/backends/template-maps');
|
2015-09-17 00:09:39 +08:00
|
|
|
|
2019-10-07 17:29:07 +08:00
|
|
|
const cleanUpQueryParamsMiddleware = require('../../lib/api/middlewares/clean-up-query-params');
|
|
|
|
const authorizeMiddleware = require('../../lib/api/middlewares/authorize');
|
|
|
|
const dbConnSetupMiddleware = require('../../lib/api/middlewares/db-conn-setup');
|
|
|
|
const credentialsMiddleware = require('../../lib/api/middlewares/credentials');
|
2017-09-25 19:40:22 +08:00
|
|
|
|
2015-09-17 00:09:39 +08:00
|
|
|
var windshaft = require('windshaft');
|
2012-07-18 17:00:24 +08:00
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
describe('prepare-context', function () {
|
|
|
|
var test_user = _.template(global.environment.postgres_auth_user, { user_id: 1 });
|
2014-02-21 01:03:43 +08:00
|
|
|
var test_pubuser = global.environment.postgres.user;
|
|
|
|
var test_database = test_user + '_db';
|
|
|
|
|
2017-09-25 19:40:22 +08:00
|
|
|
let cleanUpQueryParams;
|
|
|
|
let dbConnSetup;
|
|
|
|
let authorize;
|
2018-03-12 18:52:38 +08:00
|
|
|
let setCredentials;
|
2015-09-17 00:09:39 +08:00
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
before(function () {
|
2015-09-17 00:09:39 +08:00
|
|
|
var redisPool = new RedisPool(global.environment.redis);
|
|
|
|
var mapStore = new windshaft.storage.MapStore();
|
2019-10-22 01:07:24 +08:00
|
|
|
var metadataBackend = cartodbRedis({ pool: redisPool });
|
2015-09-17 00:09:39 +08:00
|
|
|
var pgConnection = new PgConnection(metadataBackend);
|
|
|
|
var templateMaps = new TemplateMaps(redisPool);
|
2018-04-10 00:08:56 +08:00
|
|
|
var authBackend = new AuthBackend(pgConnection, metadataBackend, mapStore, templateMaps);
|
2015-09-17 00:09:39 +08:00
|
|
|
|
2017-09-25 19:40:22 +08:00
|
|
|
cleanUpQueryParams = cleanUpQueryParamsMiddleware();
|
2018-04-10 00:08:56 +08:00
|
|
|
authorize = authorizeMiddleware(authBackend);
|
2017-09-25 19:40:22 +08:00
|
|
|
dbConnSetup = dbConnSetupMiddleware(pgConnection);
|
2018-03-12 18:52:38 +08:00
|
|
|
setCredentials = credentialsMiddleware();
|
2015-09-17 00:09:39 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('can be found in server-options', function () {
|
2017-09-25 19:40:22 +08:00
|
|
|
assert.ok(_.isFunction(authorize));
|
|
|
|
assert.ok(_.isFunction(dbConnSetup));
|
|
|
|
assert.ok(_.isFunction(cleanUpQueryParams));
|
2012-07-18 17:00:24 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
function prepareRequest (req) {
|
2015-09-16 00:16:50 +08:00
|
|
|
req.profiler = {
|
2019-10-22 01:07:24 +08:00
|
|
|
done: function () {}
|
2015-09-16 00:16:50 +08:00
|
|
|
};
|
2017-10-03 23:47:57 +08:00
|
|
|
|
2017-10-03 23:58:16 +08:00
|
|
|
return req;
|
|
|
|
}
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
function prepareResponse (res) {
|
|
|
|
if (!res.locals) {
|
2017-10-03 23:47:57 +08:00
|
|
|
res.locals = {};
|
|
|
|
}
|
|
|
|
res.locals.user = 'localhost';
|
2017-10-02 18:09:19 +08:00
|
|
|
|
2018-03-06 22:26:35 +08:00
|
|
|
res.set = function () {};
|
|
|
|
|
2017-10-03 23:58:16 +08:00
|
|
|
return res;
|
2015-07-08 21:34:46 +08:00
|
|
|
}
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('cleans up request', function (done) {
|
|
|
|
var req = { headers: { host: 'localhost' }, query: { dbuser: 'hacker', dbname: 'secret' } };
|
|
|
|
var res = {};
|
|
|
|
|
|
|
|
cleanUpQueryParams(prepareRequest(req), prepareResponse(res), function (err) {
|
|
|
|
if (err) { done(err); return; }
|
|
|
|
assert.ok(_.isObject(req.query), 'request has query');
|
2019-10-22 05:33:27 +08:00
|
|
|
assert.ok(!Object.prototype.hasOwnProperty.call(req.query, 'dbuser'), 'dbuser was removed from query');
|
|
|
|
assert.ok(Object.prototype.hasOwnProperty.call(res, 'locals'), 'response has locals');
|
|
|
|
assert.ok(!Object.prototype.hasOwnProperty.call(res.locals, 'interactivity'), 'response locals do not have interactivity');
|
2019-10-22 01:07:24 +08:00
|
|
|
done();
|
|
|
|
});
|
2012-07-18 17:00:24 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('sets dbname from redis metadata', function (done) {
|
|
|
|
var req = { headers: { host: 'localhost' }, query: {} };
|
|
|
|
var res = { set: function () {} };
|
|
|
|
|
|
|
|
dbConnSetup(prepareRequest(req), prepareResponse(res), function (err) {
|
|
|
|
if (err) { done(err); return; }
|
|
|
|
assert.ok(_.isObject(req.query), 'request has query');
|
2019-10-22 05:33:27 +08:00
|
|
|
assert.ok(!Object.prototype.hasOwnProperty.call(req.query, 'dbuser'), 'dbuser was removed from query');
|
|
|
|
assert.ok(Object.prototype.hasOwnProperty.call(res, 'locals'), 'response has locals');
|
|
|
|
assert.ok(!Object.prototype.hasOwnProperty.call(res.locals, 'interactivity'), 'response locals do not have interactivity');
|
2019-10-22 01:41:03 +08:00
|
|
|
assert.strictEqual(res.locals.dbname, test_database);
|
2019-10-22 01:07:24 +08:00
|
|
|
assert.ok(res.locals.dbuser === test_pubuser, 'could inject dbuser (' + res.locals.dbuser + ')');
|
|
|
|
done();
|
|
|
|
});
|
2012-07-18 17:00:24 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('sets also dbuser for authenticated requests', function (done) {
|
2018-03-12 18:52:38 +08:00
|
|
|
var req = {
|
|
|
|
headers: {
|
|
|
|
host: 'localhost'
|
|
|
|
},
|
2018-02-08 00:14:46 +08:00
|
|
|
query: {
|
|
|
|
api_key: '1234'
|
|
|
|
}
|
|
|
|
};
|
2018-03-12 18:52:38 +08:00
|
|
|
var res = {
|
2018-02-08 00:14:46 +08:00
|
|
|
set: function () {},
|
|
|
|
locals: {
|
2018-03-12 18:52:38 +08:00
|
|
|
api_key: '1234'
|
2018-02-08 00:14:46 +08:00
|
|
|
}
|
|
|
|
};
|
2017-09-25 19:40:22 +08:00
|
|
|
|
|
|
|
// FIXME: review authorize-pgconnsetup workflow, It might we are doing authorization twice.
|
2017-10-03 23:58:16 +08:00
|
|
|
authorize(prepareRequest(req), prepareResponse(res), function (err) {
|
2017-09-25 19:40:22 +08:00
|
|
|
if (err) { done(err); return; }
|
2019-10-22 01:07:24 +08:00
|
|
|
dbConnSetup(req, res, function (err) {
|
|
|
|
if (err) { done(err); return; }
|
2017-09-25 19:40:22 +08:00
|
|
|
assert.ok(_.isObject(req.query), 'request has query');
|
2019-10-22 05:33:27 +08:00
|
|
|
assert.ok(!Object.prototype.hasOwnProperty.call(req.query, 'dbuser'), 'dbuser was removed from query');
|
|
|
|
assert.ok(Object.prototype.hasOwnProperty.call(res, 'locals'), 'response has locals');
|
|
|
|
assert.ok(!Object.prototype.hasOwnProperty.call(res.locals, 'interactivity'), 'request params do not have interactivity');
|
2019-10-22 01:41:03 +08:00
|
|
|
assert.strictEqual(res.locals.dbname, test_database);
|
|
|
|
assert.strictEqual(res.locals.dbuser, test_user);
|
2017-09-25 19:40:22 +08:00
|
|
|
|
|
|
|
req = {
|
|
|
|
headers: {
|
2019-10-22 01:07:24 +08:00
|
|
|
host: 'localhost'
|
2017-09-25 19:40:22 +08:00
|
|
|
},
|
|
|
|
query: {
|
|
|
|
map_key: '1235'
|
2017-10-02 18:28:29 +08:00
|
|
|
}
|
2017-09-25 19:40:22 +08:00
|
|
|
};
|
|
|
|
|
2017-10-09 18:27:58 +08:00
|
|
|
res = { set: function () {} };
|
2017-10-03 23:47:57 +08:00
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
dbConnSetup(prepareRequest(req), prepareResponse(res), function () {
|
2017-09-25 19:40:22 +08:00
|
|
|
// wrong key resets params to no user
|
2019-10-22 01:07:24 +08:00
|
|
|
assert.ok(res.locals.dbuser === test_pubuser, 'could inject dbuser (' + res.locals.dbuser + ')');
|
2017-09-25 19:40:22 +08:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2012-07-18 17:00:24 +08:00
|
|
|
});
|
2013-04-24 21:10:58 +08:00
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('it should remove invalid params', function (done) {
|
2017-08-04 23:30:46 +08:00
|
|
|
var config = {
|
|
|
|
version: '1.3.0'
|
|
|
|
};
|
|
|
|
var req = {
|
|
|
|
headers: {
|
2019-10-22 01:07:24 +08:00
|
|
|
host: 'localhost'
|
2017-08-04 23:30:46 +08:00
|
|
|
},
|
|
|
|
query: {
|
|
|
|
non_included: 'toberemoved',
|
|
|
|
api_key: 'test',
|
|
|
|
style: 'override',
|
|
|
|
config: config
|
2017-10-02 18:09:19 +08:00
|
|
|
}
|
2015-03-24 00:54:37 +08:00
|
|
|
};
|
2017-09-22 22:46:39 +08:00
|
|
|
var res = {};
|
2018-03-12 18:52:38 +08:00
|
|
|
|
2017-10-03 23:58:16 +08:00
|
|
|
cleanUpQueryParams(prepareRequest(req), prepareResponse(res), function (err) {
|
2019-10-22 01:07:24 +08:00
|
|
|
if (err) {
|
2017-09-22 22:46:39 +08:00
|
|
|
return done(err);
|
|
|
|
}
|
2017-09-25 19:40:22 +08:00
|
|
|
|
2019-10-22 01:52:51 +08:00
|
|
|
assert.deepStrictEqual(config, req.query.config);
|
2019-10-22 01:41:03 +08:00
|
|
|
assert.strictEqual('test', req.query.api_key);
|
|
|
|
assert.strictEqual(undefined, req.query.non_included);
|
2017-09-22 22:46:39 +08:00
|
|
|
done();
|
2013-04-24 21:10:58 +08:00
|
|
|
});
|
|
|
|
});
|
2015-03-24 00:54:37 +08:00
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
describe('Set apikey token', function () {
|
2018-02-15 19:50:42 +08:00
|
|
|
it('from query param', function (done) {
|
|
|
|
var req = {
|
|
|
|
headers: {
|
|
|
|
host: 'localhost'
|
|
|
|
},
|
|
|
|
query: {
|
2019-10-22 01:07:24 +08:00
|
|
|
api_key: '1234'
|
2018-02-15 19:50:42 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
var res = {};
|
2018-03-12 18:52:38 +08:00
|
|
|
setCredentials(prepareRequest(req), prepareResponse(res), function (err) {
|
2018-02-15 19:50:42 +08:00
|
|
|
if (err) {
|
|
|
|
return done(err);
|
|
|
|
}
|
|
|
|
var query = res.locals;
|
2018-03-12 18:52:38 +08:00
|
|
|
|
2019-10-22 01:41:03 +08:00
|
|
|
assert.strictEqual('1234', query.api_key);
|
2018-02-15 22:27:41 +08:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('from body param', function (done) {
|
|
|
|
var req = {
|
|
|
|
headers: {
|
|
|
|
host: 'localhost'
|
|
|
|
},
|
|
|
|
body: {
|
2019-10-22 01:07:24 +08:00
|
|
|
api_key: '1234'
|
2018-02-15 22:27:41 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
var res = {};
|
2018-03-12 18:52:38 +08:00
|
|
|
setCredentials(prepareRequest(req), prepareResponse(res), function (err) {
|
2018-02-15 22:27:41 +08:00
|
|
|
if (err) {
|
|
|
|
return done(err);
|
|
|
|
}
|
|
|
|
var query = res.locals;
|
|
|
|
|
2019-10-22 01:41:03 +08:00
|
|
|
assert.strictEqual('1234', query.api_key);
|
2018-02-15 22:27:41 +08:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('from http header', function (done) {
|
|
|
|
var req = {
|
|
|
|
headers: {
|
|
|
|
host: 'localhost',
|
2019-10-22 01:07:24 +08:00
|
|
|
authorization: 'Basic bG9jYWxob3N0OjEyMzQ=' // user: localhost, password: 1234
|
2018-02-15 22:27:41 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
var res = {};
|
2018-03-12 18:52:38 +08:00
|
|
|
setCredentials(prepareRequest(req), prepareResponse(res), function (err) {
|
2018-02-16 00:49:47 +08:00
|
|
|
if (err) {
|
|
|
|
return done(err);
|
|
|
|
}
|
|
|
|
var query = res.locals;
|
|
|
|
|
2019-10-22 01:41:03 +08:00
|
|
|
assert.strictEqual('1234', query.api_key);
|
2018-02-16 00:49:47 +08:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
2018-02-15 19:50:42 +08:00
|
|
|
});
|
2012-07-18 17:00:24 +08:00
|
|
|
});
|