author | Aurelien Campeas <aurelien.campeas@logilab.fr> |
Wed, 09 May 2012 16:35:46 +0200 | |
changeset 8392 | c25b96ae4f8a |
parent 8391 | 574cf17a9928 |
child 8400 | 0ae27909e45b |
permissions | -rw-r--r-- |
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
1 |
# copyright 2011-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
2 |
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
3 |
# |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
4 |
# This file is part of CubicWeb. |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
5 |
# |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
6 |
# CubicWeb is free software: you can redistribute it and/or modify it under the |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
7 |
# terms of the GNU Lesser General Public License as published by the Free |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
8 |
# Software Foundation, either version 2.1 of the License, or (at your option) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
9 |
# any later version. |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
10 |
# |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
11 |
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
12 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
13 |
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
14 |
# details. |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
15 |
# |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
16 |
# You should have received a copy of the GNU Lesser General Public License along |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
17 |
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
18 |
"""cubicweb ldap feed source |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
19 |
|
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
20 |
unlike ldapuser source, this source is copy based and will import ldap content |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
21 |
(beside passwords for authentication) into the system source. |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
22 |
""" |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
23 |
|
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
24 |
from logilab.common.decorators import cached |
8387
b59af20a868d
[ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8382
diff
changeset
|
25 |
from logilab.common.shellutils import generate_password |
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
26 |
|
8387
b59af20a868d
[ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8382
diff
changeset
|
27 |
from cubicweb import Binary |
b59af20a868d
[ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8382
diff
changeset
|
28 |
from cubicweb.server.utils import crypt_password |
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
29 |
from cubicweb.server.sources import datafeed |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
30 |
|
8387
b59af20a868d
[ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8382
diff
changeset
|
31 |
|
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
32 |
class DataFeedlDAPParser(datafeed.DataFeedParser): |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
33 |
__regid__ = 'ldapfeed' |
8250
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
34 |
# attributes that may appears in source user_attrs dict which are not |
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
35 |
# attributes of the cw user |
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
36 |
non_attribute_keys = set(('email',)) |
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
37 |
|
8392
c25b96ae4f8a
[ldapparser] cleanup
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8391
diff
changeset
|
38 |
def process(self, url, partialcommit=True): |
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
39 |
"""IDataFeedParser main entry point""" |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
40 |
source = self.source |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
41 |
searchstr = '(&%s)' % ''.join(source.base_filters) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
42 |
for userdict in source._search(self._cw, source.user_base_dn, |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
43 |
source.user_base_scope, searchstr): |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
44 |
entity = self.extid2entity(userdict['dn'], 'CWUser', **userdict) |
8382
76c7149d9076
[ldapfeed] don't crash if entity is None. Closes (superficialy) #2341266
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8250
diff
changeset
|
45 |
if entity is not None and not self.created_during_pull(entity): |
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
46 |
self.notify_updated(entity) |
8250
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
47 |
attrs = self.ldap2cwattrs(userdict) |
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
48 |
self.update_if_necessary(entity, attrs) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
49 |
self._process_email(entity, userdict) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
50 |
|
8250
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
51 |
def ldap2cwattrs(self, sdict, tdict=None): |
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
52 |
if tdict is None: |
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
53 |
tdict = {} |
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
54 |
for sattr, tattr in self.source.user_attrs.iteritems(): |
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
55 |
if tattr not in self.non_attribute_keys: |
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
56 |
tdict[tattr] = sdict[sattr] |
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
57 |
return tdict |
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
58 |
|
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
59 |
def before_entity_copy(self, entity, sourceparams): |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
60 |
if entity.__regid__ == 'EmailAddress': |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
61 |
entity.cw_edited['address'] = sourceparams['address'] |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
62 |
else: |
8250
171a9d6bff8f
[ldapfeed] fix synchronisation crash: ldap attributes are given while we want cw attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8188
diff
changeset
|
63 |
self.ldap2cwattrs(sourceparams, entity.cw_edited) |
8387
b59af20a868d
[ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8382
diff
changeset
|
64 |
pwd = entity.cw_edited.get('upassword') |
b59af20a868d
[ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8382
diff
changeset
|
65 |
if not pwd: |
b59af20a868d
[ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8382
diff
changeset
|
66 |
# generate a dumb password if not fetched from ldap (see |
b59af20a868d
[ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8382
diff
changeset
|
67 |
# userPassword) |
b59af20a868d
[ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
8382
diff
changeset
|
68 |
pwd = crypt_password(generate_password()) |
8391
574cf17a9928
[ldapparser] reapply dropped fix
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents:
8387
diff
changeset
|
69 |
entity.cw_edited['upassword'] = Binary(pwd) |
8188
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
70 |
return entity |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
71 |
|
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
72 |
def after_entity_copy(self, entity, sourceparams): |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
73 |
super(DataFeedlDAPParser, self).after_entity_copy(entity, sourceparams) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
74 |
if entity.__regid__ == 'EmailAddress': |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
75 |
return |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
76 |
groups = [self._get_group(n) for n in self.source.user_default_groups] |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
77 |
entity.set_relations(in_group=groups) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
78 |
self._process_email(entity, sourceparams) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
79 |
|
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
80 |
def is_deleted(self, extid, etype, eid): |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
81 |
try: |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
82 |
extid, _ = extid.rsplit('@@', 1) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
83 |
except ValueError: |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
84 |
pass |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
85 |
return self.source.object_exists_in_ldap(extid) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
86 |
|
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
87 |
def _process_email(self, entity, userdict): |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
88 |
try: |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
89 |
emailaddrs = userdict[self.source.user_rev_attrs['email']] |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
90 |
except KeyError: |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
91 |
return # no email for that user, nothing to do |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
92 |
if not isinstance(emailaddrs, list): |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
93 |
emailaddrs = [emailaddrs] |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
94 |
for emailaddr in emailaddrs: |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
95 |
# search for existant email first, may be coming from another source |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
96 |
rset = self._cw.execute('EmailAddress X WHERE X address %(addr)s', |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
97 |
{'addr': emailaddr}) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
98 |
if not rset: |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
99 |
# not found, create it. first forge an external id |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
100 |
emailextid = userdict['dn'] + '@@' + emailaddr |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
101 |
email = self.extid2entity(emailextid, 'EmailAddress', |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
102 |
address=emailaddr) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
103 |
if entity.primary_email: |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
104 |
entity.set_relations(use_email=email) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
105 |
else: |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
106 |
entity.set_relations(primary_email=email) |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
107 |
# XXX else check use_email relation? |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
108 |
|
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
109 |
@cached |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
110 |
def _get_group(self, name): |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
111 |
return self._cw.execute('Any X WHERE X is CWGroup, X name %(name)s', |
1867e252e487
[repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff
changeset
|
112 |
{'name': name}).get_entity(0, 0) |