# HG changeset patch # User Julien Tayon # Date 1582669378 -3600 # Node ID 5c35b94debfc980961243d24887dfc176d2892a8 # Parent 1206b6fa11737de921fef696d8f34fc11be84c34 [ldapfeed] make code compatible with ldap3>=2 * Some constants have been renamed. * Directly bind when data-cnx-dn/data-cnx-password are provided, some servers, including ours require this. * Use raise_exceptions=True to avoid ignored ldap errors * raise in case of failed anonymous bind * do not search for "dn" attribute because this raise an "invalid attribute" with new ldap3 versions * Password is now returned as bytes, so no longer need to encode them before crypt. * modification_date is now returned as a datetime object Co-Authored-By: Philippe Pepiot Closes #16073071 diff -r 1206b6fa1173 -r 5c35b94debfc cubicweb/server/sources/ldapfeed.py --- a/cubicweb/server/sources/ldapfeed.py Tue Feb 25 22:45:42 2020 +0100 +++ b/cubicweb/server/sources/ldapfeed.py Tue Feb 25 23:22:58 2020 +0100 @@ -34,10 +34,11 @@ from cubicweb import _ # search scopes -LDAP_SCOPES = {'BASE': ldap3.SEARCH_SCOPE_BASE_OBJECT, - 'ONELEVEL': ldap3.SEARCH_SCOPE_SINGLE_LEVEL, - 'SUBTREE': ldap3.SEARCH_SCOPE_WHOLE_SUBTREE} - +LDAP_SCOPES = { + 'BASE': ldap3.BASE, + 'ONELEVEL': ldap3.LEVEL, + 'SUBTREE': ldap3.SUBTREE, +} # map ldap protocol to their standard port PROTO_PORT = {'ldap': 389, @@ -254,7 +255,7 @@ # check password by establishing a (unused) connection try: self._connect(user, password) - except ldap3.LDAPException as ex: + except ldap3.core.exceptions.LDAPException as ex: # Something went wrong, most likely bad credentials self.info('while trying to authenticate %s: %s', user, ex) raise AuthenticationError() @@ -270,15 +271,27 @@ def _connect(self, user=None, userpwd=None): protocol, host, port = self.connection_info() + kwargs = {} + if user: + kwargs['user'] = user['dn'] + elif self.cnx_dn: + kwargs['user'] = self.cnx_dn + if self.cnx_pwd: + kwargs['password'] = self.cnx_pwd self.info('connecting %s://%s:%s as %s', protocol, host, port, - user and user['dn'] or 'anonymous') + kwargs.get('user', 'anonymous')) server = ldap3.Server(host, port=int(port)) - conn = ldap3.Connection(server, user=user and user['dn'], client_strategy=ldap3.STRATEGY_SYNC_RESTARTABLE, auto_referrals=False) + conn = ldap3.Connection( + server, client_strategy=ldap3.RESTARTABLE, auto_referrals=False, + raise_exceptions=True, + **kwargs) + # Now bind with the credentials given. Let exceptions propagate out. if user is None: - # XXX always use simple bind for data connection + # anonymous bind if not self.cnx_dn: - conn.bind() + if not conn.bind(): + raise AuthenticationError(conn.result["message"]) else: self._authenticate(conn, {'dn': self.cnx_dn}, self.cnx_pwd) else: @@ -289,7 +302,6 @@ return conn def _auth_simple(self, conn, user, userpwd): - conn.authentication = ldap3.AUTH_SIMPLE conn.user = user['dn'] conn.password = userpwd return conn.bind() @@ -314,7 +326,7 @@ if self._conn is None: self._conn = self._connect() ldapcnx = self._conn - if not ldapcnx.search(base, searchstr, search_scope=scope, attributes=attrs): + if not ldapcnx.search(base, searchstr, search_scope=scope, attributes=set(attrs) - {'dn'}): return [] result = [] for rec in ldapcnx.response: @@ -330,14 +342,14 @@ """Turn an ldap received item into a proper dict.""" itemdict = {'dn': dn} for key, value in iterator: - if self.user_attrs.get(key) == 'upassword': # XXx better password detection - value = value[0].encode('utf-8') + if self.user_attrs.get(key) == 'upassword': # XXx better password detection + value = value[0] # we only support ldap_salted_sha1 for ldap sources, see: server/utils.py if not value.startswith(b'{SSHA}'): value = utils.crypt_password(value) itemdict[key] = Binary(value) elif self.user_attrs.get(key) == 'modification_date': - itemdict[key] = datetime.strptime(value[0], '%Y%m%d%H%M%SZ') + itemdict[key] = value else: if PY2 and value and isinstance(value[0], str): value = [unicode(val, 'utf-8', 'replace') for val in value] diff -r 1206b6fa1173 -r 5c35b94debfc requirements/test-server.txt --- a/requirements/test-server.txt Tue Feb 25 22:45:42 2020 +0100 +++ b/requirements/test-server.txt Tue Feb 25 23:22:58 2020 +0100 @@ -1,9 +1,9 @@ mock psycopg2-binary -ldap3 < 2 cubicweb-basket cubicweb-card cubicweb-comment cubicweb-file >= 2.2.2 cubicweb-localperms cubicweb-tag +ldap3<3,>2