server/sources/ldapfeed.py
author Rémi Cardona <remi.cardona@logilab.fr>
Fri, 18 Sep 2015 11:54:12 +0200
changeset 10706 b261d90149d0
parent 10666 7f6b5f023884
child 10766 d730f91251af
permissions -rw-r--r--
[server] Port BFSS to py3k The BFSS API changes in python 3: * 'defaultdir' MUST be a unicode object * 'fsencoding' MUST NOT be set In python 2, fsencoding handles both the encoding of file paths on the file system (utf-8 by default, but the system may actually be using something else) and the encoding of file paths that will be stored in the database. So in python 3, we wipe the slate clean: * rely on sys.getfilesystemencoding() to convert unicode objects to bytes * always encode paths to utf-8 for storage in the database Caveat emptor / here be dragons: * sys.getfilesystemencoding() depends on the current locale, which therefore MUST be set properly * when migrating an existing instance from py2 to py3, one MAY need to reencode file paths stored in the database
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
10612
84468b90e9c1 [py3k] basestring → six.string_types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10011
diff changeset
    24
from six import string_types
84468b90e9c1 [py3k] basestring → six.string_types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10011
diff changeset
    25
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
    26
import ldap
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    27
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
    28
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
    29
from ldapurl import LDAPUrl
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
    30
8989
8742f4bf029f import merge_options directly from logilab.common
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8922
diff changeset
    31
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
    32
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    33
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
    34
from cubicweb.server import utils
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    35
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
    36
10666
7f6b5f023884 [py3k] replace '_ = unicode' in global scope (closes #7589459)
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10662
diff changeset
    37
from cubicweb import _
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
    39
# search scopes
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    40
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
    41
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
    42
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
    43
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
    44
               '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
    45
               '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
    46
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    47
# 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
    48
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
    49
              'ldaps': 636,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    50
              'ldapi': None,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    51
              }
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    52
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    53
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    54
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
    55
    """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
    56
    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
    57
    system source.
ee9ecfccc3e8 [ldapfeed] move docstring to the class instead of the module
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8430
diff changeset
    58
    """
8229
b7bc631816f7 [ldapfeed] make authentication actually working
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8188
diff changeset
    59
    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
    60
    use_cwuri_as_url = False
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    62
    options = (
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    63
        ('auth-mode',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    64
         {'type' : 'choice',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    65
          'default': 'simple',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    66
          '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
    67
          '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
    68
          '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
    69
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    70
        ('auth-realm',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    71
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    72
          'default': None,
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    73
          '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
    74
          '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
    75
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    76
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    77
        ('data-cnx-dn',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    78
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    79
          'default': '',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    80
          '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
    81
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
    82
          '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
    83
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    84
        ('data-cnx-password',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    85
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    86
          'default': '',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    87
          '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
    88
          '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
    89
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    90
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    91
        ('user-base-dn',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    92
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    93
          'default': '',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    94
          '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
    95
          '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
    96
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    97
        ('user-scope',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    98
         {'type' : 'choice',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
    99
          'default': 'ONELEVEL',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   100
          '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
   101
          '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
   102
          '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
   103
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   104
        ('user-classes',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   105
         {'type' : 'csv',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   106
          'default': ('top', 'posixAccount'),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   107
          '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
   108
          '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
   109
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   110
        ('user-filter',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   111
         {'type': 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   112
          'default': '',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   113
          '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
   114
          '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
   115
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   116
        ('user-login-attr',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   117
         {'type' : 'string',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   118
          'default': 'uid',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   119
          '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
   120
          '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
   121
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   122
        ('user-default-group',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   123
         {'type' : 'csv',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   124
          'default': ('users',),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   125
          '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
   126
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
   127
          '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
   128
          }),
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   129
        ('user-attrs-map',
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   130
         {'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
   131
          '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
   132
          '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
   133
          '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
   134
          }),
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   135
        ('group-base-dn',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   136
         {'type' : 'string',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   137
          'default': '',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   138
          '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
   139
          'group': 'ldap-source', 'level': 1,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   140
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   141
        ('group-scope',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   142
         {'type' : 'choice',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   143
          'default': 'ONELEVEL',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   144
          'choices': ('BASE', 'ONELEVEL', 'SUBTREE'),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   145
          '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
   146
          'group': 'ldap-source', 'level': 1,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   147
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   148
        ('group-classes',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   149
         {'type' : 'csv',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   150
          'default': ('top', 'posixGroup'),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   151
          'help': 'classes of group',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   152
          'group': 'ldap-source', 'level': 1,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   153
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   154
        ('group-filter',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   155
         {'type': 'string',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   156
          'default': '',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   157
          '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
   158
          'group': 'ldap-source', 'level': 2,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   159
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   160
        ('group-attrs-map',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   161
         {'type' : 'named',
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   162
          'default': {'cn': 'name', 'memberUid': 'member'},
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   163
          '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
   164
          'group': 'ldap-source', 'level': 1,
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   165
          }),
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   166
    )
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   167
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   168
    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
   169
                            optgroup='ldap-source',)
8188
1867e252e487 [repository] ldap-feed source. Closes #2086984
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   170
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   171
    _conn = None
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   172
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   173
    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
   174
        """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
   175
        properly typed with defaults set
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   176
        """
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   177
        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
   178
        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
   179
        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
   180
        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
   181
        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
   182
        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
   183
        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
   184
        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
   185
        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
   186
        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
   187
        self.user_attrs.update(typedconfig['user-attrs-map'])
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10612
diff changeset
   188
        self.user_rev_attrs = dict((v, k) for k, v in self.user_attrs.items())
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   189
        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
   190
                             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
   191
        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
   192
            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
   193
        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
   194
        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
   195
        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
   196
        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
   197
        self.group_attrs.update(typedconfig['group-attrs-map'])
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10612
diff changeset
   198
        self.group_rev_attrs = dict((v, k) for k, v in self.group_attrs.items())
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   199
        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
   200
                                   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
   201
        if typedconfig['group-filter']:
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   202
            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
   203
        self._conn = None
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   204
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   205
    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
   206
        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
   207
        if self.urls:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   208
            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
   209
                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
   210
            try:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   211
                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
   212
            except ValueError:
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': _('badly formatted url')})
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   214
            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
   215
                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
   216
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   217
    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
   218
        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
   219
        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
   220
        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
   221
            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
   222
        return protocol, hostport
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   223
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   224
    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
   225
        """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
   226
        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
   227
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   228
        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
   229
        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
   230
        """
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   231
        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
   232
        if not password:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   233
            # 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
   234
            # 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
   235
            # 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
   236
            raise AuthenticationError()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   237
        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
   238
        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
   239
        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
   240
        # 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
   241
        try:
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   242
            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
   243
                                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
   244
        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
   245
            # no such user
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   246
            raise AuthenticationError()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   247
        # 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
   248
        try:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   249
            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
   250
        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
   251
            # 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
   252
            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
   253
            raise AuthenticationError()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   254
        except Exception:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   255
            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
   256
            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
   257
        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
   258
        if eid < 0:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   259
            # 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
   260
            raise AuthenticationError()
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   261
        return eid
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   262
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   263
    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
   264
        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
   265
        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
   266
                  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
   267
        # 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
   268
        # 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
   269
        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
   270
        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
   271
        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
   272
        # 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
   273
        try:
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.VERSION3)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   275
        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
   276
            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
   277
        # 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
   278
        # Required for AD
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   279
        try:
9468
39b7a91a3f4c [repo] pylint cleanup, mainly of imports, with a bit of style
Julien Cristau <julien.cristau@logilab.fr>
parents: 9462
diff changeset
   280
            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
   281
        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
   282
            pass
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   283
        #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
   284
        #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
   285
        # 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
   286
        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
   287
            # 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
   288
            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
   289
                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
   290
            else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   291
                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
   292
        else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   293
            # 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
   294
            # 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
   295
            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
   296
        return conn
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   297
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   298
    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
   299
        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
   300
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   301
    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
   302
        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
   303
        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
   304
        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
   305
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   306
    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
   307
        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
   308
        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
   309
        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
   310
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   311
    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
   312
        # 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
   313
        import kerberos
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   314
        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
   315
            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
   316
        #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
   317
        #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
   318
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   319
    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
   320
                searchstr='(objectClass=*)', attrs=()):
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   321
        """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
   322
        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
   323
                   searchstr, list(attrs))
9462
375fc1868b11 [ldap] simplify connection handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9461
diff changeset
   324
        if self._conn is None:
375fc1868b11 [ldap] simplify connection handling
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 9461
diff changeset
   325
            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
   326
        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
   327
        try:
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.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
   329
        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
   330
            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
   331
        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
   332
            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
   333
            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
   334
            return []
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   335
        # 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
   336
        #     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
   337
        #     try:
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 = 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
   339
        #     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
   340
        #         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
   341
        result = []
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   342
        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
   343
            # 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
   344
            # 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
   345
            #
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   346
            # 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
   347
            # from AD is
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   348
            # (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
   349
            # 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
   350
            # 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
   351
            try:
10662
10942ed172de [py3k] dict.iteritems → dict.items
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10612
diff changeset
   352
                items = rec_dict.items()
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   353
            except AttributeError:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   354
                continue
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   355
            else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   356
                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
   357
                result.append(itemdict)
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   358
        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
   359
        return result
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   360
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   361
    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
   362
        """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
   363
        itemdict = {'dn': dn}
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   364
        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
   365
            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
   366
                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
   367
                # 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
   368
                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
   369
                    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
   370
                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
   371
            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
   372
                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
   373
            else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   374
                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
   375
                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
   376
                    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
   377
                else:
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   378
                    itemdict[key] = value
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   379
        # 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
   380
        member = self.group_rev_attrs['member']
10612
84468b90e9c1 [py3k] basestring → six.string_types
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10011
diff changeset
   381
        if isinstance(itemdict.get(member), string_types):
8922
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   382
            itemdict[member] = [itemdict[member]]
715b9eec6da9 [ldapfeed] Add support for LDAP groups (closes #2528116)
David Douard <david.douard@logilab.fr>
parents: 8708
diff changeset
   383
        return itemdict
9461
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   384
9512
88dc96fc9fc1 [server] use a connection instead of a session for user authentication
Julien Cristau <julien.cristau@logilab.fr>
parents: 9468
diff changeset
   385
    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
   386
        """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
   387
        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
   388
fc3b8798737c [ldap] merge cw.server.ldaputils back into ldapfeed source
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8989
diff changeset
   389
        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
   390
        """