diff --git a/configAccessMatch.js b/configAccessMatch.js new file mode 100644 index 0000000..ee77c92 --- /dev/null +++ b/configAccessMatch.js @@ -0,0 +1,30 @@ +'use strict'; + +/** + * List of access match + */ +var configAccessMatch = {}; + +// Activity related with a list of users +configAccessMatch.users = [ + 'cloud_admin', 'pep', +]; + +// Activity related with request which the following headers +configAccessMatch.headers = [ + { "fiware-service": "smartcity" }, + { "x-real-ip": "127.0.0.1" } +]; + +// Activity related with request including the following subpaths +configAccessMatch.subpaths = [ + '/v1', +]; + +// Activity related with request including the following strings in body +configAccessMatch.body = [ + 'legacy' +]; + + +exports.configAccessMatch = configAccessMatch; diff --git a/lib/constants.js b/lib/constants.js index 83f7107..d955013 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -32,7 +32,8 @@ var constants = { X_REAL_IP_HEADER: 'x-real-ip', CORRELATOR_HEADER: 'fiware-correlator', - GET_ROLES_PATH: '/user' + GET_ROLES_PATH: '/user', + NA: 'N/A' }; diff --git a/lib/fiware-pep-steelskin.js b/lib/fiware-pep-steelskin.js index 6be28ed..b425b81 100644 --- a/lib/fiware-pep-steelskin.js +++ b/lib/fiware-pep-steelskin.js @@ -79,9 +79,14 @@ function accountInfoError(error, req, res, next) { ' | Token=' + req.headers['x-auth-token'] + ' | Origin=' + req.connection.remoteAddress + ' | UserId=' + req.userId + + ' | ServiceId=' + req.serviceId + + ' | UserName=' + req.userName + ' | Service=' + req.service + + ' | SubServiceId=' + req.subserviceId + ' | SubService=' + req.subService + ' | Action=' + req.action + + ' | Path=' + req.path + + ' | Body=' + JSON.stringify(req.body) + ' | Date=' + new Date().toJSON()); next(error); } @@ -118,6 +123,7 @@ function setAccessLogger() { }) ] }); + proxyMiddleware.watchConfigAccessMatchFile(); } /** diff --git a/lib/middleware/proxy.js b/lib/middleware/proxy.js index 86878da..4158d90 100644 --- a/lib/middleware/proxy.js +++ b/lib/middleware/proxy.js @@ -36,8 +36,30 @@ var config = require('../../config'), 'x-auth-token' ], winston = require('winston'), + logger = require('logops'), + configAccessMatch = require('../../configAccessMatch.js').configAccessMatch, accessLogger; +const fs = require('fs'); +const configAccessMatchFilePath = './configAccessMatch.js'; + +function requireUncached(module) { + delete require.cache[require.resolve(module)]; + return require(module); +} + +function watchConfigAccessMatchFile() { + fs.watch(configAccessMatchFilePath, (event, filename) => { + logger.info('watchConfigAccessMatchFile changed by %s detected in file %s', event, filename); + try { + configAccessMatch = requireUncached('../../configAccessMatch.js').configAccessMatch; + logger.debug('reloaded configAccessMatch %j', configAccessMatch); + } catch (err) { + logger.error('Error %s reloading module: %s ', err, filename); + } + }); +} + /** * Middleware to extract the organization data from the request. * @@ -196,16 +218,51 @@ function accountInfo(req, res, next) { }); } req.fwdResponse = req.fwdResponse.on('response', function(res) { - accessLogger.info('Right Attempt' + + var accessMsg = 'Right Attempt'; + + // CHeck here MATCH file patterns: + if (req.userName in configAccessMatch.users ) { + accessMsg += ' MATCHED USER ' + req.userName; + } + for (var header of configAccessMatch.headers) { + if (Object.keys(header).includes('fiware-service')) { + if (req.service.includes(header['fiware-service'])) { + accessMsg += ' MATCHED HEADER Service ' + header['fiware-service']; + } + } else if (Object.keys(header).includes('fiware-servicepath')) { + if (req.subService.includes(header['fiware-servicepath'])) { + accessMsg += ' MATCHED HEADER SubService ' + header['fiware-servicepath']; + } + } else if (Object.keys(header).includes('x-real-ip')) { + if (req.connection.remoteAddress.includes(header['x-real-ip'])) { + accessMsg += ' MATCHED HEADER Origin ' + header['x-real-ip']; + } + } + } + for (var subpath of configAccessMatch.subpaths) { + if (req.path.includes(subpath)) { + accessMsg += ' MATCHED SUBPATH ' + subpath; + } + } + for (var text of configAccessMatch.body) { + if (JSON.stringify(req.body).includes(text)) { + accessMsg += ' MATCHED BODY ' + text; + } + } + + accessLogger.info(accessMsg + ' | ResponseStatus=' + req.fwdResponse.response.statusCode + ' | Token=' + req.headers['x-auth-token'] + ' | Origin=' + req.connection.remoteAddress + ' | UserId=' + req.userId + + ' | UserName=' + req.userName + ' | ServiceId=' + req.serviceId + ' | Service=' + req.service + ' | SubServiceId=' + req.subserviceId + ' | SubService=' + req.subService + ' | Action=' + req.action + + ' | Path=' + req.path + + ' | Body=' + JSON.stringify(req.body).slice(0, 100) + // not all body ' | Date=' + new Date().toJSON()); }); } @@ -257,3 +314,4 @@ exports.sendResponse = sendResponse; exports.accountInfo = accountInfo; exports.checkMandatoryHeaders = checkMandatoryHeaders(validationHeaders); exports.checkAuthorizationHeader = checkMandatoryHeaders(authorizationHeaders); +exports.watchConfigAccessMatchFile = watchConfigAccessMatchFile; diff --git a/lib/services/keystoneAuth.js b/lib/services/keystoneAuth.js index a695d67..f95f813 100644 --- a/lib/services/keystoneAuth.js +++ b/lib/services/keystoneAuth.js @@ -191,6 +191,7 @@ function retrieveUser(req, callback) { req.serviceId = cachedValue.serviceId; req.domainName = cachedValue.domainName; req.userId = cachedValue.userId; + req.userName = cachedValue.userName; logger.debug('User value processed with value: %j', cachedValue); @@ -245,9 +246,12 @@ function retrieveUser(req, callback) { cachedValue = { domainName: body.token.project.domain.name, serviceId: body.token.project.domain.id, - userId: body.token['OS-TRUST:trust'].trustor_user.id + userId: body.token['OS-TRUST:trust'].trustor_user.id, + userName: constants.NA }; - + if (body.token.user) { + cachedValue.userName = body.token.user.name; + } innerCb(null, cachedValue); } else if (body.token && body.token.user && body.token.user.domain && @@ -256,7 +260,8 @@ function retrieveUser(req, callback) { cachedValue = { domainName: body.token.user.domain.name, serviceId: body.token.user.domain.id, - userId: body.token.user.id + userId: body.token.user.id, + userName: body.token.user.name }; req.userData = cachedValue;