##// END OF EJS Templates
Use webob exception as often as possible
Use webob exception as often as possible

File last commit:

r2031:82a88013 merge default
r2242:87e9718a codereview
Show More
auth_ldap.py
159 lines | 5.8 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, \
LdapPasswordError
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
implements #60, ldap configuration and authentication....
r705 pass
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'):
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)
implements #60, ldap configuration and authentication....
r705 self.LDAP_SERVER_ADDRESS = server
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
implements #60, ldap configuration and authentication....
r705 self.LDAP_BIND_DN = bind_dn
self.LDAP_BIND_PASS = bind_pass
added basic ldap auth lib
r700
implements #60, ldap configuration and authentication....
r705 self.LDAP_SERVER = "%s://%s:%s" % (ldap_server_type,
fix for issue #277,...
r1579 self.LDAP_SERVER_ADDRESS,
self.LDAP_SERVER_PORT)
implements #60, ldap configuration and authentication....
r705
self.BASE_DN = base_dn
Thayne Harbaugh
Improve LDAP authentication...
r991 self.LDAP_FILTER = 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:
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)