server/sources/ldapuser.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 19 Feb 2010 09:34:14 +0100
branchstable
changeset 4643 921737d2e3a8
parent 4556 43c14e0e8972
child 4716 55b6a3262071
permissions -rw-r--r--
fix optimisation with super session that may lead to integrity loss at some point I've decided to stop ensuring ?1 cardinality was respected when adding a new relation using a super session, to avoid the cost of the delete query. That was yet discussable because it introduced unexpected difference between execute and unsafe_execute, which is imo not worth it. Also, now that rql() in migration script default to unsafe_execute, we definitly don't want that implicit behaviour change (which already cause bug when for instance adding another default workflow for an entity type: without that fix we end up with *two* default workflows while the schema tells we can have only one. IMO we should go to the direction that super session skip all security check, but nothing else, unless explicitly asked.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     1
"""cubicweb ldap user source
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     2
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
     3
this source is for now limited to a read-only CWUser source
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     4
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     5
:organization: Logilab
4212
ab6573088b4a update copyright: welcome 2010
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3689
diff changeset
     6
:copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     7
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     8
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     9
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    10
Part of the code is coming form Zope's LDAPUserFolder
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    11
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    12
Copyright (c) 2004 Jens Vagelpohl.
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    13
All Rights Reserved.
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    14
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    15
This software is subject to the provisions of the Zope Public License,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    16
Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    17
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    18
WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
FOR A PARTICULAR PURPOSE.
1977
606923dff11b big bunch of copyright / docstring update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1954
diff changeset
    21
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    23
1952
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1802
diff changeset
    24
from base64 import b64decode
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1802
diff changeset
    25
2633
bc9386c3b2c9 get_csv is being renamed to splitstrip
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    26
from logilab.common.textutils import splitstrip
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    27
from rql.nodes import Relation, VariableRef, Constant, Function
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    29
import ldap
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    30
from ldap.ldapobject import ReconnectLDAPObject
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    31
from ldap.filter import filter_format, escape_filter_chars
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    32
from ldapurl import LDAPUrl
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    33
1238
fa29b5b60107 set 30sec query cache on pyro source, important speedup for pages generating multiple time the same external query
sylvain.thenault@logilab.fr
parents: 975
diff changeset
    34
from cubicweb import AuthenticationError, UnknownEid, RepositoryError
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    35
from cubicweb.server.utils import cartesian_product
1238
fa29b5b60107 set 30sec query cache on pyro source, important speedup for pages generating multiple time the same external query
sylvain.thenault@logilab.fr
parents: 975
diff changeset
    36
from cubicweb.server.sources import (AbstractSource, TrFunc, GlobTrFunc,
fa29b5b60107 set 30sec query cache on pyro source, important speedup for pages generating multiple time the same external query
sylvain.thenault@logilab.fr
parents: 975
diff changeset
    37
                                     ConnectionWrapper, TimedCache)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    39
# search scopes
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    40
BASE = ldap.SCOPE_BASE
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    41
ONELEVEL = ldap.SCOPE_ONELEVEL
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    42
SUBTREE = ldap.SCOPE_SUBTREE
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    43
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    44
# map ldap protocol to their standard port
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    45
PROTO_PORT = {'ldap': 389,
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    46
              'ldaps': 636,
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    47
              'ldapi': None,
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    48
              }
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    49
1263
01152fffd593 backport default branch
sylvain.thenault@logilab.fr
parents: 1016 1238
diff changeset
    50
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    51
class LDAPUserSource(AbstractSource):
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
    52
    """LDAP read-only CWUser source"""
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
    53
    support_entities = {'CWUser': False}
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    54
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    55
    options = (
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    56
        ('host',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    57
         {'type' : 'string',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    58
          'default': 'ldap',
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    59
          'help': 'ldap host. It may contains port information using \
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    60
<host>:<port> notation.',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    61
          'group': 'ldap-source', 'inputlevel': 1,
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    62
          }),
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    63
        ('protocol',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    64
         {'type' : 'choice',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    65
          'default': 'ldap',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    66
          'choices': ('ldap', 'ldaps', 'ldapi'),
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    67
          'help': 'ldap protocol',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    68
          'group': 'ldap-source', 'inputlevel': 1,
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    69
          }),
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    70
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    71
        ('auth-mode',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    72
         {'type' : 'choice',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    73
          'default': 'simple',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    74
          'choices': ('simple', 'cram_md5', 'digest_md5', 'gssapi'),
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    75
          'help': 'authentication mode used to authenticate user to the ldap.',
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    76
          'group': 'ldap-source', 'inputlevel': 1,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    77
          }),
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    78
        ('auth-realm',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    79
         {'type' : 'string',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    80
          'default': None,
4555
8968c50818db typo fix in help string
Alexandre Fayolle <alexandre.fayolle@logilab.fr>
parents: 4212
diff changeset
    81
          'help': 'realm to use when using gssapi/kerberos authentication.',
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    82
          'group': 'ldap-source', 'inputlevel': 1,
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    83
          }),
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    84
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    85
        ('data-cnx-dn',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    86
         {'type' : 'string',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    87
          'default': '',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    88
          'help': 'user dn to use to open data connection to the ldap (eg used \
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    89
to respond to rql queries).',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    90
          'group': 'ldap-source', 'inputlevel': 1,
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    91
          }),
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    92
        ('data-cnx-password',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    93
         {'type' : 'string',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    94
          'default': '',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    95
          'help': 'password to use to open data connection to the ldap (eg used to respond to rql queries).',
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    96
          'group': 'ldap-source', 'inputlevel': 1,
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    97
          }),
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
    98
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    99
        ('user-base-dn',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   100
         {'type' : 'string',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   101
          'default': 'ou=People,dc=logilab,dc=fr',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   102
          'help': 'base DN to lookup for users',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   103
          'group': 'ldap-source', 'inputlevel': 0,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   104
          }),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   105
        ('user-scope',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   106
         {'type' : 'choice',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
          'default': 'ONELEVEL',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   108
          'choices': ('BASE', 'ONELEVEL', 'SUBTREE'),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   109
          'help': 'user search scope',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   110
          'group': 'ldap-source', 'inputlevel': 1,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   111
          }),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   112
        ('user-classes',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   113
         {'type' : 'csv',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   114
          'default': ('top', 'posixAccount'),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   115
          'help': 'classes of user',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   116
          'group': 'ldap-source', 'inputlevel': 1,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   117
          }),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   118
        ('user-login-attr',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   119
         {'type' : 'string',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   120
          'default': 'uid',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   121
          'help': 'attribute used as login on authentication',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   122
          'group': 'ldap-source', 'inputlevel': 1,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   123
          }),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   124
        ('user-default-group',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   125
         {'type' : 'csv',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
          'default': ('users',),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   127
          'help': 'name of a group in which ldap users will be by default. \
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   128
You can set multiple groups by separating them by a comma.',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   129
          'group': 'ldap-source', 'inputlevel': 1,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   130
          }),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   131
        ('user-attrs-map',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   132
         {'type' : 'named',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   133
          'default': {'uid': 'login', 'gecos': 'email'},
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   134
          'help': 'map from ldap user attributes to cubicweb attributes',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   135
          'group': 'ldap-source', 'inputlevel': 1,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   136
          }),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   137
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   138
        ('synchronization-interval',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   139
         {'type' : 'int',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   140
          'default': 24*60*60,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
          'help': 'interval between synchronization with the ldap \
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   142
directory (default to once a day).',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
          'group': 'ldap-source', 'inputlevel': 2,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
          }),
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   145
        ('cache-life-time',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   146
         {'type' : 'int',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   147
          'default': 2*60,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
          'help': 'life time of query cache in minutes (default to two hours).',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
          'group': 'ldap-source', 'inputlevel': 2,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
          }),
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   151
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
    )
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   153
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   154
    def __init__(self, repo, appschema, source_config, *args, **kwargs):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   155
        AbstractSource.__init__(self, repo, appschema, source_config,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   156
                                *args, **kwargs)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   157
        self.host = source_config['host']
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   158
        self.protocol = source_config.get('protocol', 'ldap')
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   159
        self.authmode = source_config.get('auth-mode', 'simple')
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   160
        self._authenticate = getattr(self, '_auth_%s' % self.authmode)
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   161
        self.cnx_dn = source_config.get('data-cnx-dn') or ''
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   162
        self.cnx_pwd = source_config.get('data-cnx-password') or ''
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   163
        self.user_base_scope = globals()[source_config['user-scope']]
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
        self.user_base_dn = source_config['user-base-dn']
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   165
        self.user_base_scope = globals()[source_config['user-scope']]
2633
bc9386c3b2c9 get_csv is being renamed to splitstrip
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   166
        self.user_classes = splitstrip(source_config['user-classes'])
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   167
        self.user_login_attr = source_config['user-login-attr']
2633
bc9386c3b2c9 get_csv is being renamed to splitstrip
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   168
        self.user_default_groups = splitstrip(source_config['user-default-group'])
bc9386c3b2c9 get_csv is being renamed to splitstrip
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   169
        self.user_attrs = dict(v.split(':', 1) for v in splitstrip(source_config['user-attrs-map']))
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   170
        self.user_rev_attrs = {'eid': 'dn'}
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   171
        for ldapattr, cwattr in self.user_attrs.items():
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   172
            self.user_rev_attrs[cwattr] = ldapattr
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   173
        self.base_filters = [filter_format('(%s=%s)', ('objectClass', o))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   174
                              for o in self.user_classes]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   175
        self._conn = None
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   176
        self._cache = {}
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   177
        ttlm = int(source_config.get('cache-life-type', 2*60))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   178
        self._query_cache = TimedCache(ttlm)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   179
        self._interval = int(source_config.get('synchronization-interval',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   180
                                               24*60*60))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   181
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   182
    def reset_caches(self):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   183
        """method called during test to reset potential source caches"""
2763
39b42e158249 [ms] proper reset cache on external source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2707
diff changeset
   184
        self._cache = {}
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   185
        self._query_cache = TimedCache(2*60)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   186
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   187
    def init(self):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   188
        """method called by the repository once ready to handle request"""
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   189
        self.repo.looping_task(self._interval, self.synchronize)
1954
9b20f3504af8 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1952
diff changeset
   190
        self.repo.looping_task(self._query_cache.ttl.seconds/10,
9b20f3504af8 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1952
diff changeset
   191
                               self._query_cache.clear_expired)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   192
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   193
    def synchronize(self):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   194
        """synchronize content known by this repository with content in the
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   195
        external repository
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   196
        """
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   197
        self.info('synchronizing ldap source %s', self.uri)
938
a69188963ccb check ldap source has email configured before synchronization
sylvain.thenault@logilab.fr
parents: 257
diff changeset
   198
        try:
a69188963ccb check ldap source has email configured before synchronization
sylvain.thenault@logilab.fr
parents: 257
diff changeset
   199
            ldap_emailattr = self.user_rev_attrs['email']
a69188963ccb check ldap source has email configured before synchronization
sylvain.thenault@logilab.fr
parents: 257
diff changeset
   200
        except KeyError:
a69188963ccb check ldap source has email configured before synchronization
sylvain.thenault@logilab.fr
parents: 257
diff changeset
   201
            return # no email in ldap, we're done
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   202
        session = self.repo.internal_session()
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   203
        try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   204
            cursor = session.system_sql("SELECT eid, extid FROM entities WHERE "
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   205
                                        "source='%s'" % self.uri)
1952
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1802
diff changeset
   206
            for eid, b64extid in cursor.fetchall():
8e19c813750d fix extid handling: ensure encoded string is given, and store them as base64 (see note in native.py).
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1802
diff changeset
   207
                extid = b64decode(b64extid)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   208
                # if no result found, _search automatically delete entity information
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   209
                res = self._search(session, extid, BASE)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   210
                if res:
938
a69188963ccb check ldap source has email configured before synchronization
sylvain.thenault@logilab.fr
parents: 257
diff changeset
   211
                    ldapemailaddr = res[0].get(ldap_emailattr)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   212
                    if ldapemailaddr:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   213
                        rset = session.execute('EmailAddress X,A WHERE '
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   214
                                               'U use_email X, U eid %(u)s',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   215
                                               {'u': eid})
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   216
                        ldapemailaddr = unicode(ldapemailaddr)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   217
                        for emaileid, emailaddr in rset:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   218
                            if emailaddr == ldapemailaddr:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   219
                                break
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   220
                        else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   221
                            self.info('updating email address of user %s to %s',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   222
                                      extid, ldapemailaddr)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   223
                            if rset:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   224
                                session.execute('SET X address %(addr)s WHERE '
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   225
                                                'U primary_email X, U eid %(u)s',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   226
                                                {'addr': ldapemailaddr, 'u': eid})
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   227
                            else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   228
                                # no email found, create it
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   229
                                _insert_email(session, ldapemailaddr, eid)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   230
        finally:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   231
            session.commit()
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   232
            session.close()
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   233
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   234
    def get_connection(self):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   235
        """open and return a connection to the source"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   236
        if self._conn is None:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   237
            self._connect()
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   238
        return ConnectionWrapper(self._conn)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   239
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3245
diff changeset
   240
    def authenticate(self, session, login, password=None, **kwargs):
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   241
        """return CWUser eid for the given login/password if this account is
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   242
        defined in this source, else raise `AuthenticationError`
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   243
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   244
        two queries are needed since passwords are stored crypted, so we have
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   245
        to fetch the salt first
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   246
        """
3647
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3245
diff changeset
   247
        if password is None:
2941f4a0aab9 refactor repo authentication to allow pluggable authentifier to login with something else than a password
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3245
diff changeset
   248
            raise AuthenticationError()
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   249
        searchfilter = [filter_format('(%s=%s)', (self.user_login_attr, login))]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   250
        searchfilter.extend([filter_format('(%s=%s)', ('objectClass', o))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   251
                             for o in self.user_classes])
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   252
        searchstr = '(&%s)' % ''.join(searchfilter)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   253
        # first search the user
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   254
        try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   255
            user = self._search(session, self.user_base_dn,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   256
                                self.user_base_scope, searchstr)[0]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   257
        except IndexError:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   258
            # no such user
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   259
            raise AuthenticationError()
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   260
        # check password by establishing a (unused) connection
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   261
        try:
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   262
            self._connect(user, password)
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   263
        except Exception, ex:
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   264
            self.info('while trying to authenticate %s: %s', user, ex)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   265
            # Something went wrong, most likely bad credentials
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   266
            raise AuthenticationError()
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   267
        return self.extid2eid(user['dn'], 'CWUser', session)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   268
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   269
    def ldap_name(self, var):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   270
        if var.stinfo['relations']:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   271
            relname = iter(var.stinfo['relations']).next().r_type
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   272
            return self.user_rev_attrs.get(relname)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   273
        return None
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   274
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   275
    def prepare_columns(self, mainvars, rqlst):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   276
        """return two list describin how to build the final results
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   277
        from the result of an ldap search (ie a list of dictionnary)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   278
        """
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   279
        columns = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   280
        global_transforms = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   281
        for i, term in enumerate(rqlst.selection):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   282
            if isinstance(term, Constant):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   283
                columns.append(term)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   284
                continue
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   285
            if isinstance(term, Function): # LOWER, UPPER, COUNT...
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   286
                var = term.get_nodes(VariableRef)[0]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   287
                var = var.variable
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   288
                try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   289
                    mainvar = var.stinfo['attrvar'].name
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   290
                except AttributeError: # no attrvar set
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   291
                    mainvar = var.name
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   292
                assert mainvar in mainvars
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   293
                trname = term.name
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   294
                ldapname = self.ldap_name(var)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   295
                if trname in ('COUNT', 'MIN', 'MAX', 'SUM'):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   296
                    global_transforms.append(GlobTrFunc(trname, i, ldapname))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   297
                    columns.append((mainvar, ldapname))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   298
                    continue
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   299
                if trname in ('LOWER', 'UPPER'):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   300
                    columns.append((mainvar, TrFunc(trname, i, ldapname)))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   301
                    continue
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   302
                raise NotImplementedError('no support for %s function' % trname)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   303
            if term.name in mainvars:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   304
                columns.append((term.name, 'dn'))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   305
                continue
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   306
            var = term.variable
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   307
            mainvar = var.stinfo['attrvar'].name
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   308
            columns.append((mainvar, self.ldap_name(var)))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   309
            #else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   310
            #    # probably a bug in rql splitting if we arrive here
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   311
            #    raise NotImplementedError
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   312
        return columns, global_transforms
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   313
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   314
    def syntax_tree_search(self, session, union,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   315
                           args=None, cachekey=None, varmap=None, debug=0):
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   316
        """return result from this source for a rql query (actually from a rql
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   317
        syntax tree and a solution dictionary mapping each used variable to a
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   318
        possible type). If cachekey is given, the query necessary to fetch the
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   319
        results (but not the results themselves) may be cached using this key.
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   320
        """
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   321
        # XXX not handled : transform/aggregat function, join on multiple users...
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   322
        assert len(union.children) == 1, 'union not supported'
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   323
        rqlst = union.children[0]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   324
        assert not rqlst.with_, 'subquery not supported'
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   325
        rqlkey = rqlst.as_string(kwargs=args)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   326
        try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   327
            results = self._query_cache[rqlkey]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   328
        except KeyError:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   329
            results = self.rqlst_search(session, rqlst, args)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   330
            self._query_cache[rqlkey] = results
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   331
        return results
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   332
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   333
    def rqlst_search(self, session, rqlst, args):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   334
        mainvars = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   335
        for varname in rqlst.defined_vars:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   336
            for sol in rqlst.solutions:
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   337
                if sol[varname] == 'CWUser':
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   338
                    mainvars.append(varname)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   339
                    break
3245
7ef021ac8dec cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2763
diff changeset
   340
        assert mainvars, rqlst
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   341
        columns, globtransforms = self.prepare_columns(mainvars, rqlst)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   342
        eidfilters = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   343
        allresults = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   344
        generator = RQL2LDAPFilter(self, session, args, mainvars)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   345
        for mainvar in mainvars:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   346
            # handle restriction
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   347
            try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   348
                eidfilters_, ldapfilter = generator.generate(rqlst, mainvar)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   349
            except GotDN, ex:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   350
                assert ex.dn, 'no dn!'
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   351
                try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   352
                    res = [self._cache[ex.dn]]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   353
                except KeyError:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   354
                    res = self._search(session, ex.dn, BASE)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   355
            except UnknownEid, ex:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   356
                # raised when we are looking for the dn of an eid which is not
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   357
                # coming from this source
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   358
                res = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   359
            else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   360
                eidfilters += eidfilters_
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   361
                res = self._search(session, self.user_base_dn,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   362
                                   self.user_base_scope, ldapfilter)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   363
            allresults.append(res)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   364
        # 1. get eid for each dn and filter according to that eid if necessary
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   365
        for i, res in enumerate(allresults):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   366
            filteredres = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   367
            for resdict in res:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   368
                # get sure the entity exists in the system table
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   369
                eid = self.extid2eid(resdict['dn'], 'CWUser', session)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   370
                for eidfilter in eidfilters:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   371
                    if not eidfilter(eid):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   372
                        break
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   373
                else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   374
                    resdict['eid'] = eid
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   375
                    filteredres.append(resdict)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   376
            allresults[i] = filteredres
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   377
        # 2. merge result for each "mainvar": cartesian product
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   378
        allresults = cartesian_product(allresults)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   379
        # 3. build final result according to column definition
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   380
        result = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   381
        for rawline in allresults:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   382
            rawline = dict(zip(mainvars, rawline))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   383
            line = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   384
            for varname, ldapname in columns:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   385
                if ldapname is None:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   386
                    value = None # no mapping available
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   387
                elif ldapname == 'dn':
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   388
                    value = rawline[varname]['eid']
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   389
                elif isinstance(ldapname, Constant):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   390
                    if ldapname.type == 'Substitute':
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   391
                        value = args[ldapname.value]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   392
                    else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   393
                        value = ldapname.value
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   394
                elif isinstance(ldapname, TrFunc):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   395
                    value = ldapname.apply(rawline[varname])
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   396
                else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   397
                    value = rawline[varname].get(ldapname)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   398
                line.append(value)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   399
            result.append(line)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   400
        for trfunc in globtransforms:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   401
            result = trfunc.apply(result)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   402
        #print '--> ldap result', result
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   403
        return result
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   404
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   405
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   406
    def _connect(self, user=None, userpwd=None):
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   407
        if self.protocol == 'ldapi':
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   408
            hostport = self.host
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   409
        elif not ':' in self.host:
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   410
            hostport = '%s:%s' % (self.host, PROTO_PORT[self.protocol])
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   411
        else:
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   412
            hostport = self.host
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   413
        self.info('connecting %s://%s as %s', self.protocol, hostport,
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   414
                  user and user['dn'] or 'anonymous')
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   415
        url = LDAPUrl(urlscheme=self.protocol, hostport=hostport)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   416
        conn = ReconnectLDAPObject(url.initializeUrl())
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   417
        # Set the protocol version - version 3 is preferred
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   418
        try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   419
            conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   420
        except ldap.LDAPError: # Invalid protocol version, fall back safely
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   421
            conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION2)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   422
        # Deny auto-chasing of referrals to be safe, we handle them instead
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   423
        #try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   424
        #    connection.set_option(ldap.OPT_REFERRALS, 0)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   425
        #except ldap.LDAPError: # Cannot set referrals, so do nothing
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   426
        #    pass
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   427
        #conn.set_option(ldap.OPT_NETWORK_TIMEOUT, conn_timeout)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   428
        #conn.timeout = op_timeout
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   429
        # Now bind with the credentials given. Let exceptions propagate out.
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   430
        if user is None:
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   431
            # no user specified, we want to initialize the 'data' connection,
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   432
            assert self._conn is None
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   433
            self._conn = conn
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   434
            # XXX always use simple bind for data connection
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   435
            if not self.cnx_dn:
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   436
                conn.simple_bind_s(self.cnx_dn, self.cnx_pwd)
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   437
            else:
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   438
                self._authenticate(conn, {'dn': self.cnx_dn}, self.cnx_pwd)
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   439
        else:
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   440
            # user specified, we want to check user/password, no need to return
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   441
            # the connection which will be thrown out
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   442
            self._authenticate(conn, user, userpwd)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   443
        return conn
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   444
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   445
    def _auth_simple(self, conn, user, userpwd):
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   446
        conn.simple_bind_s(user['dn'], userpwd)
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   447
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   448
    def _auth_cram_md5(self, conn, user, userpwd):
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   449
        from ldap import sasl
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   450
        auth_token = sasl.cram_md5(user['dn'], userpwd)
2707
15ffc3c8923c cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2699
diff changeset
   451
        conn.sasl_interactive_bind_s('', auth_tokens)
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   452
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   453
    def _auth_digest_md5(self, conn, user, userpwd):
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   454
        from ldap import sasl
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   455
        auth_token = sasl.digest_md5(user['dn'], userpwd)
2707
15ffc3c8923c cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2699
diff changeset
   456
        conn.sasl_interactive_bind_s('', auth_tokens)
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   457
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   458
    def _auth_gssapi(self, conn, user, userpwd):
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   459
        # print XXX not proper sasl/gssapi
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   460
        import kerberos
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   461
        if not kerberos.checkPassword(user[self.user_login_attr], userpwd):
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   462
            raise Exception('BAD login / mdp')
2707
15ffc3c8923c cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2699
diff changeset
   463
        #from ldap import sasl
15ffc3c8923c cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2699
diff changeset
   464
        #conn.sasl_interactive_bind_s('', sasl.gssapi())
2699
1025300249d2 [ldap] more configuration possible on ldap source: protocal/authentication mode, dumb support for kerberos authentication
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2633
diff changeset
   465
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   466
    def _search(self, session, base, scope,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   467
                searchstr='(objectClass=*)', attrs=()):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   468
        """make an ldap query"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   469
        cnx = session.pool.connection(self.uri).cnx
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   470
        try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   471
            res = cnx.search_s(base, scope, searchstr, attrs)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   472
        except ldap.PARTIAL_RESULTS:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   473
            res = cnx.result(all=0)[1]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   474
        except ldap.NO_SUCH_OBJECT:
1398
5fe84a5f7035 rename internal entity types to have CW prefix instead of E
sylvain.thenault@logilab.fr
parents: 1263
diff changeset
   475
            eid = self.extid2eid(base, 'CWUser', session, insert=False)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   476
            if eid:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   477
                self.warning('deleting ldap user with eid %s and dn %s',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   478
                             eid, base)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   479
                self.repo.delete_info(session, eid)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   480
                self._cache.pop(base, None)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   481
            return []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   482
##         except ldap.REFERRAL, e:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   483
##             cnx = self.handle_referral(e)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   484
##             try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   485
##                 res = cnx.search_s(base, scope, searchstr, attrs)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   486
##             except ldap.PARTIAL_RESULTS:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   487
##                 res_type, res = cnx.result(all=0)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   488
        result = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   489
        for rec_dn, rec_dict in res:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   490
            # When used against Active Directory, "rec_dict" may not be
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   491
            # be a dictionary in some cases (instead, it can be a list)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   492
            # An example of a useless "res" entry that can be ignored
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   493
            # from AD is
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   494
            # (None, ['ldap://ForestDnsZones.PORTAL.LOCAL/DC=ForestDnsZones,DC=PORTAL,DC=LOCAL'])
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   495
            # This appears to be some sort of internal referral, but
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   496
            # we can't handle it, so we need to skip over it.
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   497
            try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   498
                items =  rec_dict.items()
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   499
            except AttributeError:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   500
                # 'items' not found on rec_dict, skip
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   501
                continue
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   502
            for key, value in items: # XXX syt: huuum ?
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   503
                if not isinstance(value, str):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   504
                    try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   505
                        for i in range(len(value)):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   506
                            value[i] = unicode(value[i], 'utf8')
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   507
                    except:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   508
                        pass
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   509
                if isinstance(value, list) and len(value) == 1:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   510
                    rec_dict[key] = value = value[0]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   511
            rec_dict['dn'] = rec_dn
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   512
            self._cache[rec_dn] = rec_dict
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   513
            result.append(rec_dict)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   514
        #print '--->', result
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   515
        return result
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   516
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   517
    def before_entity_insertion(self, session, lid, etype, eid):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   518
        """called by the repository when an eid has been attributed for an
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   519
        entity stored here but the entity has not been inserted in the system
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   520
        table yet.
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   521
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   522
        This method must return the an Entity instance representation of this
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   523
        entity.
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   524
        """
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   525
        entity = super(LDAPUserSource, self).before_entity_insertion(session, lid, etype, eid)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   526
        res = self._search(session, lid, BASE)[0]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   527
        for attr in entity.e_schema.indexable_attributes():
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   528
            entity[attr] = res[self.user_rev_attrs[attr]]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   529
        return entity
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   530
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   531
    def after_entity_insertion(self, session, dn, entity):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   532
        """called by the repository after an entity stored here has been
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   533
        inserted in the system table.
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   534
        """
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   535
        super(LDAPUserSource, self).after_entity_insertion(session, dn, entity)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   536
        for group in self.user_default_groups:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   537
            session.execute('SET X in_group G WHERE X eid %(x)s, G name %(group)s',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   538
                            {'x': entity.eid, 'group': group}, 'x')
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   539
        # search for existant email first
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   540
        try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   541
            emailaddr = self._cache[dn][self.user_rev_attrs['email']]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   542
        except KeyError:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   543
            return
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   544
        rset = session.execute('EmailAddress X WHERE X address %(addr)s',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   545
                               {'addr': emailaddr})
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   546
        if rset:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   547
            session.execute('SET U primary_email X WHERE U eid %(u)s, X eid %(x)s',
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   548
                            {'x': rset[0][0], 'u': entity.eid}, 'u')
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   549
        else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   550
            # not found, create it
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   551
            _insert_email(session, emailaddr, entity.eid)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   552
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   553
    def update_entity(self, session, entity):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   554
        """replace an entity in the source"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   555
        raise RepositoryError('this source is read only')
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   556
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   557
    def delete_entity(self, session, etype, eid):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   558
        """delete an entity from the source"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   559
        raise RepositoryError('this source is read only')
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   560
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   561
def _insert_email(session, emailaddr, ueid):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   562
    session.execute('INSERT EmailAddress X: X address %(addr)s, U primary_email X '
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   563
                    'WHERE U eid %(x)s', {'addr': emailaddr, 'x': ueid}, 'x')
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   564
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   565
class GotDN(Exception):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   566
    """exception used when a dn localizing the searched user has been found"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   567
    def __init__(self, dn):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   568
        self.dn = dn
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   569
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   570
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   571
class RQL2LDAPFilter(object):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   572
    """generate an LDAP filter for a rql query"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   573
    def __init__(self, source, session, args=None, mainvars=()):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   574
        self.source = source
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   575
        self._ldap_attrs = source.user_rev_attrs
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   576
        self._base_filters = source.base_filters
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   577
        self._session = session
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   578
        if args is None:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   579
            args = {}
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   580
        self._args = args
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   581
        self.mainvars = mainvars
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   582
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   583
    def generate(self, selection, mainvarname):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   584
        self._filters = res = self._base_filters[:]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   585
        self._mainvarname = mainvarname
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   586
        self._eidfilters = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   587
        self._done_not = set()
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   588
        restriction = selection.where
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   589
        if isinstance(restriction, Relation):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   590
            # only a single relation, need to append result here (no AND/OR)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   591
            filter = restriction.accept(self)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   592
            if filter is not None:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   593
                res.append(filter)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   594
        elif restriction:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   595
            restriction.accept(self)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   596
        if len(res) > 1:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   597
            return self._eidfilters, '(&%s)' % ''.join(res)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   598
        return self._eidfilters, res[0]
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   599
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   600
    def visit_and(self, et):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   601
        """generate filter for a AND subtree"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   602
        for c in et.children:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   603
            part = c.accept(self)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   604
            if part:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   605
                self._filters.append(part)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   606
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   607
    def visit_or(self, ou):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   608
        """generate filter for a OR subtree"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   609
        res = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   610
        for c in ou.children:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   611
            part = c.accept(self)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   612
            if part:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   613
                res.append(part)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   614
        if res:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   615
            if len(res) > 1:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   616
                part = '(|%s)' % ''.join(res)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   617
            else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   618
                part = res[0]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   619
            self._filters.append(part)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   620
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   621
    def visit_not(self, node):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   622
        """generate filter for a OR subtree"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   623
        part = node.children[0].accept(self)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   624
        if part:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   625
            self._filters.append('(!(%s))'% part)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   626
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   627
    def visit_relation(self, relation):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   628
        """generate filter for a relation"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   629
        rtype = relation.r_type
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   630
        # don't care of type constraint statement (i.e. relation_type = 'is')
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   631
        if rtype == 'is':
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   632
            return ''
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   633
        lhs, rhs = relation.get_parts()
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   634
        # attribute relation
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3245
diff changeset
   635
        if self.source.schema.rschema(rtype).final:
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   636
            # dunno what to do here, don't pretend anything else
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   637
            if lhs.name != self._mainvarname:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   638
                if lhs.name in self.mainvars:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   639
                    # XXX check we don't have variable as rhs
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   640
                    return
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   641
                raise NotImplementedError
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   642
            rhs_vars = rhs.get_nodes(VariableRef)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   643
            if rhs_vars:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   644
                if len(rhs_vars) > 1:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   645
                    raise NotImplementedError
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   646
                # selected variable, nothing to do here
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   647
                return
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   648
            # no variables in the RHS
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   649
            if isinstance(rhs.children[0], Function):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   650
                res = rhs.children[0].accept(self)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   651
            elif rtype != 'has_text':
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   652
                res = self._visit_attribute_relation(relation)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   653
            else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   654
                raise NotImplementedError(relation)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   655
        # regular relation XXX todo: in_group
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   656
        else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   657
            raise NotImplementedError(relation)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   658
        return res
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   659
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   660
    def _visit_attribute_relation(self, relation):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   661
        """generate filter for an attribute relation"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   662
        lhs, rhs = relation.get_parts()
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   663
        lhsvar = lhs.variable
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   664
        if relation.r_type == 'eid':
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   665
            # XXX hack
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   666
            # skip comparison sign
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   667
            eid = int(rhs.children[0].accept(self))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   668
            if relation.neged(strict=True):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   669
                self._done_not.add(relation.parent)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   670
                self._eidfilters.append(lambda x: not x == eid)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   671
                return
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   672
            if rhs.operator != '=':
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   673
                filter = {'>': lambda x: x > eid,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   674
                          '>=': lambda x: x >= eid,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   675
                          '<': lambda x: x < eid,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   676
                          '<=': lambda x: x <= eid,
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   677
                          }[rhs.operator]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   678
                self._eidfilters.append(filter)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   679
                return
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   680
            dn = self.source.eid2extid(eid, self._session)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   681
            raise GotDN(dn)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   682
        try:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   683
            filter = '(%s%s)' % (self._ldap_attrs[relation.r_type],
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   684
                                 rhs.accept(self))
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   685
        except KeyError:
975
0928daea04e9 fix ldapsource w/ restriction on unsupported relation (return no results in that case)
sylvain.thenault@logilab.fr
parents: 938
diff changeset
   686
            # unsupported attribute
0928daea04e9 fix ldapsource w/ restriction on unsupported relation (return no results in that case)
sylvain.thenault@logilab.fr
parents: 938
diff changeset
   687
            self.source.warning('%s source can\'t handle relation %s, no '
0928daea04e9 fix ldapsource w/ restriction on unsupported relation (return no results in that case)
sylvain.thenault@logilab.fr
parents: 938
diff changeset
   688
                                'results will be returned from this source',
0928daea04e9 fix ldapsource w/ restriction on unsupported relation (return no results in that case)
sylvain.thenault@logilab.fr
parents: 938
diff changeset
   689
                                self.source.uri, relation)
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   690
            raise UnknownEid # trick to return no result
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   691
        return filter
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   692
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   693
    def visit_comparison(self, cmp):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   694
        """generate filter for a comparaison"""
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   695
        return '%s%s'% (cmp.operator, cmp.children[0].accept(self))
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   696
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   697
    def visit_mathexpression(self, mexpr):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   698
        """generate filter for a mathematic expression"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   699
        raise NotImplementedError
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   700
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   701
    def visit_function(self, function):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   702
        """generate filter name for a function"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   703
        if function.name == 'IN':
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   704
            return self.visit_in(function)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   705
        raise NotImplementedError
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   706
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   707
    def visit_in(self, function):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   708
        grandpapa = function.parent.parent
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   709
        ldapattr = self._ldap_attrs[grandpapa.r_type]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   710
        res = []
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   711
        for c in function.children:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   712
            part = c.accept(self)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   713
            if part:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   714
                res.append(part)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   715
        if res:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   716
            if len(res) > 1:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   717
                part = '(|%s)' % ''.join('(%s=%s)' % (ldapattr, v) for v in res)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   718
            else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   719
                part = '(%s=%s)' % (ldapattr, res[0])
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   720
        return part
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   721
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   722
    def visit_constant(self, constant):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   723
        """generate filter name for a constant"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   724
        value = constant.value
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   725
        if constant.type is None:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   726
            raise NotImplementedError
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   727
        if constant.type == 'Date':
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   728
            raise NotImplementedError
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   729
            #value = self.keyword_map[value]()
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   730
        elif constant.type == 'Substitute':
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   731
            value = self._args[constant.value]
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   732
        else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   733
            value = constant.value
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   734
        if isinstance(value, unicode):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   735
            value = value.encode('utf8')
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   736
        else:
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   737
            value = str(value)
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   738
        return escape_filter_chars(value)
1802
d628defebc17 delete-trailing-whitespace + some copyright update
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 1398
diff changeset
   739
257
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   740
    def visit_variableref(self, variableref):
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   741
        """get the sql name for a variable reference"""
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   742
        pass
4c7d3af7e94d restore multi-sources capabilities
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   743