1
0
Fork 0

Add req.trustProxy, req.arangoUser, req.arangoVersion

This commit is contained in:
Alan Plum 2016-06-15 17:10:07 +02:00
parent 59340a570c
commit 4b65779cc4
No known key found for this signature in database
GPG Key ID: 8ED72A9A323B6EFD
7 changed files with 83 additions and 60 deletions

View File

@ -25,12 +25,10 @@
////////////////////////////////////////////////////////////////////////////////
const joi = require('joi');
const Netmask = require('netmask').Netmask;
const dd = require('dedent');
const internal = require('internal');
const db = require('@arangodb').db;
const errors = require('@arangodb').errors;
const joinPath = require('path').posix.join;
const notifications = require('@arangodb/configuration').notifications;
const examples = require('@arangodb/graph-examples/example-graph');
const createRouter = require('@arangodb/foxx/router');
@ -44,50 +42,22 @@ API_DOCS.basePath = `/_db/${encodeURIComponent(db._name())}`;
const router = createRouter();
module.exports = router;
let trustedProxies = TRUSTED_PROXIES();
let trustedProxyBlocks;
if (Array.isArray(trustedProxies)) {
trustedProxyBlocks = [];
trustedProxies.forEach(trustedProxy => {
try {
trustedProxyBlocks.push(new Netmask(trustedProxy));
} catch (e) {
console.warn("Error parsing trusted proxy " + trustedProxy, e);
}
});
} else {
trustedProxyBlocks = null;
}
let isTrustedProxy = function(proxyAddress) {
if (trustedProxies === null) {
return true;
}
return trustedProxyBlocks.some(block => {
return block.contains(proxyAddress);
});
}
router.get('/config.js', function(req, res) {
let basePath = '';
if (req.headers.hasOwnProperty('x-forwarded-for')
&& req.headers.hasOwnProperty('x-script-name')
&& isTrustedProxy(req.remoteAddress)) {
basePath = req.headers['x-script-name'];
}
res.set('content-type', 'text/javascript');
res.send("var frontendConfig = " + JSON.stringify({
"basePath": basePath,
"db": req.database,
"authenticationEnabled": global.AUTHENTICATION_ENABLED(),
"isCluster": cluster.isCluster()
}));
});
const scriptName = req.get('x-script-name');
const basePath = req.trustProxy && scriptName || '';
res.send(
`var frontendConfig = ${JSON.stringify({
basePath: basePath,
db: req.database,
authenticationEnabled: internal.authenticationEnabled(),
isCluster: cluster.isCluster()
})}`
);
})
.response(['text/javascript']);
router.get('/whoAmI', function(req, res) {
res.json({user: req.user || null});
res.json({user: req.arangoUser || null});
})
.summary('Return the current user')
.description(dd`
@ -100,8 +70,8 @@ const authRouter = createRouter();
router.use(authRouter);
authRouter.use((req, res, next) => {
if (global.AUTHENTICATION_ENABLED()) {
if (!req.user) {
if (internal.authenticationEnabled()) {
if (!req.arangoUser) {
res.throw('unauthorized');
}
}

View File

@ -24,7 +24,7 @@
/// @author Alan Plum
////////////////////////////////////////////////////////////////////////////////
const dd = require('dedent');
const internal = require('internal');
const cluster = require('@arangodb/cluster');
const createRouter = require('@arangodb/foxx/router');
@ -33,8 +33,8 @@ module.exports = router;
router.use((req, res, next) => {
if (global.AUTHENTICATION_ENABLED()) {
if (!req.user) {
if (internal.authenticationEnabled()) {
if (!req.arangoUser) {
res.throw('unauthorized');
}
}

View File

@ -27,6 +27,7 @@
const fs = require('fs');
const joi = require('joi');
const dd = require('dedent');
const internal = require('internal');
const marked = require('marked');
const highlightAuto = require('highlight.js').highlightAuto;
const errors = require('@arangodb').errors;
@ -43,8 +44,8 @@ anonymousRouter.use(router);
module.exports = anonymousRouter;
router.use((req, res, next) => {
if (global.AUTHENTICATION_ENABLED()) {
if (!req.user) {
if (internal.authenticationEnabled()) {
if (!req.arangoUser) {
res.throw('unauthorized');
}
}

View File

@ -22,11 +22,6 @@
/// @author Alan Plum
////////////////////////////////////////////////////////////////////////////////
module.context.use(function (req, res, next) {
// Expose internal request user
req.user = req._raw.user;
next();
});
module.context.use(require('./aardvark'));
module.context.use('/foxxes', require('./foxxes'));
module.context.use('/cluster', require('./cluster'));

View File

@ -1,4 +1,4 @@
/*global ArangoServerState, ArangoClusterInfo, ArangoClusterComm*/
/*global ArangoServerState, ArangoClusterComm*/
'use strict';
////////////////////////////////////////////////////////////////////////////////
@ -397,8 +397,8 @@ function computeStatisticsLong (attrs, clusterId) {
router.use((req, res, next) => {
if (global.AUTHENTICATION_ENABLED()) {
if (!req.user) {
if (internal.authenticationEnabled()) {
if (!req.arangoUser) {
throw new httperr.Unauthorized();
}
}

View File

@ -1735,6 +1735,26 @@ if (typeof ENV !== 'undefined') {
delete global.ENV;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief trustedProxies
////////////////////////////////////////////////////////////////////////////////
if (typeof TRUSTED_PROXIES !== 'undefined') {
exports.trustedProxies = new global.TRUSTED_PROXIES();
delete global.TRUSTED_PROXIES;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief authenticationEnabled
////////////////////////////////////////////////////////////////////////////////
if (typeof AUTHENTICATION_ENABLED !== 'undefined') {
exports.authenticationEnabled = new global.AUTHENTICATION_ENABLED();
delete global.AUTHENTICATION_ENABLED;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief options
////////////////////////////////////////////////////////////////////////////////

View File

@ -31,6 +31,29 @@ const parseRange = require('range-parser');
const querystring = require('querystring');
const getRawBodyBuffer = require('internal').rawRequestBody;
const crypto = require('@arangodb/crypto');
const Netmask = require('netmask').Netmask;
const trustedProxies = require('internal').trustedProxies();
const trustedProxyBlocks = [];
if (Array.isArray(trustedProxies)) {
for (const trustedProxy of trustedProxies) {
try {
trustedProxyBlocks.push(new Netmask(trustedProxy));
} catch (e) {
console.warnLines(
`Error parsing trusted proxy "${trustedProxy}":\n${e.stack}`
);
}
}
}
function shouldTrustProxy(address) {
if (trustedProxies === null) {
return true;
}
return trustedProxyBlocks
.some((block) => block.contains(address));
}
module.exports = class SyntheticRequest {
@ -46,12 +69,18 @@ module.exports = class SyntheticRequest {
this.body = getRawBodyBuffer(req);
this.rawBody = this.body;
const server = extractServer(req, context.trustProxy);
this.trustProxy = (
typeof context.trustProxy === 'boolean'
? context.trustProxy
: shouldTrustProxy(req.client.address)
);
const server = extractServer(req, this.trustProxy);
this.protocol = server.protocol;
this.hostname = server.hostname;
this.port = server.port;
const client = extractClient(req, context.trustProxy);
const client = extractClient(req, this.trustProxy);
this.remoteAddress = client.ip;
this.remoteAddresses = client.ips;
this.remotePort = client.port;
@ -146,6 +175,14 @@ module.exports = class SyntheticRequest {
// idiosyncratic
get arangoUser() {
return this._raw.user;
}
get arangoVersion() {
return this._raw.compatibility;
}
get database() {
return this._raw.database;
}