@@ -110,13 +110,17 @@ Here's a typical ldap setup::
Password = <password> #password for ldap server(if required)
Base DN = uid=%(user)s,CN=users,DC=host,DC=domain,DC=org
`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.
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
logging at the first time an special ldap account is created inside RhodeCode,
so You can control over permissions even on ldap users. If such user exists
already in RhodeCode database ldap user with the same username would be not
@@ -52,13 +52,12 @@ class AuthLdap(object):
if self.LDAP_USE_LDAPS:ldap_server_type = ldap_server_type + 's'
self.LDAP_SERVER = "%s://%s:%s" % (ldap_server_type,
self.LDAP_SERVER_ADDRESS,
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.
Raises AuthenticationError if the credentials are rejected, or
EnvironmentError if the LDAP server can't be reached.
@@ -67,31 +66,32 @@ class AuthLdap(object):
:param password: password
"""
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:
ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, '/etc/openldap/cacerts')
ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, 10)
server = ldap.initialize(self.LDAP_SERVER)
if self.ldap_version == 2:
server.protocol = ldap.VERSION2
else:
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}
server.simple_bind_s(dn, password)
properties = server.search_s(dn, ldap.SCOPE_SUBTREE)
if not properties:
raise ldap.NO_SUCH_OBJECT()
except ldap.NO_SUCH_OBJECT, e:
log.debug("LDAP says no such user '%s' (%s)", uid, username)
raise LdapUsernameError()
@@ -297,12 +297,32 @@ class LdapLibValidator(formencode.valida
import ldap
except ImportError:
raise LdapImportError
return value
class BaseDnValidator(formencode.validators.FancyValidator):
def to_python(self, value, state):
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") ,
#===============================================================================
# FORMS
class LoginForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
@@ -454,9 +474,9 @@ def LdapSettingsForm():
ldap_active = StringBoolean(if_missing=False)
ldap_host = UnicodeString(strip=True,)
ldap_port = Number(strip=True,)
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
from rhodecode import get_version
import sys
py_version = sys.version_info
requirements = [
"Pylons>=1.0.0",
"SQLAlchemy>=0.6.5",
"Mako>=0.3.6",
"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",
]
classifiers = ['Development Status :: 4 - Beta',
@@ -90,9 +91,13 @@ setup(
[paste.app_install]
main = pylons.util:PylonsInstaller
[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
""",
)
Status change: