diff --git a/kallithea/controllers/login.py b/kallithea/controllers/login.py --- a/kallithea/controllers/login.py +++ b/kallithea/controllers/login.py @@ -38,7 +38,6 @@ from pylons import request, session, tmp import kallithea.lib.helpers as h from kallithea.lib.auth import AuthUser, HasPermissionAnyDecorator -from kallithea.lib.auth_modules import importplugin from kallithea.lib.base import BaseController, log_in_user, render from kallithea.lib.exceptions import UserCreationError from kallithea.lib.utils2 import safe_str @@ -120,24 +119,6 @@ class LoginController(BaseController): log_in_user(user, c.form_result['remember']) return self._redirect_to_origin(c.came_from) - # 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: - username = auth_info.get('username') - user = User.get_by_username(username, case_insensitive=True) - log_in_user(user, remember=False) - return self._redirect_to_origin(c.came_from) - return render('/login.html') @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate', diff --git a/kallithea/lib/base.py b/kallithea/lib/base.py --- a/kallithea/lib/base.py +++ b/kallithea/lib/base.py @@ -109,6 +109,8 @@ def log_in_user(user, remember): Log a `User` in and update session and cookies. If `remember` is True, the session cookie is set to expire in a year; otherwise, it expires at the end of the browser session. + + Returns populated `AuthUser` object. """ user.update_lastlogin() meta.Session().commit() @@ -134,6 +136,8 @@ def log_in_user(user, remember): # dumps session attrs back to cookie session._update_cookie_out() + return auth_user + class BasicAuth(paste.auth.basic.AuthBasicAuthenticator): @@ -395,7 +399,7 @@ class BaseController(WSGIController): # user creation. Explanation should be provided in the # exception object. from kallithea.lib import helpers as h - h.flash(e, 'error') + h.flash(e, 'error', logf=log.error) else: authenticated = cookie_store.get('is_authenticated') @@ -405,6 +409,22 @@ class BaseController(WSGIController): return auth_user + # Authenticate by auth_container plugin (if enabled) + if any( + auth_modules.importplugin(name).is_container_auth + for name in Setting.get_auth_plugins() + ): + try: + auth_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 auth_info: + username = auth_info['username'] + user = User.get_by_username(username, case_insensitive=True) + return log_in_user(user, remember=False) + # User is anonymous return AuthUser() diff --git a/kallithea/tests/functional/test_admin_auth_settings.py b/kallithea/tests/functional/test_admin_auth_settings.py --- a/kallithea/tests/functional/test_admin_auth_settings.py +++ b/kallithea/tests/functional/test_admin_auth_settings.py @@ -111,3 +111,67 @@ class TestAuthSettingsController(TestCon def test_ldap_login_incorrect(self): pass + + def _container_auth_setup(self, **settings): + self.log_user() + + params = self._enable_plugins('kallithea.lib.auth_modules.auth_internal,kallithea.lib.auth_modules.auth_container') + params.update(settings) + + test_url = url(controller='admin/auth_settings', + action='auth_settings') + + response = self.app.post(url=test_url, params=params) + response = response.follow() + response.click('Log Out') # end admin login session + + def _container_auth_verify_login(self, resulting_username, **get_kwargs): + response = self.app.get( + url=url(controller='admin/my_account', action='my_account'), + **get_kwargs + ) + response.mustcontain('My Account %s' % resulting_username) + + def test_container_auth_login_header(self): + self._container_auth_setup( + auth_container_header='THE_USER_NAME', + auth_container_fallback_header='', + auth_container_clean_username='False', + ) + self._container_auth_verify_login( + extra_environ={'THE_USER_NAME': 'john@example.org'}, + resulting_username='john@example.org', + ) + + def test_container_auth_login_fallback_header(self): + self._container_auth_setup( + auth_container_header='THE_USER_NAME', + auth_container_fallback_header='HTTP_X_YZZY', + auth_container_clean_username='False', + ) + self._container_auth_verify_login( + headers={'X-Yzzy': r'foo\bar'}, + resulting_username=r'foo\bar', + ) + + def test_container_auth_clean_username_at(self): + self._container_auth_setup( + auth_container_header='REMOTE_USER', + auth_container_fallback_header='', + auth_container_clean_username='True', + ) + self._container_auth_verify_login( + extra_environ={'REMOTE_USER': 'john@example.org'}, + resulting_username='john', + ) + + def test_container_auth_clean_username_backslash(self): + self._container_auth_setup( + auth_container_header='REMOTE_USER', + auth_container_fallback_header='', + auth_container_clean_username='True', + ) + self._container_auth_verify_login( + extra_environ={'REMOTE_USER': r'example\jane'}, + resulting_username=r'jane', + )