Changeset - bf1fc4c84e5f
[Not reviewed]
default
0 3 0
Søren Løvborg - 10 years ago 2015-07-14 13:59:59
kwi@kwi.dk
BaseController: enable container authentication on all pages

Previously, user had to visit the login page to log in using container
authentication; this now happens on every page load, unless user has an
existing login session.

The container authentication result is cached in session on success.
3 files changed with 85 insertions and 20 deletions:
0 comments (0 inline, 0 general)
kallithea/controllers/login.py
Show inline comments
 
@@ -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',
kallithea/lib/base.py
Show inline comments
 
@@ -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()
 

	
kallithea/tests/functional/test_admin_auth_settings.py
Show inline comments
 
@@ -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',
 
        )
0 comments (0 inline, 0 general)