Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion dejacode/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,72 @@ def get_fake_redis_connection(config, use_strict_redis):
# AUTH_LDAP_USER_FILTERSTR="(uid=%(user)s)"
AUTH_LDAP_USER_FILTERSTR = env.str("AUTH_LDAP_USER_FILTERSTR", default="")

AUTH_LDAP_USER_SEARCH = LDAPSearch(AUTH_LDAP_USER_DN, ldap.SCOPE_SUBTREE, AUTH_LDAP_USER_FILTERSTR)
# Optional: Define multiple LDAP user searches using a JSON list.
# When provided, this setting overrides AUTH_LDAP_USER_DN and AUTH_LDAP_USER_FILTERSTR.
#
# Example:
# AUTH_LDAP_USER_SEARCHES = """
# [
# {
# "base": "ou=users,dc=example,dc=com",
# "filter": "(uid=%(user)s)"
# },
# {
# "base": "ou=otherusers,dc=example,dc=com",
# "filter": "(uid=%(user)s)"
# }
# ]
# """
#
# Hint: use as a single line string within docker env
#
# Each entry must define:
# - "base": The base DN to search
# - "filter": The LDAP filter (must include %(user)s)
#
# All searches are combined using LDAPSearchUnion.
AUTH_LDAP_USER_SEARCHES = env.str("AUTH_LDAP_USER_SEARCHES", default="")

if AUTH_LDAP_USER_SEARCHES:
import json
from django_auth_ldap.config import LDAPSearchUnion

try:
ldap_search_definitions = json.loads(AUTH_LDAP_USER_SEARCHES)
except json.JSONDecodeError as e:
raise ValueError("Invalid JSON in AUTH_LDAP_USER_SEARCHES") from e

if not isinstance(ldap_search_definitions, list):
raise ValueError("AUTH_LDAP_USER_SEARCHES must be a JSON list")

ldap_searches = []
for search_definition in ldap_search_definitions:
if not isinstance(search_definition, dict):
raise ValueError("Each entry must be an object")

base_dn = search_definition.get("base")
filterstr = search_definition.get("filter")

if not base_dn or not filterstr:
raise ValueError("Each LDAP search entry must define 'base' and 'filter'")

ldap_searches.append(
LDAPSearch(base_dn, ldap.SCOPE_SUBTREE, filterstr)
)

if not ldap_searches:
raise ValueError("AUTH_LDAP_USER_SEARCHES cannot be empty")

# Always use LDAPSearchUnion, even for a single search entry.
AUTH_LDAP_USER_SEARCH = LDAPSearchUnion(*ldap_searches)

else:
# Fallback to single LDAP search configuration.
AUTH_LDAP_USER_SEARCH = LDAPSearch(
AUTH_LDAP_USER_DN,
ldap.SCOPE_SUBTREE,
AUTH_LDAP_USER_FILTERSTR,
)

# When AUTH_LDAP_AUTOCREATE_USER is True (default), a new DejaCode user will be
# created in the database with the minimum permission (a read-only user).
Expand Down
36 changes: 36 additions & 0 deletions docs/application-settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,42 @@ It must return exactly one result for authentication to succeed.
AUTH_LDAP_USER_DN="ou=users,dc=example,dc=com"
AUTH_LDAP_USER_FILTERSTR="(uid=%(user)s)"

USER_SEARCHES
-------------

To search across multiple LDAP locations, use
``AUTH_LDAP_USER_SEARCHES``.

When this setting is provided, it overrides both
``AUTH_LDAP_USER_DN`` and ``AUTH_LDAP_USER_FILTERSTR``.

The setting must contain a JSON list of search definitions. Each entry
must define:

- ``base``: The base DN to search
- ``filter``: The LDAP filter (must include ``%(user)s``)

All configured searches are combined using ``LDAPSearchUnion``.

Example:

.. code-block:: python

AUTH_LDAP_USER_SEARCHES = """
[
{
"base": "ou=users,dc=example,dc=com",
"filter": "(uid=%(user)s)"
},
{
"base": "ou=otherusers,dc=example,dc=com",
"filter": "(uid=%(user)s)"
}
]
"""

For usage in a ``docker.env`` file only a single line string is accepted.

AUTOCREATE_USER
---------------

Expand Down