server/sources/ldapfeed.py
author Rémi Cardona <remi.cardona@logilab.fr>
Fri, 07 Nov 2014 15:33:30 +0100
changeset 10349 efbbf1e93a04
parent 10011 340d4ef55b6f
child 10612 84468b90e9c1
permissions -rw-r--r--
[dataimport] Properly escape strings sent to COPY FROM (closes #5278743) See http://www.postgresql.org/docs/9.1/static/sql-copy.html#AEN64296 for escaping codes.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8674
001c1592060a [repo sources] move handling of source's url into abstract source as this becomes shared by most sources
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8589
diff changeset
     1
# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     3
#
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     4
# This file is part of CubicWeb.
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     5
#
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     9
# any later version.
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    10
#
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    14
# details.
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    15
#
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
8589
ee9ecfccc3e8 [ldapfeed] move docstring to the class instead of the module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8430
diff changeset
    18
"""cubicweb ldap feed source"""
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    20
from __future__ import division # XXX why?
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    21
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    22
from datetime import datetime
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    23
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
    24
import ldap
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    25
from ldap.ldapobject import ReconnectLDAPObject
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
    26
from ldap.filter import filter_format
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    27
from ldapurl import LDAPUrl
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
    28
8989
8742f4bf029f import merge_options directly from logilab.common
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8922
diff changeset
    29
from logilab.common.configuration import merge_options
8742f4bf029f import merge_options directly from logilab.common
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8922
diff changeset
    30
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    31
from cubicweb import ValidationError, AuthenticationError, Binary
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    32
from cubicweb.server import utils
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    33
from cubicweb.server.sources import datafeed
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
    34
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
    35
_ = unicode
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
    37
# search scopes
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    38
BASE = ldap.SCOPE_BASE
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    39
ONELEVEL = ldap.SCOPE_ONELEVEL
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    40
SUBTREE = ldap.SCOPE_SUBTREE
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    41
LDAP_SCOPES = {'BASE': ldap.SCOPE_BASE,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    42
               'ONELEVEL': ldap.SCOPE_ONELEVEL,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    43
               'SUBTREE': ldap.SCOPE_SUBTREE}
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    44
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    45
# map ldap protocol to their standard port
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    46
PROTO_PORT = {'ldap': 389,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    47
              'ldaps': 636,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    48
              'ldapi': None,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    49
              }
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    50
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    51
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    52
class LDAPFeedSource(datafeed.DataFeedSource):
8589
ee9ecfccc3e8 [ldapfeed] move docstring to the class instead of the module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8430
diff changeset
    53
    """LDAP feed source: unlike ldapuser source, this source is copy based and
ee9ecfccc3e8 [ldapfeed] move docstring to the class instead of the module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8430
diff changeset
    54
    will import ldap content (beside passwords for authentication) into the
ee9ecfccc3e8 [ldapfeed] move docstring to the class instead of the module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8430
diff changeset
    55
    system source.
ee9ecfccc3e8 [ldapfeed] move docstring to the class instead of the module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8430
diff changeset
    56
    """
8229
b7bc631816f7 [ldapfeed] make authentication actually working
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8188
diff changeset
    57
    support_entities = {'CWUser': False}
8428
f1b721ca73cc [sources/ldapfeed] do not user cwuri as url (closes #2380324)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8229
diff changeset
    58
    use_cwuri_as_url = False
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    59
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    60
    options = (
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    61
        ('auth-mode',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    62
         {'type' : 'choice',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    63
          'default': 'simple',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    64
          'choices': ('simple', 'cram_md5', 'digest_md5', 'gssapi'),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    65
          'help': 'authentication mode used to authenticate user to the ldap.',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    66
          'group': 'ldap-source', 'level': 3,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    67
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    68
        ('auth-realm',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    69
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    70
          'default': None,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    71
          'help': 'realm to use when using gssapi/kerberos authentication.',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    72
          'group': 'ldap-source', 'level': 3,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    73
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    74
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    75
        ('data-cnx-dn',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    76
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    77
          'default': '',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    78
          'help': 'user dn to use to open data connection to the ldap (eg used \
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    79
to respond to rql queries). Leave empty for anonymous bind',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    80
          'group': 'ldap-source', 'level': 1,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    81
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    82
        ('data-cnx-password',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    83
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    84
          'default': '',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    85
          'help': 'password to use to open data connection to the ldap (eg used to respond to rql queries). Leave empty for anonymous bind.',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    86
          'group': 'ldap-source', 'level': 1,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    87
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    88
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    89
        ('user-base-dn',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    90
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    91
          'default': '',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    92
          'help': 'base DN to lookup for users; disable user importation mechanism if unset',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    93
          'group': 'ldap-source', 'level': 1,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    94
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    95
        ('user-scope',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    96
         {'type' : 'choice',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    97
          'default': 'ONELEVEL',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    98
          'choices': ('BASE', 'ONELEVEL', 'SUBTREE'),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    99
          'help': 'user search scope (valid values: "BASE", "ONELEVEL", "SUBTREE")',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   100
          'group': 'ldap-source', 'level': 1,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   101
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   102
        ('user-classes',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   103
         {'type' : 'csv',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   104
          'default': ('top', 'posixAccount'),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   105
          'help': 'classes of user (with Active Directory, you want to say "user" here)',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   106
          'group': 'ldap-source', 'level': 1,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   107
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   108
        ('user-filter',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   109
         {'type': 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   110
          'default': '',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   111
          'help': 'additional filters to be set in the ldap query to find valid users',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   112
          'group': 'ldap-source', 'level': 2,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   113
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   114
        ('user-login-attr',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   115
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   116
          'default': 'uid',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   117
          'help': 'attribute used as login on authentication (with Active Directory, you want to use "sAMAccountName" here)',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   118
          'group': 'ldap-source', 'level': 1,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   119
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   120
        ('user-default-group',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   121
         {'type' : 'csv',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   122
          'default': ('users',),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   123
          'help': 'name of a group in which ldap users will be by default. \
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   124
You can set multiple groups by separating them by a comma.',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   125
          'group': 'ldap-source', 'level': 1,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   126
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   127
        ('user-attrs-map',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   128
         {'type' : 'named',
10011
340d4ef55b6f [ldapfeed] Reduce default value for user-attrs-map option (closes #3824889)
Paul Tonelli <paul.tonelli@logilab.fr>
parents: 9662
diff changeset
   129
          'default': {'uid': 'login'},
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   130
          'help': 'map from ldap user attributes to cubicweb attributes (with Active Directory, you want to use sAMAccountName:login,mail:email,givenName:firstname,sn:surname)',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   131
          'group': 'ldap-source', 'level': 1,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   132
          }),
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   133
        ('group-base-dn',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   134
         {'type' : 'string',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   135
          'default': '',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   136
          'help': 'base DN to lookup for groups; disable group importation mechanism if unset',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   137
          'group': 'ldap-source', 'level': 1,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   138
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   139
        ('group-scope',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   140
         {'type' : 'choice',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   141
          'default': 'ONELEVEL',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   142
          'choices': ('BASE', 'ONELEVEL', 'SUBTREE'),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   143
          'help': 'group search scope (valid values: "BASE", "ONELEVEL", "SUBTREE")',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   144
          'group': 'ldap-source', 'level': 1,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   145
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   146
        ('group-classes',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   147
         {'type' : 'csv',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   148
          'default': ('top', 'posixGroup'),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   149
          'help': 'classes of group',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   150
          'group': 'ldap-source', 'level': 1,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   151
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   152
        ('group-filter',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   153
         {'type': 'string',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   154
          'default': '',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   155
          'help': 'additional filters to be set in the ldap query to find valid groups',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   156
          'group': 'ldap-source', 'level': 2,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   157
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   158
        ('group-attrs-map',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   159
         {'type' : 'named',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   160
          'default': {'cn': 'name', 'memberUid': 'member'},
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   161
          'help': 'map from ldap group attributes to cubicweb attributes',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   162
          'group': 'ldap-source', 'level': 1,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   163
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   164
    )
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   165
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   166
    options = merge_options(datafeed.DataFeedSource.options + options,
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   167
                            optgroup='ldap-source',)
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   168
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   169
    _conn = None
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   170
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   171
    def update_config(self, source_entity, typedconfig):
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   172
        """update configuration from source entity. `typedconfig` is config
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   173
        properly typed with defaults set
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   174
        """
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   175
        super(LDAPFeedSource, self).update_config(source_entity, typedconfig)
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   176
        self.authmode = typedconfig['auth-mode']
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   177
        self._authenticate = getattr(self, '_auth_%s' % self.authmode)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   178
        self.cnx_dn = typedconfig['data-cnx-dn']
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   179
        self.cnx_pwd = typedconfig['data-cnx-password']
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   180
        self.user_base_dn = str(typedconfig['user-base-dn'])
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   181
        self.user_base_scope = globals()[typedconfig['user-scope']]
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   182
        self.user_login_attr = typedconfig['user-login-attr']
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   183
        self.user_default_groups = typedconfig['user-default-group']
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   184
        self.user_attrs = {'dn': 'eid', 'modifyTimestamp': 'modification_date'}
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   185
        self.user_attrs.update(typedconfig['user-attrs-map'])
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   186
        self.user_rev_attrs = dict((v, k) for k, v in self.user_attrs.iteritems())
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   187
        self.base_filters = [filter_format('(%s=%s)', ('objectClass', o))
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   188
                             for o in typedconfig['user-classes']]
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   189
        if typedconfig['user-filter']:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   190
            self.base_filters.append(typedconfig['user-filter'])
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   191
        self.group_base_dn = str(typedconfig['group-base-dn'])
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   192
        self.group_base_scope = LDAP_SCOPES[typedconfig['group-scope']]
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   193
        self.group_attrs = typedconfig['group-attrs-map']
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   194
        self.group_attrs = {'dn': 'eid', 'modifyTimestamp': 'modification_date'}
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   195
        self.group_attrs.update(typedconfig['group-attrs-map'])
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   196
        self.group_rev_attrs = dict((v, k) for k, v in self.group_attrs.iteritems())
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   197
        self.group_base_filters = [filter_format('(%s=%s)', ('objectClass', o))
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   198
                                   for o in typedconfig['group-classes']]
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   199
        if typedconfig['group-filter']:
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   200
            self.group_base_filters.append(typedconfig['group-filter'])
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   201
        self._conn = None
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   202
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   203
    def _entity_update(self, source_entity):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   204
        super(LDAPFeedSource, self)._entity_update(source_entity)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   205
        if self.urls:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   206
            if len(self.urls) > 1:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   207
                raise ValidationError(source_entity.eid, {'url': _('can only have one url')})
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   208
            try:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   209
                protocol, hostport = self.urls[0].split('://')
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   210
            except ValueError:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   211
                raise ValidationError(source_entity.eid, {'url': _('badly formatted url')})
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   212
            if protocol not in PROTO_PORT:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   213
                raise ValidationError(source_entity.eid, {'url': _('unsupported protocol')})
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   214
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   215
    def connection_info(self):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   216
        assert len(self.urls) == 1, self.urls
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   217
        protocol, hostport = self.urls[0].split('://')
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   218
        if protocol != 'ldapi' and not ':' in hostport:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   219
            hostport = '%s:%s' % (hostport, PROTO_PORT[protocol])
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   220
        return protocol, hostport
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   221
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   222
    def authenticate(self, cnx, login, password=None, **kwargs):
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   223
        """return CWUser eid for the given login/password if this account is
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   224
        defined in this source, else raise `AuthenticationError`
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   225
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   226
        two queries are needed since passwords are stored crypted, so we have
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   227
        to fetch the salt first
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   228
        """
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   229
        self.info('ldap authenticate %s', login)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   230
        if not password:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   231
            # On Windows + ADAM this would have succeeded (!!!)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   232
            # You get Authenticated as: 'NT AUTHORITY\ANONYMOUS LOGON'.
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   233
            # we really really don't want that
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   234
            raise AuthenticationError()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   235
        searchfilter = [filter_format('(%s=%s)', (self.user_login_attr, login))]
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   236
        searchfilter.extend(self.base_filters)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   237
        searchstr = '(&%s)' % ''.join(searchfilter)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   238
        # first search the user
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   239
        try:
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   240
            user = self._search(cnx, self.user_base_dn,
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   241
                                self.user_base_scope, searchstr)[0]
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   242
        except (IndexError, ldap.SERVER_DOWN):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   243
            # no such user
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   244
            raise AuthenticationError()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   245
        # check password by establishing a (unused) connection
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   246
        try:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   247
            self._connect(user, password)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   248
        except ldap.LDAPError as ex:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   249
            # Something went wrong, most likely bad credentials
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   250
            self.info('while trying to authenticate %s: %s', user, ex)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   251
            raise AuthenticationError()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   252
        except Exception:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   253
            self.error('while trying to authenticate %s', user, exc_info=True)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   254
            raise AuthenticationError()
9662
f13ae1fea212 [repository] 'session' argument is always given to extid2eid, make it mandatory and simplify code accordingly
Julien Cristau <julien.cristau@logilab.fr>
parents: 9512
diff changeset
   255
        eid = self.repo.extid2eid(self, user['dn'], 'CWUser', cnx, insert=False)
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   256
        if eid < 0:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   257
            # user has been moved away from this source
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   258
            raise AuthenticationError()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   259
        return eid
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   260
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   261
    def _connect(self, user=None, userpwd=None):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   262
        protocol, hostport = self.connection_info()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   263
        self.info('connecting %s://%s as %s', protocol, hostport,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   264
                  user and user['dn'] or 'anonymous')
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   265
        # don't require server certificate when using ldaps (will
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   266
        # enable self signed certs)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   267
        ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   268
        url = LDAPUrl(urlscheme=protocol, hostport=hostport)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   269
        conn = ReconnectLDAPObject(url.initializeUrl())
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   270
        # Set the protocol version - version 3 is preferred
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   271
        try:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   272
            conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   273
        except ldap.LDAPError: # Invalid protocol version, fall back safely
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   274
            conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION2)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   275
        # Deny auto-chasing of referrals to be safe, we handle them instead
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   276
        # Required for AD
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   277
        try:
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9462
diff changeset
   278
            conn.set_option(ldap.OPT_REFERRALS, 0)
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   279
        except ldap.LDAPError: # Cannot set referrals, so do nothing
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9462
diff changeset
   280
            pass
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   281
        #conn.set_option(ldap.OPT_NETWORK_TIMEOUT, conn_timeout)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   282
        #conn.timeout = op_timeout
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   283
        # Now bind with the credentials given. Let exceptions propagate out.
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   284
        if user is None:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   285
            # XXX always use simple bind for data connection
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   286
            if not self.cnx_dn:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   287
                conn.simple_bind_s(self.cnx_dn, self.cnx_pwd)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   288
            else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   289
                self._authenticate(conn, {'dn': self.cnx_dn}, self.cnx_pwd)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   290
        else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   291
            # user specified, we want to check user/password, no need to return
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   292
            # the connection which will be thrown out
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   293
            self._authenticate(conn, user, userpwd)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   294
        return conn
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   295
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   296
    def _auth_simple(self, conn, user, userpwd):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   297
        conn.simple_bind_s(user['dn'], userpwd)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   298
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   299
    def _auth_cram_md5(self, conn, user, userpwd):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   300
        from ldap import sasl
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   301
        auth_token = sasl.cram_md5(user['dn'], userpwd)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   302
        conn.sasl_interactive_bind_s('', auth_token)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   303
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   304
    def _auth_digest_md5(self, conn, user, userpwd):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   305
        from ldap import sasl
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   306
        auth_token = sasl.digest_md5(user['dn'], userpwd)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   307
        conn.sasl_interactive_bind_s('', auth_token)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   308
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   309
    def _auth_gssapi(self, conn, user, userpwd):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   310
        # print XXX not proper sasl/gssapi
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   311
        import kerberos
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   312
        if not kerberos.checkPassword(user[self.user_login_attr], userpwd):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   313
            raise Exception('BAD login / mdp')
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   314
        #from ldap import sasl
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   315
        #conn.sasl_interactive_bind_s('', sasl.gssapi())
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   316
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   317
    def _search(self, cnx, base, scope,
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   318
                searchstr='(objectClass=*)', attrs=()):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   319
        """make an ldap query"""
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   320
        self.debug('ldap search %s %s %s %s %s', self.uri, base, scope,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   321
                   searchstr, list(attrs))
9462
375fc1868b11 [ldap] simplify connection handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9461
diff changeset
   322
        if self._conn is None:
375fc1868b11 [ldap] simplify connection handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9461
diff changeset
   323
            self._conn = self._connect()
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   324
        ldapcnx = self._conn
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   325
        try:
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   326
            res = ldapcnx.search_s(base, scope, searchstr, attrs)
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   327
        except ldap.PARTIAL_RESULTS:
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   328
            res = ldapcnx.result(all=0)[1]
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   329
        except ldap.NO_SUCH_OBJECT:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   330
            self.info('ldap NO SUCH OBJECT %s %s %s', base, scope, searchstr)
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   331
            self._process_no_such_object(cnx, base)
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   332
            return []
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   333
        # except ldap.REFERRAL as e:
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   334
        #     ldapcnx = self.handle_referral(e)
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   335
        #     try:
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   336
        #         res = ldapcnx.search_s(base, scope, searchstr, attrs)
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   337
        #     except ldap.PARTIAL_RESULTS:
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   338
        #         res_type, res = ldapcnx.result(all=0)
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   339
        result = []
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   340
        for rec_dn, rec_dict in res:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   341
            # When used against Active Directory, "rec_dict" may not be
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   342
            # be a dictionary in some cases (instead, it can be a list)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   343
            #
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   344
            # An example of a useless "res" entry that can be ignored
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   345
            # from AD is
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   346
            # (None, ['ldap://ForestDnsZones.PORTAL.LOCAL/DC=ForestDnsZones,DC=PORTAL,DC=LOCAL'])
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   347
            # This appears to be some sort of internal referral, but
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   348
            # we can't handle it, so we need to skip over it.
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   349
            try:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   350
                items = rec_dict.iteritems()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   351
            except AttributeError:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   352
                continue
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   353
            else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   354
                itemdict = self._process_ldap_item(rec_dn, items)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   355
                result.append(itemdict)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   356
        self.debug('ldap built results %s', len(result))
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   357
        return result
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   358
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   359
    def _process_ldap_item(self, dn, iterator):
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   360
        """Turn an ldap received item into a proper dict."""
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   361
        itemdict = {'dn': dn}
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   362
        for key, value in iterator:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   363
            if self.user_attrs.get(key) == 'upassword': # XXx better password detection
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   364
                value = value[0].encode('utf-8')
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   365
                # we only support ldap_salted_sha1 for ldap sources, see: server/utils.py
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   366
                if not value.startswith('{SSHA}'):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   367
                    value = utils.crypt_password(value)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   368
                itemdict[key] = Binary(value)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   369
            elif self.user_attrs.get(key) == 'modification_date':
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   370
                itemdict[key] = datetime.strptime(value[0], '%Y%m%d%H%M%SZ')
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   371
            else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   372
                value = [unicode(val, 'utf-8', 'replace') for val in value]
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   373
                if len(value) == 1:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   374
                    itemdict[key] = value = value[0]
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   375
                else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   376
                    itemdict[key] = value
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   377
        # we expect memberUid to be a list of user ids, make sure of it
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   378
        member = self.group_rev_attrs['member']
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   379
        if isinstance(itemdict.get(member), basestring):
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   380
            itemdict[member] = [itemdict[member]]
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   381
        return itemdict
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   382
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   383
    def _process_no_such_object(self, cnx, dn):
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   384
        """Some search return NO_SUCH_OBJECT error, handle this (usually because
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   385
        an object whose dn is no more existent in ldap as been encountered).
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   386
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   387
        Do nothing by default, let sub-classes handle that.
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   388
        """