diff --git a/ckanext/ozwillo_pyoidc/plugin.py b/ckanext/ozwillo_pyoidc/plugin.py index 2c0cf4d..d4b6123 100755 --- a/ckanext/ozwillo_pyoidc/plugin.py +++ b/ckanext/ozwillo_pyoidc/plugin.py @@ -1,62 +1,75 @@ import logging +import conf import ckan.plugins as plugins import ckan.plugins.toolkit as toolkit -from ckan.common import session +from ckan.common import session, c, request +from ckan import model import ckan.lib.base as base from pylons import config, request from oidc import OIDCClients -import conf - -from oic.oic import Client, AuthorizationRequest -from oic.utils.authn.client import CLIENT_AUTHN_METHOD - plugin_config_prefix = 'ckanext.ozwillo_pyoidc.' log = logging.getLogger(__name__) +plugin_controller = 'ckanext.ozwillo_pyoidc.plugin:OpenidController' -Client = OIDCClients(conf)['ozwillo'] - -def openid_callback(context, data): - print context - print data +CLIENT = None class OzwilloPyoidcPlugin(plugins.SingletonPlugin): plugins.implements(plugins.IConfigurer) plugins.implements(plugins.IRoutes) plugins.implements(plugins.IAuthenticator, inherit=True) - def __init__(self, name=None): - self.client = Client - def before_map(self, map): - map.redirect('/organization/{id:.*}/sso', '/user/login') - map.connect('/openid/callback', - controller='ckanext.ozwillo_pyoidc.plugin:OpenidController', - action='openid_callback') + map.connect('/organization/{id:.*}/sso', + controller=plugin_controller, + action='sso') + map.connect('/organization/{id:.*}/callback', + controller=plugin_controller, + action='callback') return map def after_map(self, map): return map def identify(self): - # must set toolkit.c.user - pass + user = session.get('user') + if user and not toolkit.c.userobj: + userobj = model.User.get(user) + toolkit.c.user = userobj.name + toolkit.c.userobj = userobj def login(self): - url, ht_args = self.client.create_authn_request(session, conf.ACR_VALUES) - if ht_args: - toolkit.request.headers.update(ht_args) - toolkit.redirect_to(url) + global CLIENT + if 'organization_id' in session: + g = model.Group.get(session['organization_id']) + conf.CLIENTS['ozwillo']['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 = OIDCClients(conf)['ozwillo'] + url, ht_args = CLIENT.create_authn_request(session, conf.ACR_VALUES) + if ht_args: + toolkit.request.headers.update(ht_args) + toolkit.redirect_to(url) + else: + toolkit.redirect_to('/') def logout(self): # revoke all auth tokens # redirect to logout in ozwillo - revoke_endpoint = 'https://portal.ozwillo-preprod.eu/a/revoke' - toolkit.redirect('/user/_logout') + # revoke_endpoint = 'https://portal.ozwillo-preprod.eu/a/revoke' + # toolkit.redirect('/user/_logout') + pass def update_config(self, config_): toolkit.add_template_directory(config_, 'templates') @@ -65,6 +78,36 @@ class OzwilloPyoidcPlugin(plugins.SingletonPlugin): class OpenidController(base.BaseController): - def openid_callback(self): - userinfo = Client.callback(request.GET) - return "userinfo: %s" % userinfo + def sso(self, id): + log.info('SSO for organization "%s"' % id) + session['organization_id'] = id + session.save() + log.info('redirecting to login page') + login_url = toolkit.url_for(host=request.host, + controller='user', + action='login', + qualified=True) + 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() + + org_url = toolkit.url_for(host=request.host, + controller="organization", + action='read', + id=session['organization_id'], + qualified=True) + toolkit.redirect_to(org_url)