@@ -257,6 +257,8 @@ def __init__(self, appbuilder):
257
257
app .config .setdefault ("AUTH_LDAP_FIRSTNAME_FIELD" , "givenName" )
258
258
app .config .setdefault ("AUTH_LDAP_LASTNAME_FIELD" , "sn" )
259
259
app .config .setdefault ("AUTH_LDAP_EMAIL_FIELD" , "mail" )
260
+ # Nested groups options
261
+ app .config .setdefault ("AUTH_LDAP_USE_NESTED_GROUPS_FOR_ROLES" , False )
260
262
261
263
# Rate limiting
262
264
app .config .setdefault ("AUTH_RATE_LIMITED" , False )
@@ -495,6 +497,10 @@ def auth_ldap_tls_certfile(self):
495
497
def auth_ldap_tls_keyfile (self ):
496
498
return self .appbuilder .get_app .config ["AUTH_LDAP_TLS_KEYFILE" ]
497
499
500
+ @property
501
+ def auth_ldap_use_nested_groups_for_roles (self ):
502
+ return self .appbuilder .get_app .config ["AUTH_LDAP_USE_NESTED_GROUPS_FOR_ROLES" ]
503
+
498
504
@property
499
505
def openid_providers (self ):
500
506
return self .appbuilder .get_app .config ["OPENID_PROVIDERS" ]
@@ -963,11 +969,39 @@ def _search_ldap(self, ldap, con, username):
963
969
user_dn = search_result [0 ][0 ]
964
970
# extract the other attributes
965
971
user_info = search_result [0 ][1 ]
966
- # return
967
- return user_dn , user_info
968
972
except (IndexError , NameError ):
969
973
return None , None
970
974
975
+ # get nested groups for user
976
+ if self .auth_ldap_use_nested_groups_for_roles :
977
+ log .debug ("Nested groups for LDAP enabled." )
978
+ # filter for microsoft active directory only
979
+ nested_groups_filter_str = (
980
+ f"(&(objectCategory=Group)(member:1.2.840.113556.1.4.1941:={ user_dn } ))"
981
+ )
982
+ nested_groups_request_fields = ["cn" ]
983
+
984
+ nested_groups_search_result = con .search_s (
985
+ self .auth_ldap_search ,
986
+ ldap .SCOPE_SUBTREE ,
987
+ nested_groups_filter_str ,
988
+ nested_groups_request_fields ,
989
+ )
990
+ log .debug (
991
+ "LDAP search for nested groups returned: %s" ,
992
+ nested_groups_search_result ,
993
+ )
994
+
995
+ nested_groups = [
996
+ x [0 ].encode () for x in nested_groups_search_result if x [0 ] is not None
997
+ ]
998
+ log .debug ("LDAP nested groups for users: %s" , nested_groups )
999
+
1000
+ user_info [self .auth_ldap_group_field ] = nested_groups
1001
+
1002
+ # return
1003
+ return user_dn , user_info
1004
+
971
1005
def _ldap_calculate_user_roles (
972
1006
self , user_attributes : Dict [str , bytes ]
973
1007
) -> List [str ]:
0 commit comments