##// END OF EJS Templates
Added tag v1.7.2 for changeset fc64cd9bb856
Added tag v1.7.2 for changeset fc64cd9bb856

File last commit:

r3700:3563bb7b merge default
r4108:71b73b1e default
Show More
auth_ldap.py
167 lines | 6.2 KiB | text/x-python | PythonLexer
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292 # -*- coding: utf-8 -*-
"""
rhodecode.controllers.changelog
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RhodeCode authentication library for LDAP
:created_on: Created on Nov 17, 2010
:author: marcink
2012 copyrights
r1824 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292 :license: GPLv3, see COPYING for more details.
"""
fixed license issue #149
r1206 # 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, either version 3 of the License, or
# (at your option) any later version.
source code cleanup: remove trailing white space, normalize file endings
r1203 #
fixed #72 show warning on removal when user still is owner of existing repositories...
r713 # This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
source code cleanup: remove trailing white space, normalize file endings
r1203 #
fixed #72 show warning on removal when user still is owner of existing repositories...
r713 # You should have received a copy of the GNU General Public License
fixed license issue #149
r1206 # along with this program. If not, see <http://www.gnu.org/licenses/>.
added basic ldap auth lib
r700
implements #60, ldap configuration and authentication....
r705 import logging
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292 from rhodecode.lib.exceptions import LdapConnectionError, LdapUsernameError, \
Mads Kiilerich
ldap: handle more elegantly that python-ldap isn't installed when trying to use ldap...
r3632 LdapPasswordError, LdapImportError
ldap requires only string attributes, fixes #435 ldap-does-not-work-with-non-latin-symbols
r2681 from rhodecode.lib.utils2 import safe_str
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292
implements #60, ldap configuration and authentication....
r705 log = logging.getLogger(__name__)
added basic ldap auth lib
r700
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292
implements #60, ldap configuration and authentication....
r705 try:
import ldap
except ImportError:
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292 # means that python-ldap is not installed
Mads Kiilerich
ldap: handle more elegantly that python-ldap isn't installed when trying to use ldap...
r3632 ldap = None
added basic ldap auth lib
r700
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292
implements #60, ldap configuration and authentication....
r705 class AuthLdap(object):
added basic ldap auth lib
r700
implements #60, ldap configuration and authentication....
r705 def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='',
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292 tls_kind='PLAIN', tls_reqcert='DEMAND', ldap_version=3,
Thayne Harbaugh
Improve LDAP authentication...
r991 ldap_filter='(&(objectClass=user)(!(objectClass=computer)))',
code garden...
r1792 search_scope='SUBTREE', attr_login='uid'):
Mads Kiilerich
ldap: handle more elegantly that python-ldap isn't installed when trying to use ldap...
r3632 if ldap is None:
raise LdapImportError
implements #60, ldap configuration and authentication....
r705 self.ldap_version = ldap_version
"Lorenzo M. Catucci"
Enable start_tls connection encryption.
r1290 ldap_server_type = 'ldap'
self.TLS_KIND = tls_kind
if self.TLS_KIND == 'LDAPS':
implements #60, ldap configuration and authentication....
r705 port = port or 689
"Lorenzo M. Catucci"
Enable start_tls connection encryption.
r1290 ldap_server_type = ldap_server_type + 's'
code garden...
r1792
fix for issue #277,...
r1579 OPT_X_TLS_DEMAND = 2
code garden...
r1792 self.TLS_REQCERT = getattr(ldap, 'OPT_X_TLS_%s' % tls_reqcert,
fix for issue #277,...
r1579 OPT_X_TLS_DEMAND)
Raoul Thill
LDAP fail-over using multiple server addresses from host field seperated by comma.
r2915 # split server into list
self.LDAP_SERVER_ADDRESS = server.split(',')
implements #60, ldap configuration and authentication....
r705 self.LDAP_SERVER_PORT = port
added basic ldap auth lib
r700
fixed issues with not unique emails when using ldap or container auth.
r1690 # USE FOR READ ONLY BIND TO LDAP SERVER
ldap requires only string attributes, fixes #435 ldap-does-not-work-with-non-latin-symbols
r2681 self.LDAP_BIND_DN = safe_str(bind_dn)
self.LDAP_BIND_PASS = safe_str(bind_pass)
Raoul Thill
LDAP fail-over using multiple server addresses from host field seperated by comma.
r2915 _LDAP_SERVERS = []
for host in self.LDAP_SERVER_ADDRESS:
_LDAP_SERVERS.append("%s://%s:%s" % (ldap_server_type,
host.replace(' ', ''),
self.LDAP_SERVER_PORT))
self.LDAP_SERVER = str(', '.join(s for s in _LDAP_SERVERS))
ldap requires only string attributes, fixes #435 ldap-does-not-work-with-non-latin-symbols
r2681 self.BASE_DN = safe_str(base_dn)
self.LDAP_FILTER = safe_str(ldap_filter)
fix for issue #277,...
r1579 self.SEARCH_SCOPE = getattr(ldap, 'SCOPE_%s' % search_scope)
Thayne Harbaugh
Improve LDAP authentication...
r991 self.attr_login = attr_login
implements #60, ldap configuration and authentication....
r705 def authenticate_ldap(self, username, password):
code garden...
r1792 """
Authenticate a user via LDAP and return his/her LDAP properties.
source code cleanup: remove trailing white space, normalize file endings
r1203
implements #60, ldap configuration and authentication....
r705 Raises AuthenticationError if the credentials are rejected, or
EnvironmentError if the LDAP server can't be reached.
source code cleanup: remove trailing white space, normalize file endings
r1203
implements #60, ldap configuration and authentication....
r705 :param username: username
:param password: password
"""
from rhodecode.lib.helpers import chop_at
uid = chop_at(username, "@%s" % self.LDAP_SERVER_ADDRESS)
fixes #77 and adds extendable base Dn with custom uid specification
r775
Shawn K. O'Shea
Reject LDAP authentication requests with blank password. Per RFC4513 these should be treated as anonymous binds. See the Security Considerations (Section 6.3.1) for more details on this issue.
r1659 if not password:
code garden...
r1792 log.debug("Attempt to authenticate LDAP user "
"with blank password rejected.")
Shawn K. O'Shea
Reject LDAP authentication requests with blank password. Per RFC4513 these should be treated as anonymous binds. See the Security Considerations (Section 6.3.1) for more details on this issue.
r1659 raise LdapPasswordError()
implements #60, ldap configuration and authentication....
r705 if "," in username:
fixed #72 show warning on removal when user still is owner of existing repositories...
r713 raise LdapUsernameError("invalid character in username: ,")
implements #60, ldap configuration and authentication....
r705 try:
code garden...
r1792 if hasattr(ldap, 'OPT_X_TLS_CACERTDIR'):
ldap.set_option(ldap.OPT_X_TLS_CACERTDIR,
fix for issue #277,...
r1579 '/etc/openldap/cacerts')
Thayne Harbaugh
Improve LDAP authentication...
r991 ldap.set_option(ldap.OPT_REFERRALS, ldap.OPT_OFF)
ldap.set_option(ldap.OPT_RESTART, ldap.OPT_ON)
ldap.set_option(ldap.OPT_TIMEOUT, 20)
implements #60, ldap configuration and authentication....
r705 ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, 10)
Thayne Harbaugh
Improve LDAP authentication...
r991 ldap.set_option(ldap.OPT_TIMELIMIT, 15)
"Lorenzo M. Catucci"
Enable start_tls connection encryption.
r1290 if self.TLS_KIND != 'PLAIN':
Thayne Harbaugh
Improve LDAP authentication...
r991 ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, self.TLS_REQCERT)
implements #60, ldap configuration and authentication....
r705 server = ldap.initialize(self.LDAP_SERVER)
if self.ldap_version == 2:
server.protocol = ldap.VERSION2
else:
server.protocol = ldap.VERSION3
added basic ldap auth lib
r700
"Lorenzo M. Catucci"
Enable start_tls connection encryption.
r1290 if self.TLS_KIND == 'START_TLS':
server.start_tls_s()
implements #60, ldap configuration and authentication....
r705 if self.LDAP_BIND_DN and self.LDAP_BIND_PASS:
log LDAP_BIND_DN for debugging
r2920 log.debug('Trying simple_bind with password and given DN: %s'
% self.LDAP_BIND_DN)
fixes a bug with two-pass ldap auth (thanks for TK Soh for that)
r794 server.simple_bind_s(self.LDAP_BIND_DN, self.LDAP_BIND_PASS)
added basic ldap auth lib
r700
code garden...
r1792 filter_ = '(&%s(%s=%s))' % (self.LDAP_FILTER, self.attr_login,
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292 username)
code garden...
r1792 log.debug("Authenticating %r filter %s at %s", self.BASE_DN,
filter_, self.LDAP_SERVER)
pep8
r1170 lobjects = server.search_ext_s(self.BASE_DN, self.SEARCH_SCOPE,
code garden...
r1792 filter_)
Thayne Harbaugh
Improve LDAP authentication...
r991
if not lobjects:
raise ldap.NO_SUCH_OBJECT()
fixes #77 and adds extendable base Dn with custom uid specification
r775
"Lorenzo M. Catucci"
Fetch entry after successful bind for being able to read its attributes.
r1287 for (dn, _attrs) in lobjects:
AD fix when search could return empty dn
r1444 if dn is None:
continue
Thayne Harbaugh
Improve LDAP authentication...
r991 try:
code garden...
r1792 log.debug('Trying simple bind with %s' % dn)
Thayne Harbaugh
Improve LDAP authentication...
r991 server.simple_bind_s(dn, password)
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292 attrs = server.search_ext_s(dn, ldap.SCOPE_BASE,
'(objectClass=*)')[0][1]
Thayne Harbaugh
Improve LDAP authentication...
r991 break
code garden...
r1792 except ldap.INVALID_CREDENTIALS:
garden...
r1976 log.debug(
"LDAP rejected password for user '%s' (%s): %s" % (
uid, username, dn
)
)
Thayne Harbaugh
Improve LDAP authentication...
r991
applied patch from issue #138
r1185 else:
log.debug("No matching LDAP objects for authentication "
"of '%s' (%s)", uid, username)
raise LdapPasswordError()
Thayne Harbaugh
Improve LDAP authentication...
r991
code garden...
r1792 except ldap.NO_SUCH_OBJECT:
garden...
r1976 log.debug("LDAP says no such user '%s' (%s)" % (uid, username))
fixed #72 show warning on removal when user still is owner of existing repositories...
r713 raise LdapUsernameError()
code garden...
r1792 except ldap.SERVER_DOWN:
added some fixes to LDAP form re-submition, new simples ldap-settings getter....
r1292 raise LdapConnectionError("LDAP can't access "
"authentication server")
implements #60, ldap configuration and authentication....
r705
Thayne Harbaugh
Improve LDAP authentication...
r991 return (dn, attrs)