def __load_defaults(self): c.available_plugins = [ 'kallithea.lib.auth_modules.auth_internal', 'kallithea.lib.auth_modules.auth_container', 'kallithea.lib.auth_modules.auth_ldap', 'kallithea.lib.auth_modules.auth_crowd', 'kallithea.lib.auth_modules.auth_pam' ] c.enabled_plugins = Setting.get_auth_plugins()
def get_managed_fields(user): """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: 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) return [] # TODO: Fail badly instead of allowing everything to be edited?
def _determine_auth_user(api_key, session_authuser): """ Create an `AuthUser` object given the API key (if any) and the value of the authuser session cookie. """ # Authenticate by API key if api_key: # when using API_KEY we are sure user exists. return AuthUser(dbuser=User.get_by_api_key(api_key), is_external_auth=True) # Authenticate by session cookie # In ancient login sessions, 'authuser' may not be a dict. # In that case, the user will have to log in again. # v0.3 and earlier included an 'is_authenticated' key; if present, # this must be True. if isinstance(session_authuser, dict) and session_authuser.get('is_authenticated', True): try: return AuthUser.from_cookie(session_authuser) except UserCreationError as e: # container auth or other auth functions that create users on # the fly can throw UserCreationError to signal issues with # user creation. Explanation should be provided in the # exception object. from kallithea.lib import helpers as h h.flash(e, 'error', logf=log.error) # Authenticate by auth_container plugin (if enabled) if any( auth_modules.importplugin(name).is_container_auth for name in Setting.get_auth_plugins() ): try: user_info = auth_modules.authenticate('', '', request.environ) except UserCreationError as e: from kallithea.lib import helpers as h h.flash(e, 'error', logf=log.error) else: if user_info is not None: username = user_info['username'] user = User.get_by_username(username, case_insensitive=True) return log_in_user(user, remember=False, is_external_auth=True) # User is anonymous return AuthUser()
def authenticate(username, password, environ=None): """ Authentication function used for access control, It tries to authenticate based on enabled authentication modules. :param username: username can be empty for container auth :param password: password can be empty for container auth :param environ: environ headers passed for container auth :returns: None if auth failed, plugin_user dict if auth is correct """ auth_plugins = Setting.get_auth_plugins() log.debug('Authentication against %s plugins' % (auth_plugins, )) for module in auth_plugins: try: plugin = loadplugin(module) except (ImportError, AttributeError, TypeError), e: raise ImportError('Failed to load authentication module %s : %s' % (module, str(e))) log.debug('Trying authentication using ** %s **' % (module, )) # load plugin settings from Kallithea database plugin_name = plugin.name plugin_settings = {} for v in plugin.plugin_settings(): conf_key = "auth_%s_%s" % (plugin_name, v["name"]) setting = Setting.get_by_name(conf_key) plugin_settings[ v["name"]] = setting.app_settings_value if setting else None log.debug('Plugin settings \n%s' % formatted_json(plugin_settings)) if not str2bool(plugin_settings["enabled"]): log.info("Authentication plugin %s is disabled, skipping for %s" % (module, username)) continue # use plugin's method of user extraction. user = plugin.get_user(username, environ=environ, settings=plugin_settings) log.debug('Plugin %s extracted user is `%s`' % (module, user)) if not plugin.accepts(user): log.debug( 'Plugin %s does not accept user `%s` for authentication' % (module, user)) continue else: log.debug('Plugin %s accepted user `%s` for authentication' % (module, user)) log.info('Authenticating user using %s plugin' % plugin.__module__) # _authenticate is a wrapper for .auth() method of plugin. # it checks if .auth() sends proper data. For KallitheaExternalAuthPlugin # it also maps users to Database and maps the attributes returned # from .auth() to Kallithea database. If this function returns data # then auth is correct. plugin_user = plugin._authenticate(user, username, password, plugin_settings, environ=environ or {}) log.debug('PLUGIN USER DATA: %s' % plugin_user) if plugin_user: log.debug('Plugin returned proper authentication data') return plugin_user # we failed to Auth because .auth() method didn't return proper the user if username: log.warning("User `%s` failed to authenticate against %s" % (username, plugin.__module__))
return htmlfill.render( render('/login.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except UserCreationError, e: # container auth or other auth functions that create users on # the fly can throw this exception signaling that there's issue # with user creation, explanation should be provided in # Exception itself h.flash(e, 'error') # check if we use container plugin, and try to login using it. auth_plugins = Setting.get_auth_plugins() if any((importplugin(name).is_container_auth for name in auth_plugins)): from kallithea.lib import auth_modules try: auth_info = auth_modules.authenticate('', '', request.environ) except UserCreationError, e: log.error(e) h.flash(e, 'error') # render login, with flash message about limit return render('/login.html') if auth_info: headers = self._store_user_in_session(auth_info.get('username')) raise HTTPFound(location=c.came_from, headers=headers) return render('/login.html')
def authenticate(username, password, environ=None): """ Authentication function used for access control, It tries to authenticate based on enabled authentication modules. :param username: username can be empty for container auth :param password: password can be empty for container auth :param environ: environ headers passed for container auth :returns: None if auth failed, user_data dict if auth is correct """ auth_plugins = Setting.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: raise ImportError('Failed to load authentication module %s : %s' % (module, str(e))) log.debug('Trying authentication using ** %s **', module) # load plugin settings from Kallithea database plugin_name = plugin.name plugin_settings = {} for v in plugin.plugin_settings(): conf_key = "auth_%s_%s" % (plugin_name, v["name"]) setting = Setting.get_by_name(conf_key) plugin_settings[v["name"]] = setting.app_settings_value if setting else None log.debug('Plugin settings \n%s', formatted_json(plugin_settings)) if not str2bool(plugin_settings["enabled"]): log.info("Authentication plugin %s is disabled, skipping for %s", module, username) continue # use plugin's method of user extraction. user = plugin.get_user(username, environ=environ, settings=plugin_settings) log.debug('Plugin %s extracted user is `%s`', module, user) if not plugin.accepts(user): log.debug('Plugin %s does not accept user `%s` for authentication', module, user) continue else: log.debug('Plugin %s accepted user `%s` for authentication', module, user) # The user might have tried to authenticate using their email address, # then the username variable wouldn't contain a valid username. # But as the plugin has accepted the user, .username field should # have a valid username, so use it for authentication purposes. if user is not None: username = user.username log.info('Authenticating user using %s plugin', plugin.__module__) # _authenticate is a wrapper for .auth() method of plugin. # it checks if .auth() sends proper data. For KallitheaExternalAuthPlugin # it also maps users to Database and maps the attributes returned # from .auth() to Kallithea database. If this function returns data # then auth is correct. user_data = plugin._authenticate(user, username, password, plugin_settings, environ=environ or {}) log.debug('PLUGIN USER DATA: %s', user_data) if user_data is not None: log.debug('Plugin returned proper authentication data') return user_data # we failed to Auth because .auth() method didn't return the user if username: log.warning("User `%s` failed to authenticate against %s", username, plugin.__module__) return None
del defaults['password'] return htmlfill.render(render('/login.html'), defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", force_defaults=False) except UserCreationError, e: # container auth or other auth functions that create users on # the fly can throw this exception signaling that there's issue # with user creation, explanation should be provided in # Exception itself h.flash(e, 'error') # check if we use container plugin, and try to login using it. auth_plugins = Setting.get_auth_plugins() if any( (importplugin(name).is_container_auth for name in auth_plugins)): from kallithea.lib import auth_modules try: auth_info = auth_modules.authenticate('', '', request.environ) except UserCreationError, e: log.error(e) h.flash(e, 'error') # render login, with flash message about limit return render('/login.html') if auth_info: headers = self._store_user_in_session( auth_info.get('username')) raise HTTPFound(location=c.came_from, headers=headers)