2018-02-19 21:41:06 +08:00
|
|
|
const AuthApi = require('../auth/auth_api');
|
2018-02-19 22:44:28 +08:00
|
|
|
const basicAuth = require('basic-auth');
|
2016-10-04 21:40:56 +08:00
|
|
|
|
2018-06-05 19:16:36 +08:00
|
|
|
module.exports = function authorization (metadataBackend, forceToBeMaster = false) {
|
2018-02-19 22:54:05 +08:00
|
|
|
return function authorizationMiddleware (req, res, next) {
|
2018-02-19 20:24:44 +08:00
|
|
|
const { user } = res.locals;
|
2018-02-19 23:04:57 +08:00
|
|
|
const credentials = getCredentialsFromRequest(req);
|
2018-02-19 22:44:28 +08:00
|
|
|
|
|
|
|
if (!userMatches(credentials, user)) {
|
2018-02-27 20:56:00 +08:00
|
|
|
if (req.profiler) {
|
|
|
|
req.profiler.done('authorization');
|
|
|
|
}
|
|
|
|
|
2018-02-19 22:44:28 +08:00
|
|
|
return next(new Error('permission denied'));
|
|
|
|
}
|
|
|
|
|
|
|
|
res.locals.api_key = credentials.apiKeyToken;
|
|
|
|
|
2018-02-22 18:46:34 +08:00
|
|
|
const params = Object.assign({ metadataBackend }, res.locals, req.query, req.body);
|
2018-02-20 02:16:33 +08:00
|
|
|
const authApi = new AuthApi(req, params);
|
2016-10-04 21:40:56 +08:00
|
|
|
|
2018-06-05 19:21:56 +08:00
|
|
|
authApi.verifyCredentials(function (err, authorizationLevel) {
|
2018-02-22 19:22:39 +08:00
|
|
|
if (req.profiler) {
|
2018-02-27 20:56:00 +08:00
|
|
|
req.profiler.done('authorization');
|
2018-02-22 19:22:39 +08:00
|
|
|
}
|
|
|
|
|
2016-10-04 21:40:56 +08:00
|
|
|
if (err) {
|
2018-02-17 01:21:06 +08:00
|
|
|
return next(err);
|
2016-10-04 21:40:56 +08:00
|
|
|
}
|
|
|
|
|
2018-06-05 19:21:56 +08:00
|
|
|
res.locals.authorizationLevel = authorizationLevel;
|
2018-02-22 18:46:34 +08:00
|
|
|
|
2018-06-05 19:21:56 +08:00
|
|
|
if (forceToBeMaster && authorizationLevel !== 'master') {
|
2018-02-17 01:21:06 +08:00
|
|
|
return next(new Error('permission denied'));
|
2016-10-04 21:40:56 +08:00
|
|
|
}
|
|
|
|
|
2018-03-13 18:59:07 +08:00
|
|
|
res.set('vary', 'Authorization'); //Honor Authorization header when caching.
|
|
|
|
|
2018-02-22 19:22:39 +08:00
|
|
|
next();
|
2016-10-04 21:40:56 +08:00
|
|
|
});
|
|
|
|
};
|
2018-02-19 21:20:09 +08:00
|
|
|
};
|
2018-02-19 22:44:28 +08:00
|
|
|
|
|
|
|
const credentialsGetters = [
|
|
|
|
getCredentialsFromHeaderAuthorization,
|
|
|
|
getCredentialsFromRequestQueryString,
|
|
|
|
getCredentialsFromRequestBody,
|
|
|
|
];
|
|
|
|
|
|
|
|
function getCredentialsFromRequest (req) {
|
|
|
|
let credentials = null;
|
|
|
|
|
|
|
|
for (var getter of credentialsGetters) {
|
|
|
|
credentials = getter(req);
|
|
|
|
|
|
|
|
if (apiKeyTokenFound(credentials)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return credentials;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCredentialsFromHeaderAuthorization(req) {
|
|
|
|
const { pass, name } = basicAuth(req) || {};
|
|
|
|
|
|
|
|
if (pass !== undefined && name !== undefined) {
|
|
|
|
return {
|
|
|
|
apiKeyToken: pass,
|
|
|
|
user: name
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCredentialsFromRequestQueryString(req) {
|
|
|
|
if (req.query.api_key) {
|
|
|
|
return {
|
|
|
|
apiKeyToken: req.query.api_key
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req.query.map_key) {
|
|
|
|
return {
|
|
|
|
apiKeyToken: req.query.map_key
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getCredentialsFromRequestBody(req) {
|
|
|
|
if (req.body && req.body.api_key) {
|
|
|
|
return {
|
|
|
|
apiKeyToken: req.body.api_key
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req.body && req.body.map_key) {
|
|
|
|
return {
|
|
|
|
apiKeyToken: req.body.map_key
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function apiKeyTokenFound(credentials) {
|
|
|
|
if (typeof credentials === 'boolean') {
|
|
|
|
return credentials;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (credentials.apiKeyToken !== undefined) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function userMatches (credentials, user) {
|
|
|
|
return !(credentials.user !== undefined && credentials.user !== user);
|
|
|
|
}
|