@@ -767,7 +767,72 @@ def get_fake_redis_connection(config, use_strict_redis):
767767# AUTH_LDAP_USER_FILTERSTR="(uid=%(user)s)"
768768AUTH_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