From 1966c9ee012f9ec42f1934201cdb729c0d5f183c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Thu, 10 Oct 2024 10:36:15 +0200 Subject: [PATCH 01/10] Drop support for EOL Python 3.8 --- .github/workflows/test.yml | 1 - pyproject.toml | 3 +-- tox.ini | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6c71ffd6..046b73bb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,6 @@ jobs: matrix: # https://docs.djangoproject.com/en/dev/faq/install/#what-python-version-can-i-use-with-django python-version: - - '3.8' - '3.9' - '3.10' - '3.11' diff --git a/pyproject.toml b/pyproject.toml index 3b4a52b4..8bb75a0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "django-auth-ldap" -requires-python = ">=3.8" +requires-python = ">=3.9" description = "Django LDAP authentication backend" readme = "README.rst" authors = [ @@ -23,7 +23,6 @@ classifiers = [ "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", diff --git a/tox.ini b/tox.ini index 87ffa51a..121f6e55 100644 --- a/tox.ini +++ b/tox.ini @@ -10,7 +10,6 @@ isolated_build = true [gh] python = - 3.8 = django42 3.9 = django42 3.10 = django{42,50,51,main} 3.11 = django{42,50,51,main} From 943c8002bc51532e99f482ed10301b3bd4938865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Thu, 10 Oct 2024 10:30:56 +0200 Subject: [PATCH 02/10] Allow importing the backend without loading apps Make it possible to monkey-patch the backend from the settings. --- django_auth_ldap/backend.py | 5 ++++- tests/import_test_without_django.py | 16 ++++++++++++++++ tox.ini | 4 +++- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/import_test_without_django.py diff --git a/django_auth_ldap/backend.py b/django_auth_ldap/backend.py index c63b6cec..4356d79c 100644 --- a/django_auth_ldap/backend.py +++ b/django_auth_ldap/backend.py @@ -51,7 +51,6 @@ import django.dispatch import ldap from django.contrib.auth import get_user_model -from django.contrib.auth.models import Group, Permission from django.core.cache import cache from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist @@ -777,6 +776,8 @@ def _mirror_groups(self): Mirrors the user's LDAP groups in the Django database and updates the user's membership. """ + from django.contrib.auth.models import Group + try: target_group_names = frozenset(self._get_groups().get_group_names()) except ldap.LDAPError as e: @@ -833,6 +834,8 @@ def _load_group_permissions(self): Populates self._group_permissions based on LDAP group membership and Django group permissions. """ + from django.contrib.auth.models import Permission + group_names = self._get_groups().get_group_names() perms = Permission.objects.filter(group__name__in=group_names) diff --git a/tests/import_test_without_django.py b/tests/import_test_without_django.py new file mode 100644 index 00000000..0fbdc9b4 --- /dev/null +++ b/tests/import_test_without_django.py @@ -0,0 +1,16 @@ +import os +from unittest import TestCase + + +class TestLoading(TestCase): + def test_django_not_ready(self): + orig_env = os.environ.copy() + + def reset_env(): + os.environ = orig_env + + self.addCleanup(reset_env) + + os.environ["DJANGO_SETTINGS_MODULE"] = "tests.settings" + + import django_auth_ldap.backend # noqa: F401 diff --git a/tox.ini b/tox.ini index 121f6e55..dd4f3f91 100644 --- a/tox.ini +++ b/tox.ini @@ -17,7 +17,9 @@ python = 3.13 = django{42,50,51,main} [testenv] -commands = {envpython} -Wa -b -m django test --settings tests.settings +commands = + {envpython} -Wa -b -m django test --settings tests.settings + {envpython} -Wa -b -m unittest discover --pattern *_test_without_django.py deps = django42: Django>=4.2,<4.3 django50: Django>=5.0,<5.1 From 16ea6fd4158bc47549f59ed7fce7d2ad0472a80a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Sun, 9 Feb 2025 14:17:26 +0100 Subject: [PATCH 03/10] Stop testing Python 3.10 and 3.11 against django main Django dropped support for these Python versions on main. --- tox.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index dd4f3f91..f635c98c 100644 --- a/tox.ini +++ b/tox.ini @@ -11,8 +11,8 @@ isolated_build = true [gh] python = 3.9 = django42 - 3.10 = django{42,50,51,main} - 3.11 = django{42,50,51,main} + 3.10 = django{42,50,51} + 3.11 = django{42,50,51} 3.12 = django{42,50,51,main} 3.13 = django{42,50,51,main} From c5c768388af2ab2a4266d9de94d8ec8ae3a54975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Wed, 7 May 2025 10:25:16 +0200 Subject: [PATCH 04/10] Align CI with python-ldap Ubuntu 24.04 does not support the AppArmor trick used on 22.04, and there is no documented workaround. Follow the configuration from python-ldap. --- .github/workflows/docs.yml | 11 +++++------ .github/workflows/test.yml | 9 ++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d47a1308..efef6f75 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -7,7 +7,8 @@ on: jobs: build: name: Documentation - runs-on: ubuntu-latest + # https://github.com/python-ldap/python-ldap/blob/main/.github/workflows/ci.yml + runs-on: ubuntu-22.04 env: TOXENV: docs @@ -15,11 +16,9 @@ jobs: steps: - name: Install LDAP libs run: | - sudo apt-get update - # https://www.python-ldap.org/en/latest/installing.html#debian - sudo apt-get install slapd ldap-utils libldap2-dev libsasl2-dev - # https://github.com/python-ldap/python-ldap/issues/370 - sudo apt-get install apparmor-utils + sudo apt update + # https://github.com/python-ldap/python-ldap/blob/main/.github/workflows/ci.yml + sudo apt install -y ldap-utils slapd enchant-2 libldap2-dev libsasl2-dev apparmor-utils sudo aa-disable /usr/sbin/slapd - uses: actions/checkout@v4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 046b73bb..d40e59e6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,8 @@ on: jobs: test: name: Python ${{ matrix.python-version }} / ${{ matrix.tox-environment }} - runs-on: ubuntu-latest + # https://github.com/python-ldap/python-ldap/blob/main/.github/workflows/ci.yml + runs-on: ubuntu-22.04 strategy: fail-fast: false @@ -24,10 +25,8 @@ jobs: - name: Install LDAP libs run: | sudo apt-get update - # https://www.python-ldap.org/en/latest/installing.html#debian - sudo apt-get install slapd ldap-utils libldap2-dev libsasl2-dev - # https://github.com/python-ldap/python-ldap/issues/370 - sudo apt-get install apparmor-utils + # https://github.com/python-ldap/python-ldap/blob/main/.github/workflows/ci.yml + sudo apt install -y ldap-utils slapd enchant-2 libldap2-dev libsasl2-dev apparmor-utils sudo aa-disable /usr/sbin/slapd - uses: actions/checkout@v4 From 31c4f515a3c8fc2492c67d90b207689c8a67ea42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Wed, 7 May 2025 10:20:23 +0200 Subject: [PATCH 05/10] Add support for Django 5.2 --- pyproject.toml | 1 + tox.ini | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8bb75a0e..cb590cdd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ classifiers = [ "Framework :: Django :: 4.2", "Framework :: Django :: 5.0", "Framework :: Django :: 5.1", + "Framework :: Django :: 5.2", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: OSI Approved :: BSD License", diff --git a/tox.ini b/tox.ini index f635c98c..be608a8e 100644 --- a/tox.ini +++ b/tox.ini @@ -5,16 +5,17 @@ envlist = django42 django50 django51 + django52 djangomain isolated_build = true [gh] python = 3.9 = django42 - 3.10 = django{42,50,51} - 3.11 = django{42,50,51} - 3.12 = django{42,50,51,main} - 3.13 = django{42,50,51,main} + 3.10 = django{42,50,51,52} + 3.11 = django{42,50,51,52} + 3.12 = django{42,50,51,52,main} + 3.13 = django{42,50,51,52,main} [testenv] commands = @@ -24,6 +25,7 @@ deps = django42: Django>=4.2,<4.3 django50: Django>=5.0,<5.1 django51: Django>=5.1b1,<5.2 + django52: Django>=5.2,<6.0 djangomain: https://github.com/django/django/archive/main.tar.gz [testenv:ruff] From 1400829cadb60212333283eb7cd6ee7dfd3d2f61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Wed, 7 May 2025 10:46:41 +0200 Subject: [PATCH 06/10] Drop support for Django 5.0 --- pyproject.toml | 1 - tox.ini | 10 ++++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cb590cdd..b026a43b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,6 @@ classifiers = [ "Environment :: Web Environment", "Framework :: Django", "Framework :: Django :: 4.2", - "Framework :: Django :: 5.0", "Framework :: Django :: 5.1", "Framework :: Django :: 5.2", "Intended Audience :: Developers", diff --git a/tox.ini b/tox.ini index be608a8e..20a5fe84 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,6 @@ envlist = ruff docs django42 - django50 django51 django52 djangomain @@ -12,10 +11,10 @@ isolated_build = true [gh] python = 3.9 = django42 - 3.10 = django{42,50,51,52} - 3.11 = django{42,50,51,52} - 3.12 = django{42,50,51,52,main} - 3.13 = django{42,50,51,52,main} + 3.10 = django{42,51,52} + 3.11 = django{42,51,52} + 3.12 = django{42,51,52,main} + 3.13 = django{42,51,52,main} [testenv] commands = @@ -23,7 +22,6 @@ commands = {envpython} -Wa -b -m unittest discover --pattern *_test_without_django.py deps = django42: Django>=4.2,<4.3 - django50: Django>=5.0,<5.1 django51: Django>=5.1b1,<5.2 django52: Django>=5.2,<6.0 djangomain: https://github.com/django/django/archive/main.tar.gz From f77cdec71433ed00551d51341348c108c02f14df Mon Sep 17 00:00:00 2001 From: Augustin FL Date: Mon, 5 May 2025 11:11:23 +0200 Subject: [PATCH 07/10] Increase log level to info when creating/populating a user This way, admins have a way to log users creation and update while not logging LDAP traffic. --- django_auth_ldap/backend.py | 4 ++-- tests/tests.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/django_auth_ldap/backend.py b/django_auth_ldap/backend.py index 4356d79c..b7159eef 100644 --- a/django_auth_ldap/backend.py +++ b/django_auth_ldap/backend.py @@ -642,12 +642,12 @@ def _get_or_create_user(self, force_populate=False): "user does not satisfy AUTH_LDAP_NO_NEW_USERS" ) - logger.debug("Creating Django user %s", username) + logger.info("Creating Django user %s", username) self._user.set_unusable_password() save_user = True if should_populate: - logger.debug("Populating Django user %s", username) + logger.info("Populating Django user %s", username) self._populate_user() save_user = True diff --git a/tests/tests.py b/tests/tests.py index 41cb3735..bf21179a 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -582,8 +582,8 @@ def test_populate_user_with_missing_attribute(self): [(log.levelname, log.msg, log.args) for log in logs.records], [ ("DEBUG", "Binding as %s", (dn,)), - ("DEBUG", "Creating Django user %s", ("alice",)), - ("DEBUG", "Populating Django user %s", ("alice",)), + ("INFO", "Creating Django user %s", ("alice",)), + ("INFO", "Populating Django user %s", ("alice",)), ("DEBUG", "Binding as %s", ("",)), ( "DEBUG", From ceb59a85502625bbc668241ad819f105bc24c3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Wed, 7 May 2025 10:57:39 +0200 Subject: [PATCH 08/10] Fix documentation build on readthedocs https://about.readthedocs.com/blog/2024/12/deprecate-config-files-without-sphinx-or-mkdocs-config/ --- .readthedocs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index 2646802c..0c6dba53 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -7,3 +7,5 @@ build: python: install: - requirements: docs/requirements.txt +sphinx: + configuration: docs/conf.py From c401d6bd726ccc4652a897cbd51c914ded89c1f0 Mon Sep 17 00:00:00 2001 From: Piotr Kubiak Date: Mon, 10 Mar 2025 20:22:41 +0100 Subject: [PATCH 09/10] Filter empty Django group names when mirroring groups --- django_auth_ldap/backend.py | 4 +++- tests/tests.py | 40 ++++++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/django_auth_ldap/backend.py b/django_auth_ldap/backend.py index b7159eef..513810f8 100644 --- a/django_auth_ldap/backend.py +++ b/django_auth_ldap/backend.py @@ -779,7 +779,9 @@ def _mirror_groups(self): from django.contrib.auth.models import Group try: - target_group_names = frozenset(self._get_groups().get_group_names()) + target_group_names = frozenset( + filter(None, self._get_groups().get_group_names()) + ) except ldap.LDAPError as e: _report_error( type(self.backend), diff --git a/tests/tests.py b/tests/tests.py index bf21179a..c642ec4e 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1343,7 +1343,36 @@ def test_group_mirroring(self): alice = authenticate(username="alice", password="password") - self.assertEqual(Group.objects.count(), 3) + self.assertEqual( + set(Group.objects.all().values_list("name", flat=True)), + { + "active_px", + "staff_px", + "superuser_px", + }, + ) + self.assertEqual(set(alice.groups.all()), set(Group.objects.all())) + + def test_group_mirroring_custom_grouptype(self): + self._init_settings( + USER_DN_TEMPLATE="uid=%(user)s,ou=people,o=test", + GROUP_SEARCH=LDAPSearch( + "ou=groups,o=test", ldap.SCOPE_SUBTREE, "(objectClass=posixGroup)" + ), + GROUP_TYPE=CustomGroupType(), + MIRROR_GROUPS=True, + ) + + self.assertEqual(Group.objects.count(), 0) + + alice = authenticate(username="alice", password="password") + self.assertEqual( + set(Group.objects.all().values_list("name", flat=True)), + { + "active_px", + "staff_px", + }, + ) self.assertEqual(set(alice.groups.all()), set(Group.objects.all())) def test_nested_group_mirroring(self): @@ -1821,3 +1850,12 @@ def _init_groups(self): active_nis = Group.objects.create(name="active_nis") active_nis.permissions.add(*permissions) + + +class CustomGroupType(PosixGroupType): + def group_name_from_info(self, group_info): + name = super().group_name_from_info(group_info) + if name.startswith("superuser"): + name = None + + return name From 53adb73ef39151e3d91fb8aab9e0824e9d0a63cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Wed, 7 May 2025 10:17:34 +0200 Subject: [PATCH 10/10] fixup! Filter empty Django group names when mirroring groups --- tests/tests.py | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/tests.py b/tests/tests.py index c642ec4e..9c148966 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -1343,15 +1343,12 @@ def test_group_mirroring(self): alice = authenticate(username="alice", password="password") + groups = set(Group.objects.all()) self.assertEqual( - set(Group.objects.all().values_list("name", flat=True)), - { - "active_px", - "staff_px", - "superuser_px", - }, + {g.name for g in groups}, + {"active_px", "staff_px", "superuser_px"}, ) - self.assertEqual(set(alice.groups.all()), set(Group.objects.all())) + self.assertEqual(set(alice.groups.all()), groups) def test_group_mirroring_custom_grouptype(self): self._init_settings( @@ -1366,14 +1363,12 @@ def test_group_mirroring_custom_grouptype(self): self.assertEqual(Group.objects.count(), 0) alice = authenticate(username="alice", password="password") + groups = set(Group.objects.all()) self.assertEqual( - set(Group.objects.all().values_list("name", flat=True)), - { - "active_px", - "staff_px", - }, + {g.name for g in groups}, + {"active_px", "staff_px"}, ) - self.assertEqual(set(alice.groups.all()), set(Group.objects.all())) + self.assertEqual(set(alice.groups.all()), groups) def test_nested_group_mirroring(self): self._init_settings( pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy