changeset 761:56c2850a5b5f beta

ldap auth rewrite, moved split authfunc into two functions, made ldap case insensitive for uids added some extra debug messages for ldap, and auth function added some docs for utils
author Marcin Kuzminski <marcin@python-works.com>
date Thu, 25 Nov 2010 22:58:28 +0100
parents fb7a3b291e64
children 6e8322c438ca
files rhodecode/controllers/login.py rhodecode/lib/auth.py rhodecode/lib/utils.py rhodecode/model/forms.py rhodecode/model/user.py
diffstat 5 files changed, 70 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/controllers/login.py	Thu Nov 25 22:55:10 2010 +0100
+++ b/rhodecode/controllers/login.py	Thu Nov 25 22:58:28 2010 +0100
@@ -57,7 +57,7 @@
             try:
                 c.form_result = login_form.to_python(dict(request.POST))
                 username = c.form_result['username']
-                user = UserModel().get_by_username(username)
+                user = UserModel().get_by_username(username, case_insensitive=True)
                 auth_user = AuthUser()
                 auth_user.username = user.username
                 auth_user.is_authenticated = True
--- a/rhodecode/lib/auth.py	Thu Nov 25 22:55:10 2010 +0100
+++ b/rhodecode/lib/auth.py	Thu Nov 25 22:58:28 2010 +0100
@@ -77,38 +77,45 @@
 
 def authfunc(environ, username, password):
     """
-    Authentication function used in Mercurial/Git/ and access control,
+    Dummy authentication function used in Mercurial/Git/ and access control,
+    
+    :param environ: needed only for using in Basic auth
+    """
+    return authenticate(username, password)
+
+
+def authenticate(username, password):
+    """
+    Authentication function used for access control,
     firstly checks for db authentication then if ldap is enabled for ldap
     authentication, also creates ldap user if not in database
     
-    :param environ: needed only for using in Basic auth, can be None
     :param username: username
     :param password: password
     """
     user_model = UserModel()
     user = user_model.get_by_username(username, cache=False)
 
+    log.debug('Authenticating user using RhodeCode account')
     if user is not None and user.is_ldap is False:
         if user.active:
 
             if user.username == 'default' and user.active:
-                log.info('user %s authenticated correctly', username)
+                log.info('user %s authenticated correctly as anonymous user',
+                         username)
                 return True
 
             elif user.username == username and check_password(password, user.password):
                 log.info('user %s authenticated correctly', username)
                 return True
         else:
-            log.error('user %s is disabled', username)
-
+            log.warning('user %s is disabled', username)
 
     else:
-
-        #since ldap is searching in case insensitive check if this user is still
-        #not in our system
-        username = username.lower()
+        log.debug('Regular authentication failed')
         user_obj = user_model.get_by_username(username, cache=False,
                                             case_insensitive=True)
+
         if user_obj is not None and user_obj.is_ldap is False:
             log.debug('this user already exists as non ldap')
             return False
@@ -120,7 +127,7 @@
         # FALLBACK TO LDAP AUTH IN ENABLE                
         #======================================================================
         if ldap_settings.get('ldap_active', False):
-
+            log.debug("Authenticating user using ldap")
             kwargs = {
                   'server':ldap_settings.get('ldap_host', ''),
                   'base_dn':ldap_settings.get('ldap_base_dn', ''),
@@ -134,18 +141,17 @@
             try:
                 aldap = AuthLdap(**kwargs)
                 res = aldap.authenticate_ldap(username, password)
+                log.debug('Got ldap response %s', res)
 
-                authenticated = res[1]['uid'][0] == username
-
-                if authenticated and user_model.create_ldap(username, password):
+                if user_model.create_ldap(username, password):
                     log.info('created new ldap user')
 
-                return authenticated
-            except (LdapUsernameError, LdapPasswordError):
-                return False
-            except:
+                return True
+            except (LdapUsernameError, LdapPasswordError,):
+                pass
+            except (Exception,):
                 log.error(traceback.format_exc())
-                return False
+                pass
     return False
 
 class  AuthUser(object):
--- a/rhodecode/lib/utils.py	Thu Nov 25 22:55:10 2010 +0100
+++ b/rhodecode/lib/utils.py	Thu Nov 25 22:58:28 2010 +0100
@@ -128,6 +128,13 @@
             pass
 
 def check_repo_fast(repo_name, base_path):
+    """
+    Check given path for existance of directory
+    :param repo_name:
+    :param base_path:
+    
+    :return False: if this directory is present
+    """
     if os.path.isdir(os.path.join(base_path, repo_name)):return False
     return True
 
--- a/rhodecode/model/forms.py	Thu Nov 25 22:55:10 2010 +0100
+++ b/rhodecode/model/forms.py	Thu Nov 25 22:58:28 2010 +0100
@@ -19,24 +19,27 @@
 for SELECT use formencode.All(OneOf(list), Int())
     
 """
+import os
+import re
+import logging
+
+import formencode
 from formencode import All
 from formencode.validators import UnicodeString, OneOf, Int, Number, Regex, \
     Email, Bool, StringBoolean
-from pylons import session
+
 from pylons.i18n.translation import _
-from rhodecode.lib.auth import authfunc, get_crypt_password
+
+import rhodecode.lib.helpers as h
+from rhodecode.lib.auth import authenticate, get_crypt_password
 from rhodecode.lib.exceptions import LdapImportError
 from rhodecode.model import meta
 from rhodecode.model.user import UserModel
 from rhodecode.model.repo import RepoModel
 from rhodecode.model.db import User
+from rhodecode import BACKENDS
+
 from webhelpers.pylonslib.secure_form import authentication_token
-from rhodecode import BACKENDS
-import formencode
-import logging
-import os
-import re
-import rhodecode.lib.helpers as h
 
 log = logging.getLogger(__name__)
 
@@ -142,7 +145,7 @@
         username = value['username']
         user = UserModel().get_by_username(username)
 
-        if authfunc(None, username, password):
+        if authenticate(username, password):
             return value
         else:
             if user and user.active is False:
--- a/rhodecode/model/user.py	Thu Nov 25 22:55:10 2010 +0100
+++ b/rhodecode/model/user.py	Thu Nov 25 22:58:28 2010 +0100
@@ -1,8 +1,14 @@
-#!/usr/bin/env python
-# encoding: utf-8
-# Model for users
-# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
-# 
+# -*- coding: utf-8 -*-
+"""
+    package.rhodecode.model.user
+    ~~~~~~~~~~~~~~
+
+    users model for RhodeCode
+    :created_on: Apr 9, 2010
+    :author: marcink
+    :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>    
+    :license: GPLv3, see COPYING for more details.
+"""
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
 # as published by the Free Software Foundation; version 2
@@ -17,24 +23,21 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301, USA.
-"""
-Created on April 9, 2010
-Model for users
-:author: marcink
-"""
-
-from pylons.i18n.translation import _
-from rhodecode.model import BaseModel
-from rhodecode.model.caching_query import FromCache
-from rhodecode.model.db import User
-from rhodecode.lib.exceptions import *
 
 import logging
 import traceback
 
-log = logging.getLogger(__name__)
+from pylons.i18n.translation import _
+
+from rhodecode.model import BaseModel
+from rhodecode.model.caching_query import FromCache
+from rhodecode.model.db import User
 
+from rhodecode.lib.exceptions import DefaultUserException, UserOwnsReposException
 
+from sqlalchemy.exc import DatabaseError
+
+log = logging.getLogger(__name__)
 
 class UserModel(BaseModel):
 
@@ -79,10 +82,11 @@
         :param password:
         """
         from rhodecode.lib.auth import get_crypt_password
-        if self.get_by_username(username) is None:
+        log.debug('Checking for such ldap account in RhodeCode database')
+        if self.get_by_username(username, case_insensitive=True) is None:
             try:
                 new_user = User()
-                new_user.username = username
+                new_user.username = username.lower()#add ldap account always lowercase
                 new_user.password = get_crypt_password(password)
                 new_user.email = '%s@ldap.server' % username
                 new_user.active = True
@@ -94,11 +98,12 @@
                 self.sa.add(new_user)
                 self.sa.commit()
                 return True
-            except:
+            except (DatabaseError,):
                 log.error(traceback.format_exc())
                 self.sa.rollback()
                 raise
-
+        log.debug('this %s user exists skipping creation of ldap account',
+                  username)
         return False
 
     def create_registration(self, form_data):