Use authenticated middleware in query controller
This commit is contained in:
parent
114070ef96
commit
75c2d85dbb
@ -15,13 +15,14 @@ module.exports = JobController;
|
||||
|
||||
JobController.prototype.route = function (app) {
|
||||
const { base_url } = global.settings;
|
||||
const forceToBeAuthenticated = true;
|
||||
|
||||
app.post(
|
||||
`${base_url}/sql/job`,
|
||||
checkBodyPayloadSize(),
|
||||
userMiddleware(),
|
||||
credentialsMiddleware(),
|
||||
authenticatedMiddleware(this.userDatabaseService),
|
||||
authenticatedMiddleware(this.userDatabaseService, forceToBeAuthenticated),
|
||||
createJob(this.jobService),
|
||||
setServedByDBHostHeader(),
|
||||
profile(),
|
||||
@ -46,7 +47,7 @@ JobController.prototype.route = function (app) {
|
||||
`${base_url}/sql/job/:job_id`,
|
||||
userMiddleware(),
|
||||
credentialsMiddleware(),
|
||||
authenticatedMiddleware(this.userDatabaseService),
|
||||
authenticatedMiddleware(this.userDatabaseService, forceToBeAuthenticated),
|
||||
getJob(this.jobService),
|
||||
setServedByDBHostHeader(),
|
||||
profile(),
|
||||
@ -60,7 +61,7 @@ JobController.prototype.route = function (app) {
|
||||
`${base_url}/sql/job/:job_id`,
|
||||
userMiddleware(),
|
||||
credentialsMiddleware(),
|
||||
authenticatedMiddleware(this.userDatabaseService),
|
||||
authenticatedMiddleware(this.userDatabaseService, forceToBeAuthenticated),
|
||||
cancelJob(this.jobService),
|
||||
setServedByDBHostHeader(),
|
||||
profile(),
|
||||
|
@ -5,7 +5,6 @@ var step = require('step');
|
||||
var assert = require('assert');
|
||||
var PSQL = require('cartodb-psql');
|
||||
var CachedQueryTables = require('../services/cached-query-tables');
|
||||
var AuthApi = require('../auth/auth_api');
|
||||
var queryMayWrite = require('../utils/query_may_write');
|
||||
|
||||
var formats = require('../models/formats');
|
||||
@ -15,6 +14,7 @@ var getContentDisposition = require('../utils/content_disposition');
|
||||
const credentialsMiddleware = require('../middlewares/credentials');
|
||||
const userMiddleware = require('../middlewares/user');
|
||||
const errorMiddleware = require('../middlewares/error');
|
||||
const authenticatedMiddleware = require('../middlewares/authenticated-request');
|
||||
|
||||
var ONE_YEAR_IN_SECONDS = 31536000; // 1 year time to live by default
|
||||
|
||||
@ -25,17 +25,21 @@ function QueryController(userDatabaseService, tableCache, statsd_client) {
|
||||
}
|
||||
|
||||
QueryController.prototype.route = function (app) {
|
||||
const { base_url } = global.settings;
|
||||
|
||||
app.all(
|
||||
global.settings.base_url + '/sql',
|
||||
`${base_url}/sql`,
|
||||
userMiddleware(),
|
||||
credentialsMiddleware(),
|
||||
authenticatedMiddleware(this.userDatabaseService),
|
||||
this.handleQuery.bind(this),
|
||||
errorMiddleware()
|
||||
);
|
||||
app.all(
|
||||
global.settings.base_url + '/sql.:f',
|
||||
`${base_url}/sql.:f`,
|
||||
userMiddleware(),
|
||||
credentialsMiddleware(),
|
||||
authenticatedMiddleware(this.userDatabaseService),
|
||||
this.handleQuery.bind(this),
|
||||
errorMiddleware()
|
||||
);
|
||||
@ -47,7 +51,7 @@ QueryController.prototype.handleQuery = function (req, res, next) {
|
||||
// extract input
|
||||
var body = (req.body) ? req.body : {};
|
||||
// clone so don't modify req.params or req.body so oauth is not broken
|
||||
var params = _.extend({}, res.locals, req.query, body);
|
||||
var params = _.extend({}, req.query, body);
|
||||
var sql = params.q;
|
||||
var limit = parseInt(params.rows_per_page);
|
||||
var offset = parseInt(params.page);
|
||||
@ -58,11 +62,12 @@ QueryController.prototype.handleQuery = function (req, res, next) {
|
||||
var requestedFilename = params.filename;
|
||||
var filename = requestedFilename;
|
||||
var requestedSkipfields = params.skipfields;
|
||||
var cdbUsername = res.locals.user;
|
||||
|
||||
const { user: username, userDbParams: dbopts, authDbParams, userLimits } = res.locals;
|
||||
|
||||
var skipfields;
|
||||
var dp = params.dp; // decimal point digits (defaults to 6)
|
||||
var gn = "the_geom"; // TODO: read from configuration FILE
|
||||
var userLimits;
|
||||
|
||||
if ( req.profiler ) {
|
||||
req.profiler.start('sqlapi.query');
|
||||
@ -119,30 +124,20 @@ QueryController.prototype.handleQuery = function (req, res, next) {
|
||||
throw new Error("You must indicate a sql query");
|
||||
}
|
||||
|
||||
// Database options
|
||||
var dbopts = {};
|
||||
var formatter;
|
||||
|
||||
if ( req.profiler ) {
|
||||
req.profiler.done('init');
|
||||
}
|
||||
|
||||
// 1. Get user database and related parameters
|
||||
// 3. Get the list of tables affected by the query
|
||||
// 4. Setup headers
|
||||
// 5. Send formatted results back
|
||||
// 1. Get the list of tables affected by the query
|
||||
// 2. Setup headers
|
||||
// 3. Send formatted results back
|
||||
// 4. Handle error
|
||||
step(
|
||||
function getUserDBInfo() {
|
||||
self.userDatabaseService.getConnectionParams(new AuthApi(req, res, params), cdbUsername, this);
|
||||
},
|
||||
function queryExplain(err, dbParams, authDbParams, userTimeoutLimits) {
|
||||
assert.ifError(err);
|
||||
|
||||
function queryExplain() {
|
||||
var next = this;
|
||||
|
||||
dbopts = dbParams;
|
||||
userLimits = userTimeoutLimits;
|
||||
|
||||
if ( req.profiler ) {
|
||||
req.profiler.done('setDBAuth');
|
||||
}
|
||||
@ -150,6 +145,7 @@ QueryController.prototype.handleQuery = function (req, res, next) {
|
||||
checkAborted('queryExplain');
|
||||
|
||||
var pg = new PSQL(authDbParams);
|
||||
|
||||
var skipCache = !!dbopts.authenticated;
|
||||
|
||||
self.queryTables.getAffectedTablesFromQuery(pg, sql, skipCache, function(err, result) {
|
||||
@ -221,7 +217,7 @@ QueryController.prototype.handleQuery = function (req, res, next) {
|
||||
sql = new PSQL.QueryWrapper(sql).orderBy(orderBy, sortOrder).window(limit, offset).query();
|
||||
|
||||
var opts = {
|
||||
username: cdbUsername,
|
||||
username: username,
|
||||
dbopts: dbopts,
|
||||
sink: res,
|
||||
gn: gn,
|
||||
|
@ -3,28 +3,31 @@
|
||||
var _ = require('underscore');
|
||||
var AuthApi = require('../auth/auth_api');
|
||||
|
||||
function authenticatedMiddleware(userDatabaseService) {
|
||||
function authenticatedMiddleware(userDatabaseService, forceToBeAuthenticated = false) {
|
||||
return function middleware(req, res, next) {
|
||||
req.profiler.start('sqlapi.job');
|
||||
req.profiler.done('init');
|
||||
|
||||
var body = (req.body) ? req.body : {};
|
||||
// clone so don't modify req.params or req.body so oauth is not broken
|
||||
var params = _.extend({}, res.locals, req.query, body);
|
||||
const params = _.extend({}, res.locals, req.query, req.body);
|
||||
|
||||
const { user } = res.locals;
|
||||
|
||||
var authApi = new AuthApi(req, res, params);
|
||||
userDatabaseService.getConnectionParams(authApi, res.locals.user, function connectionParams(err, userDbParams) {
|
||||
userDatabaseService.getConnectionParams(authApi, user, function (err, dbParams, authDbParams, userLimits) {
|
||||
req.profiler.done('setDBAuth');
|
||||
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (!userDbParams.authenticated) {
|
||||
if (forceToBeAuthenticated && !dbParams.authenticated) {
|
||||
return next(new Error('permission denied'));
|
||||
}
|
||||
|
||||
res.locals.userDbParams = userDbParams;
|
||||
res.locals.userDbParams = dbParams;
|
||||
res.locals.authDbParams = authDbParams;
|
||||
res.locals.userLimits = userLimits;
|
||||
|
||||
next();
|
||||
});
|
||||
|
@ -29,6 +29,7 @@ describe('app-configuration', function() {
|
||||
it('GET /api/v1/sql', function(done){
|
||||
assert.response(server, {
|
||||
url: '/api/v1/sql',
|
||||
headers: {host: 'vizzuality.cartodb.com'},
|
||||
method: 'GET'
|
||||
},{
|
||||
status: 400
|
||||
|
Loading…
Reference in New Issue
Block a user