Skip to content

Commit

Permalink
Merge pull request #347 from Wirecloud/feature/keyrock-v7-remove-v5
Browse files Browse the repository at this point in the history
Improve KeyRock v7 support and remove v5
  • Loading branch information
aarranz authored Oct 10, 2018
2 parents ab367d1 + a894745 commit ea11b0e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 40 deletions.
2 changes: 1 addition & 1 deletion docs/installation_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ for more information about how to install and configure such a NGSI proxy.

### Integration with the IdM GE

Create a new Application using the IdM server that is going to be linked (for example: `https://account.lab.fiware.org`). See the [KeyRock's User and Programmers Guide] for more information about how to create such an Application. Redirect URI must be: `http(s)://${wirecloud_server}/complete/fiware/`. Take note of the *Client ID* and the *Client Secret* values (those values are available in the Application details page, inside the *OAuth2 Credentials* section) as they are going to be used later.
The first thing to take into account is that this version of WireCloud is compatible with KeyRock v6 and KeyRock v7. To enable this integration, the first step is creating a new Application using the IdM server that is going to be used (for example: `https://account.lab.fiware.org`). See the [KeyRock's User and Programmers Guide] for more information about how to create such an Application. Redirect URI must be: `http(s)://${wirecloud_server}/complete/fiware/`. Take note of the *Client ID* and the *Client Secret* values (those values are available in the Application details page, inside the *OAuth2 Credentials* section) as they are going to be used later.

On the WireCloud instance:

Expand Down
21 changes: 7 additions & 14 deletions src/wirecloud/fiware/social_auth_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
field, check OAuthBackend class for details on how to extend it.
"""

from __future__ import unicode_literals

import base64
import time
from six.moves.urllib.parse import urljoin
Expand Down Expand Up @@ -61,7 +63,9 @@ def create_organizations(strategy, backend, user, response, *args, **kwargs):
social = None

if social is None:
org_name = Organization.objects.search_available_name(organization['displayName'])
# KeyRock v6 uses displayName instead of name
organization_name = organization["name"] if "name" in organization else organization['displayName']
org_name = Organization.objects.search_available_name(organization_name)
org = Organization.objects.create_organization(org_name)
social = UserSocialAuth.objects.create(user=org, uid=organization['id'])

Expand Down Expand Up @@ -123,7 +127,7 @@ def get_user_details(self, response):
'first_name': first_name,
'last_name': last_name,
'is_superuser': superuser,
'is_staff': superuser
'is_staff': superuser,
}

def request_user_info(self, access_token):
Expand All @@ -133,17 +137,6 @@ def request_user_info(self, access_token):

def user_data(self, access_token, *args, **kwargs):
data = self.request_user_info(access_token)
# Newer versions of the FIWARE IdM provides and id field with the
# username of the user. Older versions use actorId as identifier, but
# also provides a nickName field. We use nickName because it is also
# unique and provides a better way for migrating to newer versions
# of KeyRock. Store the appropiated field in username to simplify
# the rest of the code
data['username'] = data['nickName'] if 'nickName' in data else data['id']

# Something similar happens with Organizations, previous versions of the
# IdM used to provide an actorId, unify this behaviour...
for organization in data['organizations']:
organization["id"] = organization['actorId'] if 'actorId' in organization else organization['id']
data['username'] = data.get('username') if "username" in data else data.get('id')

return data
97 changes: 72 additions & 25 deletions src/wirecloud/fiware/tests/social_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ class BasicClass(object):
def __init__(self):
pass

def extra_data(self, user, uid, response, details=None, *args, **kwargs):
return {
"access_token": "access_token",
"refresh_token": "refresh_token",
"expires_in": 3600
}

def refresh_token(self, token, *args, **kwargs):
return {
"access_token": "new_access_token",
"refresh_token": "new_refresh_token",
"expires_in": 3600
}

@classmethod
def get_key_and_secret(cls):
return ('client', 'secret')
Expand All @@ -46,25 +60,24 @@ class TestSocialAuthBackend(WirecloudTestCase, TestCase):
populate = False
use_search_indexes = False

# KeyRock v6
OLD_RESPONSE = {
"schemas": ["urn:scim:schemas:core:2.0:User"],
"id": 1,
"actorId": 1,
"nickName": "demo",
"id": "demo",
"username": "demo",
"displayName": "Demo user",
"email": "[email protected]",
"roles": [{"id": 1, "name": "Manager"}, {"id": 7, "name": "Ticket manager"}],
"roles": [{"id": "1", "name": "Manager"}, {"id": "7", "name": "Ticket manager"}],
"organizations": [{
"id": 1,
"actorId": 2,
"id": "00000000000000000000000000000001",
"displayName": "Universidad Politecnica de Madrid",
"roles": [{"id": 14, "name": "Admin"}]
}]
}

NEW_RESPONSE = {
OLD_RESPONSE_NO_LAST_NAME = {
"id": "demo",
"displayName": "Demo user",
"username": "demo",
"displayName": "Demo",
"email": "[email protected]",
"roles": [{"id": "1", "name": "Manager"}, {"id": "7", "name": "Ticket manager"}],
"organizations": [{
Expand All @@ -74,21 +87,26 @@ class TestSocialAuthBackend(WirecloudTestCase, TestCase):
}]
}

RESPONSE_NO_LAST_NAME = {
"id": "demo",
# KeyRock v7
NEW_RESPONSE = {
"id": "8b0127d8-38f7-4428-b22d-31bd80bba510",
"displayName": "",
"username": "demo",
"displayName": "Demo",
"email": "[email protected]",
"roles": [{"id": "1", "name": "Manager"}, {"id": "7", "name": "Ticket manager"}],
"roles": [{"id": "4a923351-b767-4fef-bc92-4a4fa996e88e", "name": "Manager"}, {"id": "4a92as51-b54d-4fef-bc92-4a4fa996e88e", "name": "Ticket manager"}],
"organizations": [{
"id": "00000000000000000000000000000001",
"displayName": "Universidad Politecnica de Madrid",
"roles": [{"id": 14, "name": "Admin"}]
"id": "04ac28b2-54c7-46a7-a606-c62fdc4f1513",
"name": "Mi organization",
"description":"dafsdf",
"website": None,
"roles":[{"id": "4a923351-b767-4fef-bc92-4a4fa996e88e", "name":"one_role"}]
}]
}

USER_DATA = {"username": "demo", "email": "[email protected]", "fullname": "Demo user", "first_name": "Demo", "last_name": "user", "is_superuser": False, "is_staff": False}
NEW_USER_DATA = {"username": "demo", "email": "[email protected]", "fullname": "", "first_name": "", "last_name": "", "is_superuser": False, "is_staff": False}
USER_DATA_ADMIN = {"username": "demo", "email": "[email protected]", "fullname": "Demo user", "first_name": "Demo", "last_name": "user", "is_superuser": True, "is_staff": True}
NEW_USER_DATA_ADMIN = {"username": "demo", "email": "[email protected]", "fullname": "", "first_name": "", "last_name": "", "is_superuser": True, "is_staff": True}
USER_DATA_NO_LAST_NAME = {"username": "demo", "email": "[email protected]", "fullname": "Demo", "first_name": "Demo", "last_name": "", "is_superuser": False, "is_staff": False}

def setUp(self):
Expand Down Expand Up @@ -129,7 +147,7 @@ def test_get_user_data_old_version(self):
self.assertIn('username', data)
self.assertEqual(data['username'], 'demo')
self.assertIn('id', data['organizations'][0])
self.assertEqual(data['organizations'][0]['id'], 2)
self.assertEqual(data['organizations'][0]['id'], "00000000000000000000000000000001")

def test_get_user_data_new_version(self):

Expand All @@ -139,7 +157,7 @@ def test_get_user_data_new_version(self):
self.assertIn('username', data)
self.assertEqual(data['username'], 'demo')
self.assertIn('id', data['organizations'][0])
self.assertEqual(data['organizations'][0]['id'], "00000000000000000000000000000001")
self.assertEqual(data['organizations'][0]['id'], "04ac28b2-54c7-46a7-a606-c62fdc4f1513")

def test_get_user_data_invalid_response(self):

Expand All @@ -154,6 +172,20 @@ def test_auth_headers(self):
self.assertIn('Basic ', headers['Authorization'])
self.assertEqual(headers['Authorization'], 'Basic Y2xpZW50OnNlY3JldA==')

@patch("wirecloud.fiware.social_auth_backend.time.time")
def test_extra_data(self, time_mock):

time_mock.return_value = 10000

data = self.instance.extra_data("user", "uid", "response")

self.assertEqual(data, {
"access_token": "access_token",
"refresh_token": "refresh_token",
"expires_in": 3600,
"expires_on": 13600
})

def test_get_user_details_old_version(self):

response = deepcopy(self.OLD_RESPONSE)
Expand All @@ -165,33 +197,48 @@ def test_get_user_details_old_version(self):
def test_get_user_details_old_version_admin(self):

response = deepcopy(self.OLD_RESPONSE)
response['roles'][0]['name'] = 'admin'
response['roles'][0]['name'] = 'Admin'
data = self.instance.get_user_details(response)

self.assertEqual(data, self.USER_DATA_ADMIN)

def test_get_user_details_old_version_no_last_name(self):

response = deepcopy(self.OLD_RESPONSE_NO_LAST_NAME)
data = self.instance.get_user_details(response)

self.assertEqual(data, self.USER_DATA_NO_LAST_NAME)

def test_get_user_details_new_version(self):

response = deepcopy(self.NEW_RESPONSE)
response['username'] = 'demo'
data = self.instance.get_user_details(response)

self.assertEqual(data, self.USER_DATA)
self.assertEqual(data, self.NEW_USER_DATA)

def test_get_user_details_new_version_admin(self):

response = deepcopy(self.NEW_RESPONSE)
response['roles'][0]['name'] = 'Admin'
data = self.instance.get_user_details(response)

self.assertEqual(data, self.USER_DATA_ADMIN)
self.assertEqual(data, self.NEW_USER_DATA_ADMIN)

def test_get_user_details_no_last_name(self):
@patch("wirecloud.fiware.social_auth_backend.time.time")
def test_refresh_token_normalizes_token_expiration_time(self, time_mock):

response = deepcopy(self.RESPONSE_NO_LAST_NAME)
data = self.instance.get_user_details(response)
time_mock.return_value = 10000

self.assertEqual(data, self.USER_DATA_NO_LAST_NAME)
data = self.instance.refresh_token("old_access_token")

self.assertEqual(data, {
"access_token": "new_access_token",
"refresh_token": "new_refresh_token",
"expires_in": 3600,
"expires_on": 13600,
"openstack_token": None
})

def test_request_user_info(self):

Expand Down

0 comments on commit ea11b0e

Please sign in to comment.