[Python-modules-commits] [django-auth-ldap] 01/20: Import django-auth-ldap_1.2.10+dfsg.orig.tar.gz

Michael Fladischer fladi at moszumanska.debian.org
Sun Mar 19 08:08:20 UTC 2017


This is an automated email from the git hooks/post-receive script.

fladi pushed a commit to branch master
in repository django-auth-ldap.

commit 041fe276d3d9753ff0a455423ca517459335477e
Author: Michael Fladischer <FladischerMichael at fladi.at>
Date:   Fri Mar 17 20:22:55 2017 +0100

    Import django-auth-ldap_1.2.10+dfsg.orig.tar.gz
---
 CHANGES                                | 24 +++++++++++---
 PKG-INFO                               |  3 +-
 django_auth_ldap.egg-info/PKG-INFO     |  3 +-
 django_auth_ldap.egg-info/requires.txt |  2 +-
 django_auth_ldap/__init__.py           |  2 +-
 django_auth_ldap/backend.py            | 24 ++++++++------
 django_auth_ldap/config.py             | 11 ++++---
 django_auth_ldap/tests.py              | 52 ++++++++++++++++++++++++++++--
 docs/source/conf.py                    |  2 +-
 docs/source/reference.rst              | 27 ++++++++++++----
 docs/source/users.rst                  | 58 ++++++++++++++++++++--------------
 setup.cfg                              |  1 -
 setup.py                               |  5 +--
 tox.ini                                | 21 ++++++++++--
 14 files changed, 175 insertions(+), 60 deletions(-)

diff --git a/CHANGES b/CHANGES
index 968a1cc..721c122 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,21 @@
-v1.2.7 - 2015-09-29
--------------------
+v1.2.9 - 2017-02-14 - Fix python-ldap incompatibility
+-----------------------------------------------------
+
+- Fix `#65`_: Ignore python-ldap documentation and accept
+  :data:`ldap.RES_SEARCH_ENTRY` from :meth:`ldap.LDAPObject.result`.
+
+.. _#65: https://bitbucket.org/psagers/django-auth-ldap/issues/65/
+
+
+v1.2.8 - 2016-04-18 - AUTH_LDAP_USER_ATTRLIST
+---------------------------------------------
+
+- Add :setting:`AUTH_LDAP_USER_ATTRLIST` to override the set of attributes
+  requested from the LDAP server.
+
+
+v1.2.7 - 2015-09-29 - Python 3
+------------------------------
 
 - Support Python 3 with `pyldap <https://pypi.python.org/pypi/pyldap>`_.
 
@@ -24,8 +40,8 @@ v1.2.5 - 2015-01-30
   :setting:`AUTH_LDAP_USER_SEARCH`.
 
 
-v1.2.4 - 2014-12-28
--------------------
+v1.2.4 - 2014-12-28 - nisNetgroup support
+-----------------------------------------
 
 - Add support for nisNetgroup groups (thanks to Christopher Bartz).
 
diff --git a/PKG-INFO b/PKG-INFO
index c482b3e..6643b4f 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: django-auth-ldap
-Version: 1.2.7
+Version: 1.2.10
 Summary: Django LDAP authentication backend
 Home-page: http://bitbucket.org/psagers/django-auth-ldap/
 Author: Peter Sagerson
@@ -83,6 +83,7 @@ Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
 Classifier: Framework :: Django
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: System Administrators
diff --git a/django_auth_ldap.egg-info/PKG-INFO b/django_auth_ldap.egg-info/PKG-INFO
index c482b3e..6643b4f 100644
--- a/django_auth_ldap.egg-info/PKG-INFO
+++ b/django_auth_ldap.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: django-auth-ldap
-Version: 1.2.7
+Version: 1.2.10
 Summary: Django LDAP authentication backend
 Home-page: http://bitbucket.org/psagers/django-auth-ldap/
 Author: Peter Sagerson
@@ -83,6 +83,7 @@ Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
 Classifier: Framework :: Django
 Classifier: Intended Audience :: Developers
 Classifier: Intended Audience :: System Administrators
diff --git a/django_auth_ldap.egg-info/requires.txt b/django_auth_ldap.egg-info/requires.txt
index 7ba1718..6d5787b 100644
--- a/django_auth_ldap.egg-info/requires.txt
+++ b/django_auth_ldap.egg-info/requires.txt
@@ -1,2 +1,2 @@
 django
-python-ldap >= 2.0
\ No newline at end of file
+python-ldap >= 2.0
diff --git a/django_auth_ldap/__init__.py b/django_auth_ldap/__init__.py
index 065d66c..4d81c7f 100644
--- a/django_auth_ldap/__init__.py
+++ b/django_auth_ldap/__init__.py
@@ -1,2 +1,2 @@
-version = (1, 2, 7)
+version = (1, 2, 10)
 version_string = '.'.join(map(str, version))
diff --git a/django_auth_ldap/backend.py b/django_auth_ldap/backend.py
index 3cf6fd2..81ad4ae 100644
--- a/django_auth_ldap/backend.py
+++ b/django_auth_ldap/backend.py
@@ -70,10 +70,15 @@ except ImportError:
 # Support Django 1.5's custom user models
 try:
     from django.contrib.auth import get_user_model
-    get_user_username = lambda u: u.get_username()
+
+    def get_user_username(user):
+        return user.get_username()
 except ImportError:
-    get_user_model = lambda: User                                        # noqa
-    get_user_username = lambda u: u.username
+    def get_user_model():
+        return User
+
+    def get_user_username(user):
+        return user.username
 
 # Small compatibility hack
 try:
@@ -159,12 +164,12 @@ class LDAPBackend(object):
     #
 
     def authenticate(self, username, password, **kwargs):
-        if len(password) == 0 and not self.settings.PERMIT_EMPTY_PASSWORD:
+        if bool(password) or self.settings.PERMIT_EMPTY_PASSWORD:
+            ldap_user = _LDAPUser(self, username=username.strip())
+            user = ldap_user.authenticate(password)
+        else:
             logger.debug('Rejecting empty password for %s' % username)
-            return None
-
-        ldap_user = _LDAPUser(self, username=username.strip())
-        user = ldap_user.authenticate(password)
+            user = None
 
         return user
 
@@ -456,7 +461,7 @@ class _LDAPUser(object):
 
     def _load_user_attrs(self):
         if self.dn is not None:
-            search = LDAPSearch(self.dn, ldap.SCOPE_BASE)
+            search = LDAPSearch(self.dn, ldap.SCOPE_BASE, attrlist=self.settings.USER_ATTRLIST)
             results = search.execute(self.connection)
 
             if results is not None and len(results) > 0:
@@ -890,6 +895,7 @@ class LDAPSettings(object):
         'REQUIRE_GROUP': None,
         'SERVER_URI': 'ldap://localhost',
         'START_TLS': False,
+        'USER_ATTRLIST': None,
         'USER_ATTR_MAP': {},
         'USER_DN_TEMPLATE': None,
         'USER_FLAGS_BY_GROUP': {},
diff --git a/django_auth_ldap/config.py b/django_auth_ldap/config.py
index 47a52b0..7702714 100644
--- a/django_auth_ldap/config.py
+++ b/django_auth_ldap/config.py
@@ -105,7 +105,7 @@ class LDAPSearch(object):
     documented for configuration purposes. Internal clients may use the other
     methods to refine and execute the search.
     """
-    def __init__(self, base_dn, scope, filterstr=u'(objectClass=*)'):
+    def __init__(self, base_dn, scope, filterstr=u'(objectClass=*)', attrlist=None):
         """
         These parameters are the same as the first three parameters to
         ldap.search_s.
@@ -113,6 +113,7 @@ class LDAPSearch(object):
         self.base_dn = base_dn
         self.scope = scope
         self.filterstr = filterstr
+        self.attrlist = attrlist
         self.ldap = _LDAPConfig.get_ldap()
 
     def search_with_additional_terms(self, term_dict, escape=True):
@@ -159,7 +160,8 @@ class LDAPSearch(object):
             filterstr = self.filterstr % filterargs
             results = connection.search_s(force_str(self.base_dn),
                                           self.scope,
-                                          force_str(filterstr))
+                                          force_str(filterstr),
+                                          self.attrlist)
         except ldap.LDAPError as e:
             results = []
             logger.error(u"search_s('%s', %d, '%s') raised %s" %
@@ -182,7 +184,8 @@ class LDAPSearch(object):
         try:
             filterstr = self.filterstr % filterargs
             msgid = connection.search(force_str(self.base_dn),
-                                      self.scope, force_str(filterstr))
+                                      self.scope, force_str(filterstr),
+                                      self.attrlist)
         except ldap.LDAPError as e:
             msgid = None
             logger.error(u"search('%s', %d, '%s') raised %s" %
@@ -196,7 +199,7 @@ class LDAPSearch(object):
         """
         try:
             kind, results = connection.result(msgid)
-            if kind != ldap.RES_SEARCH_RESULT:
+            if kind not in (ldap.RES_SEARCH_ENTRY, ldap.RES_SEARCH_RESULT):
                 results = []
         except ldap.LDAPError as e:
             results = []
diff --git a/django_auth_ldap/tests.py b/django_auth_ldap/tests.py
index 8d3ecbc..61f2fcc 100644
--- a/django_auth_ldap/tests.py
+++ b/django_auth_ldap/tests.py
@@ -55,7 +55,8 @@ except ImportError:
 try:
     from django.test.utils import override_settings
 except ImportError:
-    override_settings = lambda *args, **kwargs: (lambda v: v)
+    def override_settings(*args, **kwargs):
+        return lambda v: v
 
 from django_auth_ldap.models import TestUser, TestProfile
 from django_auth_ldap import backend
@@ -427,7 +428,7 @@ class LDAPTest(TestCase):
         )
         # mockldap doesn't handle case-insensitive matching properly.
         self.ldapobj.search_s.seed('ou=people,o=test', ldap.SCOPE_SUBTREE,
-                                   '(uid=Alice)')([self.alice])
+                                   '(uid=Alice)', None)([self.alice])
         User.objects.create(username='alice')
 
         user = self.backend.authenticate(username='Alice', password='password')
@@ -493,7 +494,7 @@ class LDAPTest(TestCase):
             self.ldapobj.methods_called(with_args=True),
             [('initialize', ('ldap://localhost',), {}),
              ('simple_bind_s', ('', ''), {}),
-             ('search_s', ('ou=people,o=test', ldap.SCOPE_SUBTREE, '(uid=alice\\2a)'), {})]
+             ('search_s', ('ou=people,o=test', ldap.SCOPE_SUBTREE, '(uid=alice\\2a)', None), {})]
         )
 
     def test_search_bind_no_user(self):
@@ -616,6 +617,29 @@ class LDAPTest(TestCase):
             ['initialize', 'simple_bind_s', 'simple_bind_s', 'search_s']
         )
 
+    def test_poplate_with_attrlist(self):
+        self._init_settings(
+            USER_DN_TEMPLATE='uid=%(user)s,ou=people,o=test',
+            USER_ATTR_MAP={'first_name': 'givenName', 'last_name': 'sn'},
+            USER_ATTRLIST=['*', '+'],
+        )
+
+        user = self.backend.authenticate(username='alice', password='password')
+
+        self.assertEqual(user.username, 'alice')
+        self.assertEqual(user.first_name, 'Alice')
+        self.assertEqual(user.last_name, 'Adams')
+
+        # init, bind as user, bind anonymous, lookup user attrs
+        self.assertEqual(
+            self.ldapobj.methods_called(),
+            ['initialize', 'simple_bind_s', 'simple_bind_s', 'search_s']
+        )
+        self.assertEqual(
+            self.ldapobj.methods_called(with_args=True)[3],
+            ('search_s', ('uid=alice,ou=people,o=test', ldap.SCOPE_BASE, '(objectClass=*)', ['*', '+']), {})
+        )
+
     def test_bind_as_user(self):
         self._init_settings(
             USER_DN_TEMPLATE='uid=%(user)s,ou=people,o=test',
@@ -1261,6 +1285,20 @@ class LDAPTest(TestCase):
             ['initialize', 'simple_bind_s']
         )
 
+    def test_permit_null_password(self):
+        self._init_settings(
+            USER_DN_TEMPLATE='uid=%(user)s,ou=people,o=test',
+            PERMIT_EMPTY_PASSWORD=True,
+        )
+
+        alice = self.backend.authenticate(username=u'alice', password=None)
+
+        self.assertEqual(alice, None)
+        self.assertEqual(
+            self.ldapobj.methods_called(),
+            ['initialize', 'simple_bind_s']
+        )
+
     def test_pickle(self):
         self._init_settings(
             USER_DN_TEMPLATE='uid=%(user)s,ou=people,o=test',
@@ -1282,6 +1320,14 @@ class LDAPTest(TestCase):
         self.assertTrue(self.backend.has_perm(alice, "auth.add_user"))
         self.assertTrue(self.backend.has_module_perms(alice, "auth"))
 
+    def test_search_attrlist(self):
+        search = LDAPSearch("ou=people,o=test", ldap.SCOPE_SUBTREE, '(uid=alice)', ['*', '+'])
+        search.execute(self.ldapobj)
+        self.assertEqual(
+            self.ldapobj.methods_called(with_args=True),
+            [('search_s', ('ou=people,o=test', ldap.SCOPE_SUBTREE, '(uid=alice)', ['*', '+']), {})]
+        )
+
     #
     # Utilities
     #
diff --git a/docs/source/conf.py b/docs/source/conf.py
index c0ddf1c..cfc6f62 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -59,7 +59,7 @@ copyright = u'2009, Peter Sagerson'
 # The short X.Y version.
 version = '1.1'
 # The full version, including alpha/beta/rc tags.
-release = '1.2.7'
+release = '1.2.10'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/docs/source/reference.rst b/docs/source/reference.rst
index 734a55f..26db1ce 100644
--- a/docs/source/reference.rst
+++ b/docs/source/reference.rst
@@ -255,12 +255,27 @@ AUTH_LDAP_START_TLS
 
 Default: ``False``
 
-If ``True``, each connection to the LDAP server will call :meth:`~ldap.LDAPObject.start_tls_s` to enable
-TLS encryption over the standard LDAP port. There are a number of configuration
-options that can be given to :setting:`AUTH_LDAP_GLOBAL_OPTIONS` that affect the
-TLS connection. For example, :data:`ldap.OPT_X_TLS_REQUIRE_CERT` can be set to
-:data:`ldap.OPT_X_TLS_NEVER` to disable certificate verification, perhaps to
-allow self-signed certificates.
+If ``True``, each connection to the LDAP server will call
+:meth:`~ldap.LDAPObject.start_tls_s` to enable TLS encryption over the standard
+LDAP port. There are a number of configuration options that can be given to
+:setting:`AUTH_LDAP_GLOBAL_OPTIONS` that affect the TLS connection. For example,
+:data:`ldap.OPT_X_TLS_REQUIRE_CERT` can be set to :data:`ldap.OPT_X_TLS_NEVER`
+to disable certificate verification, perhaps to allow self-signed certificates.
+
+
+.. setting:: AUTH_LDAP_USER_ATTRLIST
+
+AUTH_LDAP_USER_ATTRLIST
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Default: ``None``
+
+A list of attribute names to load for the authenticated user. Normally, you can
+ignore this and the LDAP server will send back all of the attributes of the
+directory entry. One reason you might need to override this is to get
+operational attributes, which are not normally included::
+
+    AUTH_LDAP_USER_ATTRLIST = ['*', '+']
 
 
 .. setting:: AUTH_LDAP_USER_ATTR_MAP
diff --git a/docs/source/users.rst b/docs/source/users.rst
index c5cc902..792244a 100644
--- a/docs/source/users.rst
+++ b/docs/source/users.rst
@@ -19,12 +19,12 @@ substitute a proxy model.
     version 1.1.4, django-auth-ldap will respect custom user models.
 
 The only required field for a user is the username, which we obviously have. The
-:class:`~django.contrib.auth.models.User` model is picky about the characters
-allowed in usernames, so :class:`~django_auth_ldap.backend.LDAPBackend` includes
-a pair of hooks,
+default :class:`~django.contrib.auth.models.User` model can be picky about the
+characters allowed in usernames, so
+:class:`~django_auth_ldap.backend.LDAPBackend` includes a pair of hooks,
 :meth:`~django_auth_ldap.backend.LDAPBackend.ldap_to_django_username` and
 :meth:`~django_auth_ldap.backend.LDAPBackend.django_to_ldap_username`, to
-translate between LDAP usernames and Django usernames. You'll need this, for
+translate between LDAP usernames and Django usernames. You may need this, for
 example, if your LDAP names have periods in them. You can subclass
 :class:`~django_auth_ldap.backend.LDAPBackend` to implement these hooks; by
 default the username is not modified. :class:`~django.contrib.auth.models.User`
@@ -45,15 +45,36 @@ course, be the Django username.
     unavailable.
 
 
-User Attributes
+Populating Users
+----------------
+
+You can perform arbitrary population of your user models by adding listeners to
+a pair of :mod:`Django signals <django:django.dispatch>`:
+:data:`django_auth_ldap.backend.populate_user` and
+:data:`django_auth_ldap.backend.populate_user_profile`. These are sent after the
+user object has been created and any configured attribute mapping has been
+applied (see below). You can use this to propagate information from the LDAP
+directory to the user and profile objects any way you like. The user instance
+will be saved automatically after the signal handlers are run.
+
+If you need an attribute that isn't included by default in the LDAP search
+results, see :setting:`AUTH_LDAP_USER_ATTRLIST`.
+
+.. note::
+
+    Django 1.7 and later do not directly support user profiles. In these
+    versions, :data:`~django_auth_ldap.backend.populate_user_profile` will not
+    be sent.
+
+
+Easy Attributes
 ---------------
 
-LDAP directories tend to contain much more information about users that you may
-wish to propagate. A pair of settings, :setting:`AUTH_LDAP_USER_ATTR_MAP` and
-:setting:`AUTH_LDAP_PROFILE_ATTR_MAP`, serve to copy directory information into
-:class:`~django.contrib.auth.models.User` and profile objects. These are
-dictionaries that map user and profile model keys, respectively, to
-(case-insensitive) LDAP attribute names::
+If you just want to copy a few attribute values directly from the user's LDAP
+directory entry to their Django user, a pair of settings,
+:setting:`AUTH_LDAP_USER_ATTR_MAP` and :setting:`AUTH_LDAP_PROFILE_ATTR_MAP`,
+make it easy. These are dictionaries that map user and profile model keys,
+respectively, to (case-insensitive) LDAP attribute names::
 
     AUTH_LDAP_USER_ATTR_MAP = {"first_name": "givenName", "last_name": "sn"}
     AUTH_LDAP_PROFILE_ATTR_MAP = {"home_directory": "homeDirectory"}
@@ -80,6 +101,9 @@ any group.
     Django 1.7 and later do not directly support user profiles. In these
     versions, LDAPBackend will ignore the profile-related settings.
 
+Remember that if these settings don't do quite what you want, you can always use
+the signals described in the previous section to implement your own logic.
+
 
 Updating Users
 --------------
@@ -124,15 +148,3 @@ Python-ldap returns all attribute values as utf8-encoded strings. For
 convenience, this module will try to decode all values into Unicode strings. Any
 string that can not be successfully decoded will be left as-is; this may apply
 to binary values such as Active Directory's objectSid.
-
-
-Custom Field Population
------------------------
-
-If you would like to perform any additional population of user or profile
-objects, :mod:`django_auth_ldap.backend` exposes two custom signals to help:
-:data:`~django_auth_ldap.backend.populate_user` and
-:data:`~django_auth_ldap.backend.populate_user_profile`. These are sent after
-the backend has finished populating the respective objects and before they are
-saved to the database. You can use this to propagate additional information from
-the LDAP directory to the user and profile objects any way you like.
diff --git a/setup.cfg b/setup.cfg
index 861a9f5..8bfd5a1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff --git a/setup.py b/setup.py
index e033246..732b9f7 100644
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ PY3 = (sys.version_info[0] == 3)
 
 setup(
     name="django-auth-ldap",
-    version="1.2.7",
+    version="1.2.10",
     description="Django LDAP authentication backend",
     long_description=open('README').read(),
     url="http://bitbucket.org/psagers/django-auth-ldap/",
@@ -28,6 +28,7 @@ setup(
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3.3",
         "Programming Language :: Python :: 3.4",
+        "Programming Language :: Python :: 3.5",
         "Framework :: Django",
         "Intended Audience :: Developers",
         "Intended Audience :: System Administrators",
@@ -45,6 +46,6 @@ setup(
         "setuptools >= 0.6c11",
     ],
     tests_require=[
-        "mockldap >= 0.2.6",
+        "mockldap >= 0.2.7",
     ]
 )
diff --git a/tox.ini b/tox.ini
index e6ac844..79d2f7d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,8 @@
+[pep8]
+max-line-length = 120
+
 [flake8]
-ignore = E501
+max-line-length = 120
 
 
 [tox]
@@ -11,12 +14,14 @@ envlist = py26-django13,
           py27-django18,
           py33-django16,
           py34-django17,
-          py34-django18
+          py34-django18,
+          py35-django18,
+          py35-django19,
 
 [testenv]
 changedir = test
 commands = {envpython} manage.py test django_auth_ldap
-deps = mockldap >= 0.2.6
+deps = mockldap>=0.2.7
 
 [testenv:py26-django13]
 basepython = python2.6
@@ -62,3 +67,13 @@ deps = {[testenv]deps}
 basepython = python3.4
 deps = {[testenv]deps}
        django<1.9
+
+[testenv:py35-django18]
+basepython = python3.5
+deps = {[testenv]deps}
+       django<1.9
+
+[testenv:py35-django19]
+basepython = python3.5
+deps = {[testenv]deps}
+       django>=1.9a1,<1.10

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/django-auth-ldap.git



More information about the Python-modules-commits mailing list