#!/usr/bin/python # # Copyright (C) 2013 Simo Sorce # # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from ipsilon.util import data from ipsilon.util import page from ipsilon.util import user from ipsilon.util.plugin import Plugins import cherrypy import inspect import os class LoginManagerBase(object): def __init__(self): self.name = None self.path = '/' self._config = None self._options = None self.next_login = None def get_config_desc(self): """ The configuration description is a dictionary that provides A description of the supported configuration options, as well as the default configuration option values. The key is the option name, the value is an array of 3 elements: - description - option type - default value """ return self._options def set_config(self, config): self._config = config def get_config_value(self, name): value = None if self._config: value = self._config.get(name, None) if not value: if self._options: opt = self._options.get(name, None) if opt: value = opt[2] if cherrypy.config.get('debug', False): cherrypy.log('[%s] %s: %s' % (self.name, name, value)) return value def set_config_value(self, option, value): if not self._config: self._config = dict() self._config[option] = value def redirect_to_path(self, path): base = cherrypy.config.get('base.mount', "") raise cherrypy.HTTPRedirect('%s/login/%s' % (base, path)) def auth_successful(self, username): # save ref before calling UserSession login() as it # may regenerate the session ref = '/idp' if 'referral' in cherrypy.session: ref = cherrypy.session['referral'] user.UserSession().login(username) raise cherrypy.HTTPRedirect(ref) def auth_failed(self): # Just make sure we destroy the session user.UserSession().logout(None) if self.next_login: return self.redirect_to_path(self.next_login.path) # FIXME: show an error page instead raise cherrypy.HTTPError(401) class LoginPageBase(page.Page): def __init__(self, site, mgr): super(LoginPageBase, self).__init__(site) self.lm = mgr def root(self, *args, **kwargs): raise cherrypy.HTTPError(500) class Login(page.Page): def __init__(self, *args, **kwargs): super(Login, self).__init__(*args, **kwargs) (whitelist, config) = data.Store().get_login_config() if whitelist is not None: self.plugin_whitelist = whitelist else: self.plugin_whitelist = [] self._site['login_plugins'] = dict() login_plugins = self._site['login_plugins'] login_plugins['config'] = config plugins = Plugins(path=cherrypy.config['base.dir']) (login_path, dummy_file) = os.path.split(inspect.getfile(Login)) login_plugins['available'] = plugins.get_plugins(login_path, 'LoginManager') login_plugins['enabled'] = [] prev_obj = None for item in login_plugins['available']: self._log('Login plugin available: %s' % item) if item not in self.plugin_whitelist: continue self._log('Login plugin enabled: %s' % item) login_plugins['enabled'].append(item) obj = login_plugins['available'][item] if prev_obj: prev_obj.next_login = obj else: self.first_login = obj prev_obj = obj if item in config: obj.set_config(config[item]) self.__dict__[item] = obj.get_tree(self._site) def _log(self, fact): if cherrypy.config.get('debug', False): cherrypy.log(fact) def root(self, *args, **kwargs): if self.first_login: raise cherrypy.HTTPRedirect('%s/login/%s' % (self.basepath, self.first_login.path)) return self._template('login/index.html', title='Login') class Logout(page.Page): def root(self, *args, **kwargs): user.UserSession().logout(self.user) return self._template('logout.html', title='Logout')