# HG changeset patch # User Sylvain Thénault # Date 1336053121 -7200 # Node ID b59af20a868d5b8e8a1c52102a21564cfe628387 # Parent 249b21722e5e95140223eed58987dd22eb05fac6 [ldap] we may actually get back password from ldap diff -r 249b21722e5e -r b59af20a868d hooks/metadata.py --- a/hooks/metadata.py Thu May 03 15:50:23 2012 +0200 +++ b/hooks/metadata.py Thu May 03 15:52:01 2012 +0200 @@ -199,17 +199,12 @@ entity = self._cw.entity_from_eid(self.eidfrom) # copy entity if necessary if not oldsource.repo_source.copy_based_source: - entity.complete(skip_bytes=False) + entity.complete(skip_bytes=False, skip_pwd=False) if not entity.creation_date: entity.cw_attr_cache['creation_date'] = datetime.now() if not entity.modification_date: entity.cw_attr_cache['modification_date'] = datetime.now() entity.cw_attr_cache['cwuri'] = u'%s%s' % (self._cw.base_url(), entity.eid) - for rschema, attrschema in entity.e_schema.attribute_definitions(): - if attrschema == 'Password' and \ - rschema.rdef(entity.e_schema, attrschema).cardinality[0] == '1': - from logilab.common.shellutils import generate_password - entity.cw_attr_cache[rschema.type] = generate_password() entity.cw_edited = EditedEntity(entity, **entity.cw_attr_cache) syssource.add_entity(self._cw, entity) # we don't want the moved entity to be reimported later. To diff -r 249b21722e5e -r b59af20a868d server/ldaputils.py --- a/server/ldaputils.py Thu May 03 15:50:23 2012 +0200 +++ b/server/ldaputils.py Thu May 03 15:52:01 2012 +0200 @@ -37,7 +37,7 @@ from ldap.filter import filter_format from ldapurl import LDAPUrl -from cubicweb import ValidationError, AuthenticationError +from cubicweb import ValidationError, AuthenticationError, Binary from cubicweb.server.sources import ConnectionWrapper _ = unicode @@ -125,7 +125,7 @@ }), ('user-attrs-map', {'type' : 'named', - 'default': {'uid': 'login', 'gecos': 'email'}, + 'default': {'uid': 'login', 'gecos': 'email', 'userPassword': 'upassword'}, 'help': 'map from ldap user attributes to cubicweb attributes (with Active Directory, you want to use sAMAccountName:login,mail:email,givenName:firstname,sn:surname)', 'group': 'ldap-source', 'level': 1, }), @@ -344,14 +344,13 @@ """Turn an ldap received item into a proper dict.""" itemdict = {'dn': dn} for key, value in iterator: - if not isinstance(value, str): - try: - for i in range(len(value)): - value[i] = unicode(value[i], 'utf8') - except Exception: - pass - if isinstance(value, list) and len(value) == 1: - itemdict[key] = value = value[0] + if self.user_attrs.get(key) == 'upassword': # XXx better password detection + itemdict[key] = Binary(value[0].encode('utf-8')) + else: + for i, val in enumerate(value): + value[i] = unicode(val, 'utf-8', 'replace') + if isinstance(value, list) and len(value) == 1: + itemdict[key] = value = value[0] return itemdict def _process_no_such_object(self, session, dn): diff -r 249b21722e5e -r b59af20a868d server/test/unittest_ldapuser.py --- a/server/test/unittest_ldapuser.py Thu May 03 15:50:23 2012 +0200 +++ b/server/test/unittest_ldapuser.py Thu May 03 15:52:01 2012 +0200 @@ -156,10 +156,15 @@ self.assertEqual(e.cw_source[0].name, 'system') self.assertTrue(e.creation_date) self.assertTrue(e.modification_date) - # XXX test some password has been set source.pull_data(self.session) rset = self.sexecute('CWUser X WHERE X login %(login)s', {'login': 'syt'}) self.assertEqual(len(rset), 1) + # test some password has been set + cu = self.session.system_sql('SELECT cw_upassword FROM cw_CWUser WHERE cw_eid=%s' % rset[0][0]) + value = str(cu.fetchall()[0][0]) + self.assertEqual(value, '{SSHA}v/8xJQP3uoaTBZz1T7Y0B3qOxRN1cj7D') + self.assertTrue(self.repo.system_source.authenticate( + self.session, 'syt', password='syt')) class LDAPUserSourceTC(LDAPFeedSourceTC): diff -r 249b21722e5e -r b59af20a868d server/utils.py --- a/server/utils.py Thu May 03 15:50:23 2012 +0200 +++ b/server/utils.py Thu May 03 15:52:01 2012 +0200 @@ -57,7 +57,7 @@ def calc_checksum(self, secret): return md5crypt(secret, self.salt.encode('ascii')) -myctx = CryptContext(['sha512_crypt', CustomMD5Crypt, 'des_crypt']) +myctx = CryptContext(['sha512_crypt', CustomMD5Crypt, 'des_crypt', 'ldap_salted_sha1']) def crypt_password(passwd, salt=None): """return the encrypted password using the given salt or a generated one diff -r 249b21722e5e -r b59af20a868d sobjects/ldapparser.py --- a/sobjects/ldapparser.py Thu May 03 15:50:23 2012 +0200 +++ b/sobjects/ldapparser.py Thu May 03 15:52:01 2012 +0200 @@ -23,9 +23,13 @@ from base64 import b64decode from logilab.common.decorators import cached +from logilab.common.shellutils import generate_password +from cubicweb import Binary +from cubicweb.server.utils import crypt_password from cubicweb.server.sources import datafeed + class DataFeedlDAPParser(datafeed.DataFeedParser): __regid__ = 'ldapfeed' # attributes that may appears in source user_attrs dict which are not @@ -62,6 +66,12 @@ entity.cw_edited['address'] = sourceparams['address'] else: self.ldap2cwattrs(sourceparams, entity.cw_edited) + pwd = entity.cw_edited.get('upassword') + if not pwd: + # generate a dumb password if not fetched from ldap (see + # userPassword) + pwd = crypt_password(generate_password()) + entity.cw_edited = Binary(pwd) return entity def after_entity_copy(self, entity, sourceparams):