Skip to content

Commit be07be4

Browse files
committed
feat: add support for django LDAPSearchUnion
1 parent 8d0a720 commit be07be4

1 file changed

Lines changed: 66 additions & 1 deletion

File tree

dejacode/settings.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,72 @@ def get_fake_redis_connection(config, use_strict_redis):
767767
# AUTH_LDAP_USER_FILTERSTR="(uid=%(user)s)"
768768
AUTH_LDAP_USER_FILTERSTR = env.str("AUTH_LDAP_USER_FILTERSTR", default="")
769769

770-
AUTH_LDAP_USER_SEARCH = LDAPSearch(AUTH_LDAP_USER_DN, ldap.SCOPE_SUBTREE, AUTH_LDAP_USER_FILTERSTR)
770+
# Optional: Define multiple LDAP user searches using a JSON list.
771+
# When provided, this setting overrides AUTH_LDAP_USER_DN and AUTH_LDAP_USER_FILTERSTR.
772+
#
773+
# Example:
774+
# AUTH_LDAP_USER_SEARCHES = """
775+
# [
776+
# {
777+
# "base": "ou=users,dc=example,dc=com",
778+
# "filter": "(uid=%(user)s)"
779+
# },
780+
# {
781+
# "base": "ou=otherusers,dc=example,dc=com",
782+
# "filter": "(uid=%(user)s)"
783+
# }
784+
# ]
785+
# """
786+
#
787+
# Hint: use as a single line string within docker env
788+
#
789+
# Each entry must define:
790+
# - "base": The base DN to search
791+
# - "filter": The LDAP filter (must include %(user)s)
792+
#
793+
# All searches are combined using LDAPSearchUnion.
794+
AUTH_LDAP_USER_SEARCHES = env.str("AUTH_LDAP_USER_SEARCHES", default="")
795+
796+
if AUTH_LDAP_USER_SEARCHES:
797+
import json
798+
from django_auth_ldap.config import LDAPSearchUnion
799+
800+
try:
801+
ldap_search_definitions = json.loads(AUTH_LDAP_USER_SEARCHES)
802+
except json.JSONDecodeError as e:
803+
raise ValueError("Invalid JSON in AUTH_LDAP_USER_SEARCHES") from e
804+
805+
if not isinstance(ldap_search_definitions, list):
806+
raise ValueError("AUTH_LDAP_USER_SEARCHES must be a JSON list")
807+
808+
ldap_searches = []
809+
for search_definition in ldap_search_definitions:
810+
if not isinstance(search_definition, dict):
811+
raise ValueError("Each entry must be an object")
812+
813+
base_dn = search_definition.get("base")
814+
filterstr = search_definition.get("filter")
815+
816+
if not base_dn or not filterstr:
817+
raise ValueError("Each LDAP search entry must define 'base' and 'filter'")
818+
819+
ldap_searches.append(
820+
LDAPSearch(base_dn, ldap.SCOPE_SUBTREE, filterstr)
821+
)
822+
823+
if not ldap_searches:
824+
raise ValueError("AUTH_LDAP_USER_SEARCHES cannot be empty")
825+
826+
# Always use LDAPSearchUnion, even for a single search entry.
827+
AUTH_LDAP_USER_SEARCH = LDAPSearchUnion(*ldap_searches)
828+
829+
else:
830+
# Fallback to single LDAP search configuration.
831+
AUTH_LDAP_USER_SEARCH = LDAPSearch(
832+
AUTH_LDAP_USER_DN,
833+
ldap.SCOPE_SUBTREE,
834+
AUTH_LDAP_USER_FILTERSTR,
835+
)
771836

772837
# When AUTH_LDAP_AUTOCREATE_USER is True (default), a new DejaCode user will be
773838
# created in the database with the minimum permission (a read-only user).

0 commit comments

Comments
 (0)