diff --git a/docs/setup.rst b/docs/setup.rst --- a/docs/setup.rst +++ b/docs/setup.rst @@ -113,7 +113,11 @@ Here's a typical ldap setup:: `Account` and `Password` are optional, and used for two-phase ldap authentication so those are credentials to access Your ldap, if it doesn't -support anonymous search/user lookups. +support anonymous search/user lookups. + +Base DN must have %(user)s template inside, it's a placer where Your uid used +to login would go, it allows admins to specify not standard schema for uid +variable If all data are entered correctly, and `python-ldap` is properly installed Users should be granted to access RhodeCode wit ldap accounts. When diff --git a/rhodecode/lib/auth_ldap.py b/rhodecode/lib/auth_ldap.py --- a/rhodecode/lib/auth_ldap.py +++ b/rhodecode/lib/auth_ldap.py @@ -55,7 +55,6 @@ class AuthLdap(object): self.LDAP_SERVER_PORT) self.BASE_DN = base_dn - self.AUTH_DN = "uid=%s,%s" def authenticate_ldap(self, username, password): """Authenticate a user via LDAP and return his/her LDAP properties. @@ -70,8 +69,7 @@ class AuthLdap(object): from rhodecode.lib.helpers import chop_at uid = chop_at(username, "@%s" % self.LDAP_SERVER_ADDRESS) - dn = self.AUTH_DN % (uid, self.BASE_DN) - log.debug("Authenticating %r at %s", dn, self.LDAP_SERVER) + if "," in username: raise LdapUsernameError("invalid character in username: ,") try: @@ -84,11 +82,13 @@ class AuthLdap(object): server.protocol = ldap.VERSION3 if self.LDAP_BIND_DN and self.LDAP_BIND_PASS: - server.simple_bind_s(self.AUTH_DN % (self.LDAP_BIND_DN, - self.BASE_DN), - self.LDAP_BIND_PASS) + login_dn = self.BASE_DN % {'user':uid} + server.simple_bind_s(login_dn, self.LDAP_BIND_PASS) + dn = self.BASE_DN % {'user':uid} + log.debug("Authenticating %r at %s", dn, self.LDAP_SERVER) server.simple_bind_s(dn, password) + properties = server.search_s(dn, ldap.SCOPE_SUBTREE) if not properties: raise ldap.NO_SUCH_OBJECT() diff --git a/rhodecode/model/forms.py b/rhodecode/model/forms.py --- a/rhodecode/model/forms.py +++ b/rhodecode/model/forms.py @@ -300,6 +300,26 @@ class LdapLibValidator(formencode.valida raise LdapImportError return value +class BaseDnValidator(formencode.validators.FancyValidator): + + def to_python(self, value, state): + + try: + value % {'user':'valid'} + + if value.find('%(user)s') == -1: + raise formencode.Invalid(_("You need to specify %(user)s in " + "template for example uid=%(user)s " + ",dc=company...") , + value, state) + + except KeyError: + raise formencode.Invalid(_("Wrong template used, only %(user)s " + "is an valid entry") , + value, state) + + return value + #=============================================================================== # FORMS #=============================================================================== @@ -457,6 +477,6 @@ def LdapSettingsForm(): ldap_ldaps = StringBoolean(if_missing=False) ldap_dn_user = UnicodeString(strip=True,) ldap_dn_pass = UnicodeString(strip=True,) - ldap_base_dn = UnicodeString(strip=True,) + ldap_base_dn = All(BaseDnValidator, UnicodeString(strip=True,)) return _LdapSettingsForm diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -1,7 +1,8 @@ -from rhodecode import get_version import sys py_version = sys.version_info +from rhodecode import get_version + requirements = [ "Pylons>=1.0.0", "SQLAlchemy>=0.6.5", @@ -9,7 +10,7 @@ requirements = [ "vcs>=0.1.10", "pygments>=1.3.0", "mercurial>=1.7.1", - "whoosh>=1.3.1", + "whoosh==1.3.1", "celery>=2.1.3", "py-bcrypt", "babel", @@ -93,6 +94,10 @@ setup( [paste.global_paster_command] make-index = rhodecode.lib.indexers:MakeIndex upgrade-db = rhodecode.lib.utils:UpgradeDb - + celeryd=rhodecode.lib.celerypylons.commands:CeleryDaemonCommand + celerybeat=rhodecode.lib.celerypylons.commands:CeleryBeatCommand + camqadm=rhodecode.lib.celerypylons.commands:CAMQPAdminCommand + celeryev=rhodecode.lib.celerypylons.commands:CeleryEventCommand + """, )