Mercurial > kallithea
changeset 6562:f58ed40c9a72
auth: refactor auth plugin importing
The list of authentication plugins, configured in the database, may contain
plugins which are no longer available. Therefore directly import the plugin in
get_auth_plugins and report the ImportError to the log instead of
breaking kallithea completely.
Patch modified by Mads Kiilerich.
author | domruf <dominikruf@gmail.com> |
---|---|
date | Sun, 02 Apr 2017 13:38:08 +0200 |
parents | 7d86b9876ac9 |
children | 42bbccdec0a0 |
files | kallithea/controllers/admin/auth_settings.py kallithea/lib/auth_modules/__init__.py kallithea/lib/base.py kallithea/model/db.py |
diffstat | 4 files changed, 31 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/controllers/admin/auth_settings.py Sun Apr 02 13:38:08 2017 +0200 +++ b/kallithea/controllers/admin/auth_settings.py Sun Apr 02 13:38:08 2017 +0200 @@ -59,20 +59,20 @@ 'kallithea.lib.auth_modules.auth_crowd', 'kallithea.lib.auth_modules.auth_pam' ] - c.enabled_plugin_names = Setting.get_auth_plugins() + self.enabled_plugins = auth_modules.get_auth_plugins() + c.enabled_plugin_names = [plugin.__class__.__module__ for plugin in self.enabled_plugins] def __render(self, defaults, errors): c.defaults = {} c.plugin_settings = {} c.plugin_shortnames = {} - for module in c.enabled_plugin_names: - plugin = auth_modules.loadplugin(module) - plugin_name = plugin.name - c.plugin_shortnames[module] = plugin_name + for plugin in self.enabled_plugins: + module = plugin.__class__.__module__ + c.plugin_shortnames[module] = plugin.name c.plugin_settings[module] = plugin.plugin_settings() for v in c.plugin_settings[module]: - fullname = "auth_%s_%s" % (plugin_name, v["name"]) + fullname = "auth_%s_%s" % (plugin.name, v["name"]) if "default" in v: c.defaults[fullname] = v["default"] # Current values will be the default on the form, if there are any
--- a/kallithea/lib/auth_modules/__init__.py Sun Apr 02 13:38:08 2017 +0200 +++ b/kallithea/lib/auth_modules/__init__.py Sun Apr 02 13:38:08 2017 +0200 @@ -296,10 +296,10 @@ return user_data -def importplugin(plugin): +def loadplugin(plugin): """ - Imports and returns the authentication plugin in the module named by plugin - (e.g., plugin='kallithea.lib.auth_modules.auth_internal'). Returns the + Imports, instantiates, and returns the authentication plugin in the module named by plugin + (e.g., plugin='kallithea.lib.auth_modules.auth_internal'). Returns an instance of the KallitheaAuthPluginBase subclass on success, raises exceptions on failure. raises: @@ -329,16 +329,8 @@ if not issubclass(pluginclass, KallitheaAuthPluginBase): raise TypeError("Authentication class %s.KallitheaAuthPlugin is not " "a subclass of %s" % (plugin, KallitheaAuthPluginBase)) - return pluginclass - -def loadplugin(plugin): - """ - Loads and returns an instantiated authentication plugin. - - see: importplugin - """ - plugin = importplugin(plugin)() + plugin = pluginclass() if plugin.plugin_settings.im_func != KallitheaAuthPluginBase.plugin_settings.im_func: raise TypeError("Authentication class %s.KallitheaAuthPluginBase " "has overridden the plugin_settings method, which is " @@ -346,6 +338,19 @@ return plugin +def get_auth_plugins(): + """Return a list of instances of plugins that are available and enabled""" + auth_plugins = [] + for plugin_name in Setting.get_by_name("auth_plugins").app_settings_value: + try: + plugin = loadplugin(plugin_name) + except ImportError as e: + log.exception('Failed to load authentication module %s' % (plugin_name)) + else: + auth_plugins.append(plugin) + return auth_plugins + + def authenticate(username, password, environ=None): """ Authentication function used for access control, @@ -357,14 +362,10 @@ :returns: None if auth failed, user_data dict if auth is correct """ - auth_plugins = Setting.get_auth_plugins() + auth_plugins = get_auth_plugins() log.debug('Authentication against %s plugins', auth_plugins) - for module in auth_plugins: - try: - plugin = loadplugin(module) - except (ImportError, AttributeError, TypeError) as e: - log.error('Failed to load authentication module %s : %s' % (module, str(e))) - continue + for plugin in auth_plugins: + module = plugin.__class__.__module__ log.debug('Trying authentication using ** %s **', module) # load plugin settings from Kallithea database plugin_name = plugin.name @@ -424,10 +425,10 @@ """return list of fields that are managed by the user's auth source, usually some of 'username', 'firstname', 'lastname', 'email', 'active', 'password' """ - auth_plugins = Setting.get_auth_plugins() - for module in auth_plugins: + auth_plugins = get_auth_plugins() + for plugin in auth_plugins: + module = plugin.__class__.__module__ log.debug('testing %s (%s) with auth plugin %s', user, user.extern_type, module) - plugin = loadplugin(module) if plugin.name == user.extern_type: return plugin.get_managed_fields() log.error('no auth plugin %s found for %s', user.extern_type, user)
--- a/kallithea/lib/base.py Sun Apr 02 13:38:08 2017 +0200 +++ b/kallithea/lib/base.py Sun Apr 02 13:38:08 2017 +0200 @@ -482,8 +482,8 @@ # Authenticate by auth_container plugin (if enabled) if any( - auth_modules.importplugin(name).is_container_auth - for name in Setting.get_auth_plugins() + plugin.is_container_auth + for plugin in auth_modules.get_auth_plugins() ): try: user_info = auth_modules.authenticate('', '', request.environ)
--- a/kallithea/model/db.py Sun Apr 02 13:38:08 2017 +0200 +++ b/kallithea/model/db.py Sun Apr 02 13:38:08 2017 +0200 @@ -300,11 +300,6 @@ return settings @classmethod - def get_auth_plugins(cls, cache=False): - auth_plugins = cls.get_by_name("auth_plugins").app_settings_value - return auth_plugins - - @classmethod def get_auth_settings(cls, cache=False): ret = cls.query() \ .filter(cls.app_settings_name.startswith('auth_')).all()