Skip to content

Commit

Permalink
Merge 6039718 into 2e8f1f5
Browse files Browse the repository at this point in the history
  • Loading branch information
dcalvoalonso committed Mar 5, 2019
2 parents 2e8f1f5 + 6039718 commit 3324a27
Show file tree
Hide file tree
Showing 12 changed files with 439 additions and 13 deletions.
5 changes: 4 additions & 1 deletion CHANGES_NEXT_RELEASE
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ Fix: modified engine version >=6 in packages.json
Fix: update logops dependency from 1.0.8 to 2.1.0
Fix: user provider timestamp correctly propagated to mapped entities when multientity pluging is used (#748)
Add: new functions to set callbacks for removal of devices and groups (#735)
Fix: add ?type parameter in CB request updates to avoid potential entity ambiguities (#733)
Fix: add ?type parameter in CB request updates to avoid potential entity ambiguities (#733)
Add: support HTTPS requests toward Keystone (if url is used in the authorization configuration)
Add: support OAuth2 provider as authentication backend (#591)
Add: support for authentication to NGSIv1 subscription requests (#592)
20 changes: 9 additions & 11 deletions lib/services/ngsi/subscriptionService.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@

'use strict';

var request = require('request'),
errors = require('../../errors'),
var errors = require('../../errors'),
intoTrans = require('../common/domain').intoTrans,
logger = require('logops'),
config = require('../../commonConfig'),
deviceService = require('../devices/deviceService'),
context = {
op: 'IoTAgentNGSI.NGSIService'
},
Expand Down Expand Up @@ -186,8 +186,8 @@ function subscribeNgsi1(device, triggers, content, callback) {
} else {
options.uri = config.getConfig().contextBroker.url + '/v1/subscribeContext';
}

request(options, createSubscriptionHandlerNgsi1(device, triggers, store, callback));
deviceService.executeWithSecurity(options,
device, createSubscriptionHandlerNgsi1(device, triggers, store, callback));
}

/**
Expand All @@ -200,7 +200,7 @@ function subscribeNgsi1(device, triggers, content, callback) {
* @param {Object} content Array with the names of the attributes to retrieve in the notification.
*/
function subscribeNgsi2(device, triggers, content, callback) {
var options = {
var options = {
method: 'POST',
headers: {
'fiware-service': device.service,
Expand Down Expand Up @@ -248,8 +248,8 @@ function subscribeNgsi2(device, triggers, content, callback) {
} else {
options.uri = config.getConfig().contextBroker.url + '/v2/subscriptions';
}

request(options, createSubscriptionHandlerNgsi2(device, triggers, store, callback));
deviceService.executeWithSecurity(options,
device, createSubscriptionHandlerNgsi2(device, triggers, store, callback));
}

/**
Expand Down Expand Up @@ -379,8 +379,7 @@ function unsubscribeNgsi1(device, id, callback) {
} else {
options.uri = config.getConfig().contextBroker.url + '/v1/unsubscribeContext';
}

request(options, createUnsubscribeHandlerNgsi1(device, id, callback));
deviceService.executeWithSecurity(options, device, createUnsubscribeHandlerNgsi1(device, id, callback));
}

/**
Expand All @@ -405,8 +404,7 @@ function unsubscribeNgsi2(device, id, callback) {
} else {
options.uri = config.getConfig().contextBroker.url + '/v2/subscriptions/' + id;
}

request(options, createUnsubscribeHandlerNgsi2(device, id, callback));
deviceService.executeWithSecurity(options, device, createUnsubscribeHandlerNgsi2(device, id, callback));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion test/unit/examples/contextRequests/updateContext4.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@
}
],
"updateAction": "UPDATE"
}
}
19 changes: 19 additions & 0 deletions test/unit/examples/contextRequests/updateContext5.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"contextElements": [{
"type": "Light",
"isPattern": "false",
"id": "light1",
"attributes": [{
"name": "state",
"type": "Boolean",
"value": " "
},
{
"name": "dimming",
"type": "Percentage",
"value": " "
}
]
}],
"updateAction": "APPEND"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"devices": [
{
"device_id": "Light1",
"protocol": "GENERIC_PROTO",
"entity_name": "light1",
"entity_type": "Light",
"attributes": [
{
"name": "state",
"type": "Boolean"
},
{
"name": "dimming",
"type": "Percentage"
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"entities": [
{
"type": "Light",
"isPattern": "false",
"id": "light1"
}
],
"reference": "http://smartGondor.com/notify",
"duration": "P1M",
"notifyConditions": [
{
"type": "ONCHANGE",
"condValues": [
"dimming"
]
}
],
"throttling": "PT5S"
}
110 changes: 110 additions & 0 deletions test/unit/general/contextBrokerKeystoneSecurityAccess-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var iotAgentLib = require('../../../lib/fiware-iotagent-lib'),
should = require('should'),
logger = require('logops'),
nock = require('nock'),
request = require('request'),
contextBrokerMock,
keystoneMock,
iotAgentConfig = {
Expand Down Expand Up @@ -260,4 +261,113 @@ describe('Secured access to the Context Broker with Keystone', function() {
});
});

describe('When subscriptions are used on a protected Context Broker', function() {
beforeEach(function(done) {

var optionsProvision = {
url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
method: 'POST',
json: utils.readExampleFile(
'./test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice3.json'),
headers: {
'fiware-service': 'smartGondor',
'fiware-servicepath': 'electricity'
}
};

nock.cleanAll();

iotAgentLib.activate(iotAgentConfig, function() {
keystoneMock = nock('http://128.16.109.11:5000')
.post('/v3/auth/tokens',
utils.readExampleFile(
'./test/unit/examples/keystoneRequests/getTokenFromTrust.json'))
.times(3)
.reply(
201,
utils.readExampleFile('./test/unit/examples/keystoneResponses/tokenFromTrust.json'),
{
'X-Subject-Token': '12345679ABCDEF'
});


contextBrokerMock = nock('http://192.168.1.1:1026');

contextBrokerMock
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', 'electricity')
.matchHeader('X-Auth-Token', '12345679ABCDEF')
.post('/v1/updateContext',
utils.readExampleFile('./test/unit/examples/contextRequests/updateContext5.json'))
.reply(
200,
utils.readExampleFile('./test/unit/examples/contextResponses/updateContext1Success.json'));

contextBrokerMock
.post('/NGSI9/registerContext',
utils.readExampleFile('./test/unit/examples/contextAvailabilityRequests/registerNewDevice1.json'))
.reply(
200,
utils.readExampleFile(
'./test/unit/examples/contextAvailabilityResponses/registerNewDevice1Success.json'));

contextBrokerMock
.post('/v1/subscribeContext',
utils.readExampleFile(
'./test/unit/examples/subscriptionRequests/simpleSubscriptionRequest1.json'))
.matchHeader('X-Auth-Token', '12345679ABCDEF')
.reply(200,
utils.readExampleFile(
'./test/unit/examples/subscriptionResponses/simpleSubscriptionSuccess.json'));

iotAgentLib.clearAll(function() {
request(optionsProvision, function(error, result, body) {
done();
});
});
});
});

it('subscribe requests use auth header', function(done) {
iotAgentLib.getDevice('Light1', 'smartGondor', 'electricity', function(error, device) {
iotAgentLib.subscribe(device, ['dimming'], null, function(error) {
should.not.exist(error);

contextBrokerMock.done();

done();
});
});
});

it('unsubscribe requests use auth header', function(done) {

keystoneMock
.post('/v3/auth/tokens',
utils.readExampleFile('./test/unit/examples/keystoneRequests/getTokenFromTrust.json'))
.reply(
201,
utils.readExampleFile('./test/unit/examples/keystoneResponses/tokenFromTrust.json'),
{
'X-Subject-Token': '12345679ABCDEF'
});

contextBrokerMock = nock('http://192.168.1.1:1026')
.post('/v1/unsubscribeContext',
utils.readExampleFile('./test/unit/examples/subscriptionRequests/simpleSubscriptionRemove.json'))
.matchHeader('X-Auth-Token', '12345679ABCDEF')
.reply(200,
utils.readExampleFile('./test/unit/examples/subscriptionResponses/simpleSubscriptionSuccess.json'));

iotAgentLib.getDevice('Light1', 'smartGondor', 'electricity', function(error, device) {
iotAgentLib.subscribe(device, ['dimming'], null, function(error) {
iotAgentLib.unsubscribe(device, '51c0ac9ed714fb3b37d7d5a8', function(error) {
contextBrokerMock.done();
done();
});
});
});
});

});
});
105 changes: 105 additions & 0 deletions test/unit/general/contextBrokerOAuthSecurityAccess-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,111 @@ describe('Secured access to the Context Broker with OAuth2 provider', function()
});
});

describe('When subscriptions are used on a protected Context Broker', function() {
beforeEach(function(done) {

var optionsProvision = {
url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
method: 'POST',
json: utils.readExampleFile(
'./test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice3.json'),
headers: {
'fiware-service': 'smartGondor',
'fiware-servicepath': 'electricity'
}
};

nock.cleanAll();

iotAgentLib.activate(iotAgentConfig, function() {
oauth2Mock = nock('http://192.168.1.1:3000')
.post('/auth/realms/default/protocol/openid-connect/token',
utils.readExampleFile('./test/unit/examples/oauthRequests/getTokenFromTrust.json', true))
.times(3)
.reply(
201,
utils.readExampleFile('./test/unit/examples/oauthResponses/tokenFromTrust.json'),
{});


contextBrokerMock = nock('http://192.168.1.1:1026');

contextBrokerMock
.matchHeader('fiware-service', 'smartGondor')
.matchHeader('fiware-servicepath', 'electricity')
.matchHeader('Authorization', 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ3cHdWclJ3')
.post('/v1/updateContext',
utils.readExampleFile('./test/unit/examples/contextRequests/updateContext5.json'))
.reply(
200,
utils.readExampleFile('./test/unit/examples/contextResponses/updateContext1Success.json'));

contextBrokerMock
.post('/NGSI9/registerContext',
utils.readExampleFile(
'./test/unit/examples/contextAvailabilityRequests/registerNewDevice1.json'))
.reply(
200,
utils.readExampleFile(
'./test/unit/examples/contextAvailabilityResponses/registerNewDevice1Success.json'));

contextBrokerMock
.post('/v1/subscribeContext',
utils.readExampleFile(
'./test/unit/examples/subscriptionRequests/simpleSubscriptionRequest1.json'))
.matchHeader('Authorization', 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ3cHdWclJ3')
.reply(200,
utils.readExampleFile(
'./test/unit/examples/subscriptionResponses/simpleSubscriptionSuccess.json'));

iotAgentLib.clearAll(function() {
request(optionsProvision, function(error, result, body) {
done();
});
});
});
});

it('subscribe requests use auth header', function(done) {
iotAgentLib.getDevice('Light1', 'smartGondor', 'electricity', function(error, device) {
iotAgentLib.subscribe(device, ['dimming'], null, function(error) {
should.not.exist(error);

contextBrokerMock.done();

done();
});
});
});

it('unsubscribe requests use auth header', function(done) {

oauth2Mock
.post('/auth/realms/default/protocol/openid-connect/token',
utils.readExampleFile('./test/unit/examples/oauthRequests/getTokenFromTrust.json', true))
.reply(
201,
utils.readExampleFile('./test/unit/examples/oauthResponses/tokenFromTrust.json'),
{});

contextBrokerMock = nock('http://192.168.1.1:1026')
.post('/v1/unsubscribeContext',
utils.readExampleFile('./test/unit/examples/subscriptionRequests/simpleSubscriptionRemove.json'))
.matchHeader('Authorization', 'Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ3cHdWclJ3')
.reply(200,
utils.readExampleFile('./test/unit/examples/subscriptionResponses/simpleSubscriptionSuccess.json'));

iotAgentLib.getDevice('Light1', 'smartGondor', 'electricity', function(error, device) {
iotAgentLib.subscribe(device, ['dimming'], null, function(error) {
iotAgentLib.unsubscribe(device, '51c0ac9ed714fb3b37d7d5a8', function(error) {
contextBrokerMock.done();
done();
});
});
});
});

});
});

describe('Secured access to the Context Broker with OAuth2 provider (FIWARE Keyrock IDM)', function() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"dataProvided": {
"entities": [{
"type": "Light",
"id": "light1"
}],
"attrs": [
"temperature"
]
},
"provider": {
"http": {
"url": "http://smartGondor.com"
},
"legacyForwarding": true
},
"expires": "2015-09-05T07:35:01.468Z"
}
Loading

0 comments on commit 3324a27

Please sign in to comment.