From b699aa4449862ebc54016f6222025e5a89804594 Mon Sep 17 00:00:00 2001 From: Serghei MIHAI Date: Tue, 10 Feb 2015 11:32:23 +0100 Subject: [PATCH] OIDC client computed for each organization --- ckanext/ozwillo_pyoidc/plugin.py | 93 ++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 39 deletions(-) diff --git a/ckanext/ozwillo_pyoidc/plugin.py b/ckanext/ozwillo_pyoidc/plugin.py index 00b9129..e54d04b 100755 --- a/ckanext/ozwillo_pyoidc/plugin.py +++ b/ckanext/ozwillo_pyoidc/plugin.py @@ -17,7 +17,32 @@ plugin_config_prefix = 'ckanext.ozwillo_pyoidc.' log = logging.getLogger(__name__) plugin_controller = 'ckanext.ozwillo_pyoidc.plugin:OpenidController' -CLIENT = None +_CLIENTS = {} + +class Clients(object): + + @classmethod + def get(cls, g): + global _CLIENTS + if g.id in _CLIENTS: + return _CLIENTS.get(g.id) + client = cls().get_client(g) + _CLIENTS.update({g.id: client}) + return client + + def get_client(self, g): + params = conf.CLIENT.copy() + params['client_registration'].update({ + 'client_id': g._extras['client_id'].value, + 'client_secret': g._extras['client_secret'].value, + 'redirect_uris': [toolkit.url_for(host=request.host, + controller=plugin_controller, + action='callback', + id=g.name, + qualified=True)] + }) + return create_client(**params) + class OzwilloPyoidcPlugin(plugins.SingletonPlugin): plugins.implements(plugins.IConfigurer) @@ -49,21 +74,10 @@ class OzwilloPyoidcPlugin(plugins.SingletonPlugin): toolkit.c.userobj = userobj def login(self): - global CLIENT if 'organization_id' in session: g = model.Group.get(session['organization_id']) - conf.CLIENT['client_registration'].update({ - 'client_id': g._extras['client_id'].value, - 'client_secret': g._extras['client_secret'].value, - 'redirect_uris': [toolkit.url_for(host=request.host, - controller=plugin_controller, - action='callback', - id=g.name, - qualified=True)] - }) - log.info('registration info for organization "%s" set' % g.name) - CLIENT = create_client(**conf.CLIENT) - url, ht_args = CLIENT.create_authn_request(session, conf.ACR_VALUES) + client = Clients.get(g) + url, ht_args = client.create_authn_request(session, conf.ACR_VALUES) if ht_args: toolkit.request.headers.update(ht_args) toolkit.redirect_to(url) @@ -92,34 +106,35 @@ class OpenidController(base.BaseController): toolkit.redirect_to(login_url) def callback(self): - global CLIENT - if CLIENT: - userinfo = CLIENT.callback(request.GET) - log.info('Received userinfo: %s' % userinfo) - userobj = model.User.get(userinfo['nickname']) - if userobj: - userobj.email = userinfo['email'] - if 'given_name' in userinfo: - userobj.fullname = userinfo['given_name'] - if 'family_name' in userinfo: - userobj.fullname += userinfo['family_name'] - userobj.save() - session['user'] = userobj.id - session.save() + g = model.Group.get(session['organization_id']) + client = Clients.get(g) + userinfo = client.callback(request.GET) + log.info('Received userinfo: %s' % userinfo) + userobj = model.User.get(userinfo['nickname']) + if userobj: + userobj.email = userinfo['email'] + if 'given_name' in userinfo: + userobj.fullname = userinfo['given_name'] + if 'family_name' in userinfo: + userobj.fullname += userinfo['family_name'] + userobj.save() + session['user'] = userobj.id + session.save() - org_url = toolkit.url_for(host=request.host, - controller="organization", - action='read', - id=session['organization_id'], - qualified=True) - toolkit.redirect_to(org_url) + org_url = toolkit.url_for(host=request.host, + controller="organization", + action='read', + id=g.id, + qualified=True) + toolkit.redirect_to(org_url) def slo(self): """ Revokes the delivered access token. Logs out the user """ - global CLIENT - logout_url = CLIENT.end_session_endpoint + g = model.Group.get(session['organization_id']) + client = Clients.get(g) + logout_url = client.end_session_endpoint org_url = toolkit.url_for(host=request.host, controller='organization', action='read', @@ -129,11 +144,11 @@ class OpenidController(base.BaseController): # revoke the access token headers = {'Content-Type': 'application/x-www-form-urlencoded'} - data = 'token=%s&token_type_hint=access_token' % CLIENT.access_token - CLIENT.http_request(CLIENT.revocation_endpoint, 'POST', + data = 'token=%s&token_type_hint=access_token' % client.access_token + client.http_request(client.revocation_endpoint, 'POST', data=data, headers=headers) # redirect to IDP logout - logout_url += '?id_token_hint=%s&' % CLIENT.id_token + logout_url += '?id_token_hint=%s&' % client.id_token logout_url += 'post_logout_redirect_uri=%s' % redirect_uri toolkit.redirect_to(str(logout_url))