sobjects/ldapparser.py
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Mon, 08 Apr 2013 17:12:53 +0200
branchstable
changeset 8872 b638a99ab9cf
parent 8694 d901c36bcfce
child 8888 738f97bc3e19
permissions -rw-r--r--
[predicates] keep making `yes` predicate importable from cubicweb (closes #2790319) The `yes` predicate was moved out in CubicWeb 3.15 but it should have remained importable from the cubicweb.predicates module, for bw compat reasons and also because logilab.common.registry is an implementation detail.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
"""
8638
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    23
from logilab.common.decorators import cached, cachedproperty
8387
b59af20a868d [ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8382
diff changeset
    24
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
    25
8566
76bcfb3c483d [ldapparser] raise specific error if the configuration is wrong (closes #2498164)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8479
diff changeset
    26
from cubicweb import Binary, ConfigurationError
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.server.utils import crypt_password
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
from cubicweb.server.sources import datafeed
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    29
8387
b59af20a868d [ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8382
diff changeset
    30
8430
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    31
class DataFeedLDAPAdapter(datafeed.DataFeedParser):
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    32
    __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
    33
    # 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
    34
    # 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
    35
    non_attribute_keys = set(('email',))
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
8638
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    37
    @cachedproperty
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    38
    def searchfilterstr(self):
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    39
        """ ldap search string, including user-filter """
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    40
        return '(&%s)' % ''.join(self.source.base_filters)
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    41
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    42
    @cachedproperty
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    43
    def source_entities_by_extid(self):
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    44
        source = self.source
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    45
        return dict((userdict['dn'], userdict)
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    46
                    for userdict in source._search(self._cw,
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    47
                                                   source.user_base_dn,
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    48
                                                   source.user_base_scope,
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    49
                                                   self.searchfilterstr))
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    50
8409
79534887943e [datafeed] fix/finish cleanup started by auc in 8393:c25b96ae4f8a: parser.process prototytpe is (url, raise_on_error=False). Drop partialcommit argument which were never specified
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8400
diff changeset
    51
    def process(self, url, raise_on_error=False):
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    52
        """IDataFeedParser main entry point"""
8638
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    53
        self.debug('processing ldapfeed source %s %s', self.source, self.searchfilterstr)
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    54
        for userdict in self.source_entities_by_extid.itervalues():
8427
63c4c65e4db1 [web/views/staticcontroller] safety belt for unguessed mimetypes (closes #2380304)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8409
diff changeset
    55
            self.warning('fetched user %s', userdict)
8638
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    56
            extid = userdict['dn']
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
    57
            entity = self.extid2entity(extid, '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
    58
            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
    59
                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
    60
                attrs = self.ldap2cwattrs(userdict)
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
                self.update_if_necessary(entity, attrs)
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
                self._process_email(entity, userdict)
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    63
8430
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    64
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    65
    def handle_deletion(self, config, session, myuris):
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    66
        if config['delete-entities']:
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    67
            super(DataFeedLDAPAdapter, self).handle_deletion(config, session, myuris)
8432
96b4f7a35e6c [ldapparser] missing return
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8431
diff changeset
    68
            return
8430
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    69
        if myuris:
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    70
            byetype = {}
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    71
            for extid, (eid, etype) in myuris.iteritems():
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    72
                if self.is_deleted(extid, etype, eid):
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    73
                    byetype.setdefault(etype, []).append(str(eid))
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    74
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    75
            for etype, eids in byetype.iteritems():
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    76
                if etype != 'CWUser':
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    77
                    continue
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    78
                self.warning('deactivate %s %s entities', len(eids), etype)
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    79
                for eid in eids:
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    80
                    wf = session.entity_from_eid(eid).cw_adapt_to('IWorkflowable')
8434
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    81
                    wf.fire_transition_if_possible('deactivate')
8430
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    82
        session.commit(free_cnxset=False)
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
    83
8434
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    84
    def update_if_necessary(self, entity, attrs):
8478
e099ebc65e61 [ldap feed] fix error since with read security activated, password value is not selecteable (closes #2406597). Also add a note in the book about packages required to connect to an ldap server
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8434
diff changeset
    85
        # disable read security to allow password selection
e099ebc65e61 [ldap feed] fix error since with read security activated, password value is not selecteable (closes #2406597). Also add a note in the book about packages required to connect to an ldap server
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8434
diff changeset
    86
        with entity._cw.security_enabled(read=False):
e099ebc65e61 [ldap feed] fix error since with read security activated, password value is not selecteable (closes #2406597). Also add a note in the book about packages required to connect to an ldap server
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8434
diff changeset
    87
            entity.complete(tuple(attrs))
8434
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    88
        if entity.__regid__ == 'CWUser':
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    89
            wf = entity.cw_adapt_to('IWorkflowable')
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    90
            if wf.state == 'deactivated':
8639
2fddbe32ae8b [ldapfeed] if a deactivated user becomes available again in its source, reactivate it (closes #2542776)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8638
diff changeset
    91
                wf.fire_transition('activate')
2fddbe32ae8b [ldapfeed] if a deactivated user becomes available again in its source, reactivate it (closes #2542776)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8638
diff changeset
    92
                self.warning('user %s reactivated', entity.login)
8434
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    93
        mdate = attrs.get('modification_date')
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    94
        if not mdate or mdate > entity.modification_date:
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    95
            attrs = dict( (k, v) for k, v in attrs.iteritems()
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    96
                          if v != getattr(entity, k))
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    97
            if attrs:
8483
4ba11607d84a [entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8434
diff changeset
    98
                entity.cw_set(**attrs)
8434
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
    99
                self.notify_updated(entity)
39c5bb4dcc59 [ldapfeed] do not crash on ldap user deletion + pull + already deactivated users, cleanups (closes #2392933)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8432
diff changeset
   100
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
   101
    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
   102
        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
   103
            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
   104
        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
   105
            if tattr not in self.non_attribute_keys:
8566
76bcfb3c483d [ldapparser] raise specific error if the configuration is wrong (closes #2498164)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8479
diff changeset
   106
                try:
76bcfb3c483d [ldapparser] raise specific error if the configuration is wrong (closes #2498164)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8479
diff changeset
   107
                    tdict[tattr] = sdict[sattr]
76bcfb3c483d [ldapparser] raise specific error if the configuration is wrong (closes #2498164)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8479
diff changeset
   108
                except KeyError:
76bcfb3c483d [ldapparser] raise specific error if the configuration is wrong (closes #2498164)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8479
diff changeset
   109
                    raise ConfigurationError('source attribute %s is not present '
76bcfb3c483d [ldapparser] raise specific error if the configuration is wrong (closes #2498164)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8479
diff changeset
   110
                                             'in the source, please check the '
76bcfb3c483d [ldapparser] raise specific error if the configuration is wrong (closes #2498164)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8479
diff changeset
   111
                                             'user-attrs-map field' % sattr)
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
   112
        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
   113
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   114
    def before_entity_copy(self, entity, sourceparams):
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   115
        if entity.__regid__ == 'EmailAddress':
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   116
            entity.cw_edited['address'] = sourceparams['address']
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   117
        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
   118
            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
   119
            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
   120
            if not pwd:
b59af20a868d [ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8382
diff changeset
   121
                # 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
   122
                # userPassword)
b59af20a868d [ldap] we may actually get back password from ldap
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8382
diff changeset
   123
                pwd = crypt_password(generate_password())
8391
574cf17a9928 [ldapparser] reapply dropped fix
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8387
diff changeset
   124
                entity.cw_edited['upassword'] = Binary(pwd)
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   125
        return entity
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   127
    def after_entity_copy(self, entity, sourceparams):
8430
5bee87a14bb1 fix ldap removal handling in ldapfeed (closes #2376625 and #2385133)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8427
diff changeset
   128
        super(DataFeedLDAPAdapter, self).after_entity_copy(entity, sourceparams)
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   129
        if entity.__regid__ == 'EmailAddress':
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   130
            return
8679
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   131
        groups = filter(None, [self._get_group(name)
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   132
                               for name in self.source.user_default_groups])
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   133
        if groups:
8683
d537786e52b8 [merge] backport stable fixes
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8645 8679
diff changeset
   134
            entity.cw_set(in_group=groups)
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   135
        self._process_email(entity, sourceparams)
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   136
8638
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
   137
    def is_deleted(self, extidplus, etype, eid):
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   138
        try:
8638
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
   139
            extid, _ = extidplus.rsplit('@@', 1)
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   140
        except ValueError:
8638
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
   141
            # for some reason extids here tend to come in both forms, e.g:
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
   142
            # dn, dn@@Babar
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
   143
            extid = extidplus
9f95c2368b8b [ldaputils,ldapparser] correctly compute "deleted" users (closes #2542083)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8633
diff changeset
   144
        return extid not in self.source_entities_by_extid
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   145
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   146
    def _process_email(self, entity, userdict):
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   147
        try:
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
            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
   149
        except KeyError:
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
            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
   151
        if not isinstance(emailaddrs, list):
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
            emailaddrs = [emailaddrs]
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   153
        for emailaddr in emailaddrs:
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   154
            # 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
   155
            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
   156
                                   {'addr': emailaddr})
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   157
            if not rset:
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
                # 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
   159
                emailextid = userdict['dn'] + '@@' + emailaddr
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   160
                email = self.extid2entity(emailextid, 'EmailAddress',
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   161
                                          address=emailaddr)
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   162
                if entity.primary_email:
8483
4ba11607d84a [entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8434
diff changeset
   163
                    entity.cw_set(use_email=email)
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
                else:
8483
4ba11607d84a [entity api] unify set_attributes / set_relations into a cw_set method. Closes #2423719
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8434
diff changeset
   165
                    entity.cw_set(primary_email=email)
8400
0ae27909e45b [ldapfeed] properly mark email address as encountered during import to avoid deleting them
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8392
diff changeset
   166
            elif self.sourceuris:
0ae27909e45b [ldapfeed] properly mark email address as encountered during import to avoid deleting them
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8392
diff changeset
   167
                # pop from sourceuris anyway, else email may be removed by the
0ae27909e45b [ldapfeed] properly mark email address as encountered during import to avoid deleting them
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8392
diff changeset
   168
                # source once import is finished
8575
688d108af306 [ldapparser] utf-8 uri + unicode emailaddr will crash if the later is not properly encoded (closes #2508515)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8566
diff changeset
   169
                uri = userdict['dn'] + '@@' + emailaddr.encode('utf-8')
688d108af306 [ldapparser] utf-8 uri + unicode emailaddr will crash if the later is not properly encoded (closes #2508515)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8566
diff changeset
   170
                self.sourceuris.pop(uri, None)
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   171
            # XXX else check use_email relation?
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   172
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   173
    @cached
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   174
    def _get_group(self, name):
8679
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   175
        try:
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   176
            return self._cw.execute('Any X WHERE X is CWGroup, X name %(name)s',
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   177
                                    {'name': name}).get_entity(0, 0)
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   178
        except IndexError:
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   179
            self.error('group %r referenced by source configuration %r does not exist'
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   180
                       % (name, self.source.uri))
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   181
            return None
cf4dacc80976 [ldapfeed] don't crash if one specify an unexisting group in the configuration. Closes #2538399
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8639
diff changeset
   182