diff --git a/ldapcherry/__init__.py b/ldapcherry/__init__.py index a263ec7..06161b7 100644 --- a/ldapcherry/__init__.py +++ b/ldapcherry/__init__.py @@ -76,6 +76,21 @@ else: raise MissingParameter(section, key) + + def _get_groups(self, username): + ret = {} + for b in self.backends: + ret[b] = self.backends[b].get_groups(username) + return ret + + def _get_roles(self, username): + groups = self._get_groups(username) + return self.roles.get_roles(groups) + + def _is_admin(self, username): + roles = self._get_roles(username) + return self.roles.is_admin(roles['roles']) + def _check_backends(self): backends = self.backends_params.keys() for b in self.roles.get_backends(): @@ -114,6 +129,27 @@ except: raise BackendModuleInitFail(module) + + def _init_auth(self, config): + self.auth_mode = self._get_param('auth', 'auth.mode', config) + if self.auth_mode in ['and', 'or', 'none']: + pass + elif self.auth_mode == 'custom': + # load custom auth module + auth_module = self._get_param('auth', 'auth.module', config) + auth = __import__(auth_module, globals(), locals(), ['Auth'], -1) + self.auth = auth.Auth(config['auth'], cherrypy.log) + else: + raise WrongParamValue('auth.mode', 'auth', ['and', 'or', 'none', 'custom']) + + self.roles_file = self._get_param('roles', 'roles.file', config) + cherrypy.log.error( + msg = "loading roles file <%(file)s>" % { 'file': self.roles_file }, + severity = logging.DEBUG + ) + self.roles = Roles(self.roles_file) + + def _set_access_log(self, config, level): access_handler = self._get_param('global', 'log.access_handler', config, 'syslog') @@ -201,6 +237,27 @@ else: return logging.INFO + def _auth(self, user, password): + if self.auth_mode == 'none': + return {'connected': True, 'isadmin': True} + elif self.auth_mode == 'and': + ret1 = True + for b in self.backends: + ret1 = self.backends[b].auth(user, password) and ret1 + elif self.auth_mode == 'or': + ret1 = False + for b in self.backends: + ret1 = self.backends[b].auth(user, password) or ret1 + elif self.auth_mode == 'custom': + ret1 = self.auth.auth(user, password) + else: + raise Exception() + if not ret1: + return {'connected': False, 'isadmin': False} + else: + isadmin = self._is_admin(user) + return {'connected': True, 'isadmin': isadmin} + def reload(self, config = None): """ load/reload the configuration """ @@ -229,18 +286,14 @@ self.temp_login = self.temp_lookup.get_template('login.tmpl') - self.roles_file = self._get_param('roles', 'roles.file', config) - cherrypy.log.error( - msg = "loading roles file <%(file)s>" % { 'file': self.roles_file }, - severity = logging.DEBUG - ) - self.roles = Roles(self.roles_file) + self._init_auth(config) self.attributes_file = self._get_param('attributes', 'attributes.file', config) cherrypy.log.error( msg = "loading attributes file <%(file)s>" % { 'file': self.attributes_file }, severity = logging.DEBUG ) + self.attributes = Attributes(self.attributes_file) cherrypy.log.error( @@ -318,7 +371,8 @@ def login(self, login, password): """login page """ - if self.auth.check_credentials(login, password): + auth = self._auth(login, password) + if auth['connected']: message = "login success for user '%(user)s'" % { 'user': login } @@ -327,6 +381,7 @@ severity = logging.INFO ) cherrypy.session[SESSION_KEY] = cherrypy.request.login = login + cherrypy.session['isadmin'] = auth['isadmin'] raise cherrypy.HTTPRedirect("/") else: message = "login failed for user '%(user)s'" % { diff --git a/ldapcherry/exceptions.py b/ldapcherry/exceptions.py index bd612e6..27d62b4 100644 --- a/ldapcherry/exceptions.py +++ b/ldapcherry/exceptions.py @@ -5,6 +5,8 @@ # LdapCherry # Copyright (c) 2014 Carpentier Pierre-Francois +import string + class MissingParameter(Exception): def __init__(self, section, key): self.section = section @@ -69,6 +71,14 @@ self.module = module self.log = "fail to init module <%(module)s>" % {'module': module} +class WrongParamValue(Exception): + def __init__(self, param, section, possible_values): + self.possible_values = possible_values + self.section = section + self.param = param + possible_values_str = string.join(possible_values, ', ') + self.log = "wrong value for param <%(param)s> in section <%(section)s>, possible values are [%(values)s]" % {'param': param, 'section': section, 'values': possible_values_str} + class WrongAttributeType(Exception): def __init__(self, key, section, ymlfile): self.key = key