Split prepare context middleware and fix unit test

This commit is contained in:
Daniel García Aubert
2017-09-25 13:40:22 +02:00
parent 0e8fb68794
commit b236112069
12 changed files with 221 additions and 40 deletions
+1 -1
View File
@@ -9,7 +9,7 @@ var BaseController = require('./base');
var cors = require('../middleware/cors');
var userMiddleware = require('../middleware/user');
const prepareContextMiddleware = require('../middleware/prepare-context');
const prepareContextMiddleware = require('../middleware/context');
function AnalysesController(authApi, pgConnection) {
BaseController.call(this, authApi, pgConnection);
+1 -1
View File
@@ -1,6 +1,6 @@
var debug = require('debug')('windshaft:cartodb');
function BaseController(authApi, pgConnection) {
function BaseController() {
}
module.exports = BaseController;
+1 -1
View File
@@ -15,7 +15,7 @@ var MapStoreMapConfigProvider = require('../models/mapconfig/provider/map-store-
var QueryTables = require('cartodb-query-tables');
const prepareContextMiddleware = require('../middleware/prepare-context');
const prepareContextMiddleware = require('../middleware/context');
/**
* @param {AuthApi} authApi
+1 -1
View File
@@ -20,7 +20,7 @@ var NamedMapsCacheEntry = require('../cache/model/named_maps_entry');
var NamedMapMapConfigProvider = require('../models/mapconfig/provider/named-map-provider');
var CreateLayergroupMapConfigProvider = require('../models/mapconfig/provider/create-layergroup-provider');
const prepareContextMiddleware = require('../middleware/prepare-context');
const prepareContextMiddleware = require('../middleware/context');
/**
* @param {AuthApi} authApi
+1 -1
View File
@@ -9,7 +9,7 @@ var BaseController = require('./base');
var cors = require('../middleware/cors');
var userMiddleware = require('../middleware/user');
var allowQueryParams = require('../middleware/allow-query-params');
const prepareContextMiddleware = require('../middleware/prepare-context');
const prepareContextMiddleware = require('../middleware/context');
function NamedMapsController(authApi, pgConnection, namedMapProviderCache, tileBackend, previewBackend,
surrogateKeysCache, tablesExtentApi, metadataBackend) {
@@ -0,0 +1,30 @@
const _ = require('underscore');
module.exports = function authorizeMiddleware (authApi) {
return function (req, res, next) {
// bring all query values onto req.params object
_.extend(req.params, req.query);
// FIXME: Temporary hack to share data between middlewares. Express overrides req.params to
// parse url params to an object and it's performed after matching path and controller.
req.locals = {};
_.extend(req.locals, req.params);
req.profiler.done('req2params.setup');
authApi.authorize(req, (err, authorized) => {
req.profiler.done('authorize');
if (err) {
return next(err);
}
if(!authorized) {
err = new Error("Sorry, you are unauthorized (permission denied)");
err.http_status = 403;
return next(err);
}
return next();
});
};
};
@@ -0,0 +1,37 @@
const _ = require('underscore');
// Whitelist query parameters and attach format
const REQUEST_QUERY_PARAMS_WHITELIST = [
'config',
'map_key',
'api_key',
'auth_token',
'callback',
'zoom',
'lon',
'lat',
// analysis
'filters' // json
];
module.exports = function cleanUpQueryParamsMiddleware () {
return function cleanUpQueryParams (req, res, next) {
var allowedQueryParams = REQUEST_QUERY_PARAMS_WHITELIST;
if (Array.isArray(req.context.allowedQueryParams)) {
allowedQueryParams = allowedQueryParams.concat(req.context.allowedQueryParams);
}
req.query = _.pick(req.query, allowedQueryParams);
// bring all query values onto req.params object
_.extend(req.params, req.query);
// FIXME: Temporary hack to share data between middlewares. Express overrides req.params to
// parse url params to an object and it's performed after matching path and controller.
req.locals = {};
_.extend(req.locals, req.params);
next();
};
};
@@ -0,0 +1,36 @@
const _ = require('underscore');
module.exports = function dbConnSetupMiddleware(pgConnection) {
return function (req, res, next) {
const user = req.context.user;
// FIXME: this function shouldn't be able to change `req.params`. It should return an
// object with the user's conf and it should be merge with default here.
pgConnection.setDBConn(user, req.params, (err) => {
if (err) {
if (err.message && -1 !== err.message.indexOf('name not found')) {
err.http_status = 404;
}
req.profiler.done('req2params');
return next(err, req);
}
// Add default database connection parameters
// if none given
_.defaults(req.params, {
dbuser: global.environment.postgres.user,
dbpassword: global.environment.postgres.password,
dbhost: global.environment.postgres.host,
dbport: global.environment.postgres.port
});
// FIXME: Temporary hack to share data between middlewares. Express overrides req.params to
// parse url params to an object and it's performed after matching path and controller.
_.defaults(req.locals, req.params);
req.profiler.done('req2params');
next(null, req);
});
};
};
+13
View File
@@ -0,0 +1,13 @@
const cleanUpQueryParams = require('./clean-up-query-params');
const parseTokenParam = require('./parse-token-param');
const authorize = require('./authorize');
const dbConnSetup = require('./db-conn-setup');
module.exports = function prepareContextMiddleware(authApi, pgConnection) {
return [
cleanUpQueryParams(),
parseTokenParam(),
authorize(authApi),
dbConnSetup(pgConnection)
];
};
@@ -0,0 +1,47 @@
module.exports = function parseTokenParamMiddleware () {
return function parseTokenParam (req, res, next) {
// jshint maxcomplexity:7
if (!req.params.token) {
return next();
}
var user = req.context.user;
// Token might match the following patterns:
// - {user}@{tpl_id}@{token}:{cache_buster}
var tksplit = req.params.token.split(':');
req.params.token = tksplit[0];
if ( tksplit.length > 1 ) {
req.params.cache_buster= tksplit[1];
}
tksplit = req.params.token.split('@');
if ( tksplit.length > 1 ) {
req.params.signer = tksplit.shift();
if ( ! req.params.signer ) {
req.params.signer = user;
} else if ( req.params.signer !== user ) {
var err = new Error(
`Cannot use map signature of user "${req.params.signer}" on db of user "${user}"`
);
err.http_status = 403;
req.profiler.done('req2params');
return next(err);
}
// skip template hash
if (tksplit.length > 1) {
tksplit.shift();
}
req.params.token = tksplit.shift();
}
next();
};
};