Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new approach for trust #745

Merged
merged 18 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Add: new approach to handle trust auth (urbo-deployer#868)
AlvaroVega marked this conversation as resolved.
Show resolved Hide resolved
- Fix: expandVar return a 'null' instead of null (#746)
- Fix: smtp and smpp logs (#738)
- Add: allow access entities using NGSIv2 API for non_signal rules (new setting nonSignalByAPI / PERSEO_CHECK_NON_SIGNAL_BY_API) (#549)
Expand Down
21 changes: 21 additions & 0 deletions configTrust.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

/**
* List of pre-configured trusts
*/
var configTrust = {};

configTrust.trusts = [
{
id: 'trust1',
user: 'user1',
password: 'password',
service: 'domain1'
},
{
id: 'trust2',
user: 'user2',
password: 'password2',
service: 'domain2'
}
];
18 changes: 1 addition & 17 deletions docs/API/plain_rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,23 +396,7 @@ the Perseo configuration). The `parameters` map includes the following fields:
- UPDATE: update attributes, asumming they exist (otherwise the update operation fails at CB)
- DELETE: delete attributes (or the entity itself if the attributes list is empty)
- trust: optional, trust for getting an access token from Auth Server which can be used to get to a Context Broker
behind a PEP. A trust is a way of Keystone to allow an user (trustor) delegates a role to another user (trustee) for
a subservice. Complete info could be found at:
- [Trusts concept](https://docs.openstack.org/keystone/stein/user/trusts)
- [Trusts API](https://docs.openstack.org/keystone/stein/api_curl_examples.html#post-v3-os-trust-trusts)
- [Trust token flow example](./trust_token.md)
- authentication: optional, authentication (host, port, user, password and service) configuration values that will be
used by updateAction rule (instead of default authentication defined by configuration) which will be used when a
trust token should be negotiated. i.e.:
```json
"authentication": {
"host": "ext-keystone",
"port": 5001,
"user": "mycepuser",
"password": "myceppassword",
"service": "mycepuserservice"
}
```
behind a PEP.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This modification means that authentication field is no longer supported?

In addition, the usage of the new configTrust.js file should be documented (although not sure in which .md file...)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Witch this changes authentication is used partially, just host and port.
configTrust could be documented in a newAproachTrust.md ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

configTrust.js is related with (static) configuration, so a good place would be configuration.md.

The trust_token.md should be probably also updated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc was updated by fd58e18

- service: optional, service that will be used by updateAction rule instead of current event service. In this case,
externalCBUrl or configured Orion PEP URL will be used instead of Orion URL, and then no token for auth will be
negotiated.
Expand Down
31 changes: 18 additions & 13 deletions lib/models/keystone.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,21 @@ var util = require('util'),
request = require('request'),
logger = require('logops'),
config = require('../../config'),
configTrust = require('../../configTrust'),
alarm = require('../alarm'),
errors = {};

function getToken(trust, authentication, callback) {
const host = authentication && authentication.host ? authentication.host : config.authentication.host;
const port = authentication && authentication.port ? authentication.port : config.authentication.port;
const user = authentication && authentication.user ? authentication.user : config.authentication.user;
const password =
authentication && authentication.password ? authentication.password : config.authentication.password;
const domain = authentication && authentication.service ? authentication.service : config.authentication.service;
function getToken(trust, callback) {
const host = config.authentication.host;
const port = config.authentication.port;
var trustConf = configTrust.trusts.find((item) => item.id === trust);
// check trust was found or log it
if (!trustConf) {
logger.error('Trust [%s] not found in configTrust file', trust);
callback(new errors.TokenRetrievalError(trust,
'trust not found' + trust)
);
}
var options = {
url: 'http://' + host + ':' + port + '/v3/auth/tokens',
method: 'POST',
Expand All @@ -46,23 +51,23 @@ function getToken(trust, authentication, callback) {
password: {
user: {
domain: {
name: domain
name: trustConf.service
},
name: user,
password: password
name: trustConf.user,
password: trustConf.password
}
}
},
scope: {
'OS-TRUST:trust': {
id: trust
domain: {
name: trustConf.service
}
}
}
}
};

logger.debug('retrieving token from Keystone using trust [%s]', trust);
logger.debug('retrieving token with trust [%s]', trust);

request(options, function handleResponse(error, response /*, body*/) {
if (error) {
Expand Down
8 changes: 4 additions & 4 deletions lib/models/updateAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ function getCachedToken(service, subservice, name) {
return tokens[service][subservice][name];
}

function generateToken(trust, cached, authentication) {
function generateToken(trust, cached) {
cached.generating = true;
logger.info('start generating token');
// Here we call KeyStone to generate a token, we'll entry into the event loop
keystone.getToken(trust, authentication, function(error, token) {
keystone.getToken(trust, function(error, token) {
if (!error) {
cached.token = token;
logger.info('token generated successfully');
Expand Down Expand Up @@ -498,7 +498,7 @@ function doItWithToken(action, event, version, callback) {
// v2 response using ngsijs
cached.emitter.once(newTokenEventName, newTokenListener);
if (cached.generating === false) {
generateToken(action.parameters.trust, cached, action.parameters.authentication);
generateToken(action.parameters.trust, cached);
}
} else {
return callback(error, data);
Expand All @@ -516,7 +516,7 @@ function doItWithToken(action, event, version, callback) {
cached.emitter.once(newTokenEventName, newTokenListener);
if (cached.generating === false) {
logger.debug('generating token for %s %s %s', service, subservice, ruleName);
generateToken(action.parameters.trust, cached, action.parameters.authentication);
generateToken(action.parameters.trust, cached);
}
} else if (cached.generating === true) {
// In the middle of getting a new one
Expand Down
20 changes: 0 additions & 20 deletions lib/myutils.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,19 +379,6 @@ function ruleWithContextTimedRule(rule) {
.trim();
}

function purgeRuleAuthPassword(rule) {
if (
rule &&
rule.action &&
rule.action.parameters &&
rule.action.parameters.authentication &&
rule.action.parameters.authentication.password
) {
rule.action.parameters.authentication.password = constants.OBFUSCATED_PWD;
}
return rule;
}

/**
* expandVar substitutes every variable in val (denoted as $(var}) with the value
* in mappings (as dictionary), getting the key 'var' from the object
Expand Down Expand Up @@ -495,10 +482,3 @@ module.exports.contextEPLTimedRule = contextEPLTimedRule;
* @param {Object} Object rule
*/
module.exports.ruleWithContextTimedRule = ruleWithContextTimedRule;

/**
* ruleWithContextTimedRule returns the rule with action auth password obfuscated
*
* @param {Object} Object rule
*/
module.exports.purgeRuleAuthPassword = purgeRuleAuthPassword;
2 changes: 0 additions & 2 deletions lib/routes/rulesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ function GetAllRules(req, resp) {
data = data.splice(offset, limit);
var dataPurged = [];
data.forEach(function(rule) {
rule = myutils.purgeRuleAuthPassword(rule);
dataPurged.push(rule);
});
data = dataPurged;
Expand All @@ -57,7 +56,6 @@ function GetRules(req, resp) {
};
logger.debug({}, 'getting rule %j', rule);
rules.Find(rule, function(err, data) {
data = myutils.purgeRuleAuthPassword(data);
myutils.respond(resp, err, data);
});
}
Expand Down
8 changes: 8 additions & 0 deletions test/component/auth_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ describe('Auth', function() {
action.ev.id += date.getTime();
utilsT.getConfig().authentication.host = 'localhost';
utilsT.getConfig().authentication.port = utilsT.fakeHttpServerPort;
utilsT.getConfigTrust().trusts = [
{
id: 'thisIsATriustToken',
user: 'user1',
password: 'password',
service: 'domain1'
}
];
utilsT.getConfig().orion.URL = new URL(util.format('http://localhost:%s', utilsT.fakeHttpServerPort));
updateDone.once('updated_renew', done);
updateDone.once('updated_first', function(error) {
Expand Down
6 changes: 6 additions & 0 deletions test/utils/utilsT.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var fs = require('fs'),
path = require('path'),
MongoClient = require('mongodb').MongoClient,
config = require('../../config'),
configTrust = require('../../configTrust'),
fakeServerPort = 9753,
fakeServerCode = 200,
fakeServerMessage = 'All right',
Expand Down Expand Up @@ -244,6 +245,10 @@ function getConfig() {
return config;
}

function getConfigTrust() {
return configTrust;
}

function fakeHttpServer(cb) {
var server = require('http')
.createServer(function(req, res) {
Expand Down Expand Up @@ -289,3 +294,4 @@ module.exports.setServerCallback = function(fxn) {
fakeServerCallback = fxn;
};
module.exports.getConfig = getConfig;
module.exports.getConfigTrust = getConfigTrust;