changeset 1617:cf128ced8c85 beta

Improved container-based auth implementation and added support for a reverse-proxy setup (using the X-Forwarded-User header)
author Liad Shani <liadff@gmail.com>
date Wed, 26 Oct 2011 21:59:22 +0200
parents bbe3f2ba52ca
children 9353189b7675
files rhodecode/config/deployment.ini_tmpl rhodecode/lib/auth.py rhodecode/lib/base.py rhodecode/lib/middleware/simplehg.py
diffstat 4 files changed, 29 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/config/deployment.ini_tmpl	Tue Oct 25 21:17:29 2011 +0200
+++ b/rhodecode/config/deployment.ini_tmpl	Wed Oct 26 21:59:22 2011 +0200
@@ -54,6 +54,7 @@
 commit_parse_limit = 50
 use_gravatar = true
 container_auth_enabled = false
+proxypass_auth_enabled = false
 
 ####################################
 ###        CELERY CONFIG        ####
--- a/rhodecode/lib/auth.py	Tue Oct 25 21:17:29 2011 +0200
+++ b/rhodecode/lib/auth.py	Wed Oct 26 21:59:22 2011 +0200
@@ -223,6 +223,21 @@
                 pass
     return False
 
+def get_container_username(environ, cfg=config):
+    from paste.httpheaders import REMOTE_USER
+    from paste.deploy.converters import asbool
+    username = REMOTE_USER(environ)
+
+    if not username and asbool(cfg.get('proxypass_auth_enabled', False)):
+        username = environ.get('HTTP_X_FORWARDED_USER')
+
+    if username:
+        #Removing realm and domain from username
+        username = username.partition('@')[0]
+        username = username.rpartition('\\')[2]
+        log.debug('Received username %s from container', username)
+
+    return username
 
 class  AuthUser(object):
     """
@@ -238,8 +253,8 @@
 
         self.user_id = user_id
         self.api_key = None
-
-        self.username = 'None' if username is None else username
+        self.username = username
+        
         self.name = ''
         self.lastname = ''
         self.email = ''
@@ -263,10 +278,7 @@
             log.debug('Auth User lookup by USER ID %s', self.user_id)
             user_model.fill_data(self, user_id=self.user_id)
             is_user_loaded = True
-        elif self.username != 'None':
-            #Removing realm from username
-            self.username = self.username.partition('@')[0]
-
+        elif self.username:
             log.debug('Auth User lookup by USER NAME %s', self.username)
             dbuser = User.get_by_username(self.username)
             if dbuser is not None and dbuser.active:
@@ -274,6 +286,8 @@
                     setattr(self, k, v)
                 self.set_authenticated()
                 is_user_loaded = True
+                log.debug('User %s is now logged in', self.username)
+                dbuser.update_lastlogin()
 
         if not is_user_loaded:
             if self.anonymous_user.active is True:
@@ -284,6 +298,9 @@
             else:
                 self.is_authenticated = False
 
+        if not self.username:
+            self.username = 'None'
+
         log.debug('Auth User is now %s', self)
         user_model.fill_perms(self)
 
--- a/rhodecode/lib/base.py	Tue Oct 25 21:17:29 2011 +0200
+++ b/rhodecode/lib/base.py	Wed Oct 26 21:59:22 2011 +0200
@@ -8,12 +8,10 @@
 from pylons.controllers import WSGIController
 from pylons.controllers.util import redirect
 from pylons.templating import render_mako as render
-
 from paste.deploy.converters import asbool
-from paste.httpheaders import REMOTE_USER
 
 from rhodecode import __version__
-from rhodecode.lib.auth import AuthUser
+from rhodecode.lib.auth import AuthUser, get_container_username
 from rhodecode.lib.utils import get_repo_slug
 from rhodecode.model import meta
 from rhodecode.model.scm import ScmModel
@@ -47,7 +45,7 @@
             api_key = request.GET.get('api_key')
             user_id = getattr(session.get('rhodecode_user'), 'user_id', None)
             if asbool(config.get('container_auth_enabled', False)):
-                username = REMOTE_USER(environ)
+                username = get_container_username(environ)
             else:
                 username = None
 
--- a/rhodecode/lib/middleware/simplehg.py	Tue Oct 25 21:17:29 2011 +0200
+++ b/rhodecode/lib/middleware/simplehg.py	Wed Oct 26 21:59:22 2011 +0200
@@ -35,7 +35,7 @@
 from paste.httpheaders import REMOTE_USER, AUTH_TYPE
 
 from rhodecode.lib import safe_str
-from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware
+from rhodecode.lib.auth import authfunc, HasPermissionAnyMiddleware, get_container_username
 from rhodecode.lib.utils import make_ui, invalidate_cache, \
     is_valid_repo, ui_sections
 from rhodecode.model.db import User
@@ -114,7 +114,7 @@
                 # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS
                 #==============================================================
 
-                if not REMOTE_USER(environ):
+                if not get_container_username(environ, self.config):
                     self.authenticate.realm = \
                         safe_str(self.config['rhodecode_realm'])
                     result = self.authenticate(environ)
@@ -130,8 +130,7 @@
                 #==============================================================
 
                 if action in ['pull', 'push']:
-                    #Removing realm from username
-                    username = REMOTE_USER(environ).partition('@')[0]
+                    username = get_container_username(environ, self.config)
                     try:
                         user = self.__get_user(username)
                         if user is None: