X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=blobdiff_plain;f=ipsilon%2Flogin%2Fcommon.py;h=3002d7870c6e5eb6c4e0bf2a565ec3e0ccedf5ed;hp=028b7544838be1f2c3622d2ffc83335bf8206669;hb=d71af443d0178aeded3a6e65921292819f9f3b5b;hpb=0167e69a38734586c1a1f45786313efb3b5f73c3 diff --git a/ipsilon/login/common.py b/ipsilon/login/common.py old mode 100755 new mode 100644 index 028b754..3002d78 --- a/ipsilon/login/common.py +++ b/ipsilon/login/common.py @@ -1,5 +1,3 @@ -#!/usr/bin/python -# # Copyright (C) 2013 Simo Sorce # # see file 'COPYING' for use and warranty information @@ -19,8 +17,8 @@ from ipsilon.util.page import Page from ipsilon.util.user import UserSession -from ipsilon.util.plugin import PluginLoader, PluginObject -from ipsilon.util.plugin import PluginInstaller +from ipsilon.util.plugin import PluginInstaller, PluginLoader +from ipsilon.util.plugin import PluginObject, PluginConfig from ipsilon.info.common import Info from ipsilon.util.cookies import SecureCookie import cherrypy @@ -29,15 +27,15 @@ import cherrypy USERNAME_COOKIE = 'ipsilon_default_username' -class LoginManagerBase(PluginObject): +class LoginManagerBase(PluginConfig, PluginObject): - def __init__(self): - super(LoginManagerBase, self).__init__() + def __init__(self, *args): + PluginConfig.__init__(self) + PluginObject.__init__(self, *args) + self._root = None self._site = None self.path = '/' - self.next_login = None self.info = None - self.is_enabled = False def redirect_to_path(self, path): base = cherrypy.config.get('base.mount', "") @@ -46,27 +44,34 @@ class LoginManagerBase(PluginObject): def auth_successful(self, trans, username, auth_type=None, userdata=None): session = UserSession() + # merge attributes from login plugin and info plugin if self.info: - userattrs = self.info.get_user_attrs(username) - if userdata: - userdata.update(userattrs.get('userdata', {})) - else: - userdata = userattrs.get('userdata', {}) + infoattrs = self.info.get_user_attrs(username) + else: + infoattrs = dict() + + if userdata is None: + userdata = dict() - # merge groups and extras from login plugin and info plugin - userdata['groups'] = list(set(userdata.get('groups', []) + - userattrs.get('groups', []))) + if '_groups' in infoattrs: + userdata['_groups'] = list(set(userdata.get('_groups', []) + + infoattrs['_groups'])) + del infoattrs['_groups'] - userdata['extras'] = userdata.get('extras', {}) - userdata['extras'].update(userattrs.get('extras', {})) + if '_extras' in infoattrs: + userdata['_extras'] = userdata.get('_extras', {}) + userdata['_extras'].update(infoattrs['_extras']) + del infoattrs['_extras'] - self.debug("User %s attributes: %s" % (username, repr(userdata))) + userdata.update(infoattrs) + + self.debug("User %s attributes: %s" % (username, repr(userdata))) if auth_type: if userdata: - userdata.update({'auth_type': auth_type}) + userdata.update({'_auth_type': auth_type}) else: - userdata = {'auth_type': auth_type} + userdata = {'_auth_type': auth_type} # create session login including all the userdata just gathered session.login(username, userdata) @@ -93,8 +98,9 @@ class LoginManagerBase(PluginObject): def auth_failed(self, trans): # try with next module - if self.next_login: - return self.redirect_to_path(self.next_login.path) + next_login = self.next_login() + if next_login: + return self.redirect_to_path(next_login.path) # return to the caller if any session = UserSession() @@ -116,62 +122,26 @@ class LoginManagerBase(PluginObject): def get_tree(self, site): raise NotImplementedError - def enable(self, site): - if self.is_enabled: - return + def register(self, root, site): + self._root = root + self._site = site - if not self._site: - self._site = site + def next_login(self): plugins = self._site[FACILITY] + try: + idx = plugins.enabled.index(self.name) + item = plugins.enabled[idx + 1] + return plugins.available[item] + except (ValueError, IndexError): + return None - # configure self - if self.name in plugins['config']: - self.set_config(plugins['config'][self.name]) + def on_enable(self): # and add self to the root - root = plugins['root'] - root.add_subtree(self.name, self.get_tree(site)) - - # finally add self in login chain - prev_obj = None - for prev_obj in plugins['enabled']: - if prev_obj.next_login: - break - if prev_obj: - while prev_obj.next_login: - prev_obj = prev_obj.next_login - prev_obj.next_login = self - if not root.first_login: - root.first_login = self - - plugins['enabled'].append(self) - self.is_enabled = True - self._debug('Login plugin enabled: %s' % self.name) + self._root.add_subtree(self.name, self.get_tree(self._site)) # Get handle of the info plugin - self.info = root.info - - def disable(self, site): - if not self.is_enabled: - return - - plugins = self._site[FACILITY] - - # remove self from chain - root = plugins['root'] - if root.first_login == self: - root.first_login = self.next_login - elif root.first_login: - prev_obj = root.first_login - while prev_obj.next_login != self: - prev_obj = prev_obj.next_login - if prev_obj: - prev_obj.next_login = self.next_login - self.next_login = None - - plugins['enabled'].remove(self) - self.is_enabled = False - self._debug('Login plugin disabled: %s' % self.name) + self.info = self._root.info class LoginPageBase(Page): @@ -206,23 +176,26 @@ class LoginFormBase(LoginPageBase): def create_tmpl_context(self, **kwargs): next_url = None - if self.lm.next_login is not None: - next_url = '%s?%s' % (self.lm.next_login.path, + next_login = self.lm.next_login() + if next_login: + next_url = '%s?%s' % (next_login.path, self.trans.get_GET_arg()) cookie = SecureCookie(USERNAME_COOKIE) cookie.receive() username = cookie.value - if username is None: - username = '' target = None if self.trans is not None: tid = self.trans.transaction_id target = self.trans.retrieve().get('login_target') + username = self.trans.retrieve().get('login_username') if tid is None: tid = '' + if username is None: + username = '' + context = { "title": 'Login', "action": '%s/%s' % (self.basepath, self.formpage), @@ -252,31 +225,42 @@ class Login(Page): def __init__(self, *args, **kwargs): super(Login, self).__init__(*args, **kwargs) self.cancel = Cancel(*args, **kwargs) - self.first_login = None self.info = Info(self._site) - loader = PluginLoader(Login, FACILITY, 'LoginManager') - self._site[FACILITY] = loader.get_plugin_data() - plugins = self._site[FACILITY] + plugins = PluginLoader(Login, FACILITY, 'LoginManager') + plugins.get_plugin_data() + self._site[FACILITY] = plugins - available = plugins['available'].keys() + available = plugins.available.keys() self._debug('Available login managers: %s' % str(available)) - plugins['root'] = self - for item in plugins['whitelist']: - self._debug('Login plugin in whitelist: %s' % item) - if item not in plugins['available']: + for item in plugins.available: + plugin = plugins.available[item] + plugin.register(self, self._site) + + for item in plugins.enabled: + self._debug('Login plugin in enabled list: %s' % item) + if item not in plugins.available: continue - plugins['available'][item].enable(self._site) + plugins.available[item].enable() def add_subtree(self, name, page): self.__dict__[name] = page + def get_first_login(self): + plugin = None + plugins = self._site[FACILITY] + if plugins.enabled: + first = plugins.enabled[0] + plugin = plugins.available[first] + return plugin + def root(self, *args, **kwargs): - if self.first_login: + plugin = self.get_first_login() + if plugin: trans = self.get_valid_transaction('login', **kwargs) redirect = '%s/login/%s?%s' % (self.basepath, - self.first_login.path, + plugin.path, trans.get_GET_arg()) raise cherrypy.HTTPRedirect(redirect) return self._template('login/index.html', title='Login') @@ -311,5 +295,5 @@ class Cancel(Page): class LoginMgrsInstall(object): def __init__(self): - pi = PluginInstaller(LoginMgrsInstall) + pi = PluginInstaller(LoginMgrsInstall, FACILITY) self.plugins = pi.get_plugins()