1111from functools import lru_cache
1212from ldap .controls import SimplePagedResultsControl
1313
14+ from ralph .accounts .models import RalphUser , Region
1415from ralph .helpers import cache
1516
1617logger = logging .getLogger (__name__ )
@@ -68,20 +69,20 @@ def __exit__(self, type, value, traceback):
6869
6970
7071@cache (seconds = 600 )
71- def get_nested_groups ():
72+ def get_nested_groups () -> tuple [ dict [ str , set [ str ]], defaultdict [ str , set [ str ]]] :
7273 """
7374 Fetching users in nested group based on custom LDAP filter
7475 (AUTH_LDAP_NESTED_FILTER) e.g. (memberOf:{}). AUTH_LDAP_NESTED_FILTER
7576 is a simple dictonary where key is the name of group in DB, the value
7677 contains DN for nested group.
7778 """
7879 # mapping from django group name to set of users (usernames) belonging to it
79- group_users = {}
80+ group_name_to_usernames : dict [ str , set [ str ]] = {}
8081 # mapping from user (username) to set of groups DNs to which he belongs to
81- users_groups = defaultdict (set )
82+ username_to_group_names : defaultdict [ str , set [ str ]] = defaultdict (set )
8283 nested_groups = getattr (settings , "AUTH_LDAP_NESTED_GROUPS" , None )
8384 if not nested_groups :
84- return group_users , users_groups
85+ return group_name_to_usernames , username_to_group_names
8586 nested_filter = getattr (settings , "AUTH_LDAP_NESTED_FILTER" , "(memberOf:{})" )
8687 logger .info ("Fetching nested groups from LDAP" )
8788 with LDAPConnectionManager () as conn :
@@ -99,7 +100,7 @@ def get_nested_groups():
99100 settings .AUTH_LDAP_QUERY_PAGE_SIZE ,
100101 )
101102 logger .info ("{} fetched" .format (ralph_group_name ))
102- group_users [ralph_group_name ] = set (
103+ group_name_to_usernames [ralph_group_name ] = set (
103104 [
104105 u [1 ][settings .AUTH_LDAP_USER_USERNAME_ATTR ][0 ]
105106 .decode ("utf-8" )
@@ -109,13 +110,13 @@ def get_nested_groups():
109110 )
110111 logger .info (
111112 "Users in nested group {}: {}" .format (
112- ralph_group_name , group_users [ralph_group_name ]
113+ ralph_group_name , group_name_to_usernames [ralph_group_name ]
113114 )
114115 )
115- for username in group_users [ralph_group_name ]:
116+ for username in group_name_to_usernames [ralph_group_name ]:
116117 # notice group DN here, not Django group name!
117- users_groups [username ].add (ldap_group_name )
118- return group_users , users_groups
118+ username_to_group_names [username ].add (ldap_group_name )
119+ return group_name_to_usernames , username_to_group_names
119120
120121
121122def _make_paged_query (conn , search_base , search_scope , ad_query , attr_list , page_size ):
@@ -156,7 +157,29 @@ def _make_paged_query(conn, search_base, search_scope, ad_query, attr_list, page
156157 return result
157158
158159
159- class NestedGroups (object ):
160+ def _add_regions (user : RalphUser , region_names : list [str ]):
161+ for region_name in region_names :
162+ try :
163+ user .regions .add (Region .objects .get (name = region_name ))
164+ logger .info ("Assigned {} to region {}" .format (user .username , region_name ))
165+ except Region .DoesNotExist :
166+ logger .warning (
167+ "Region {} does not exist, cannot assign to user {}" .format (
168+ region_name ,
169+ user .username ,
170+ )
171+ )
172+
173+
174+ def assign_user_to_group (user : RalphUser , group : Group ):
175+ user .groups .add (group )
176+ default_regions = settings .DEFAULT_REGIONS_FOR_GROUP .get (group .name , [])
177+ _add_regions (user , default_regions )
178+
179+ logger .info ("Added {} to {}" .format (user .username , group .name ))
180+
181+
182+ class NestedGroups :
160183 """
161184 Class fetch nested groups and mapping them to standard Django's
162185 group (get or create). django_auth_ldap and their class for nested
@@ -170,19 +193,17 @@ def __init__(self):
170193 def get_group_from_db (self , name ):
171194 return Group .objects .get_or_create (name = name )[0 ]
172195
173- def handle (self , user ):
196+ def handle (self , user : RalphUser ):
174197 """
175198 Match user to group in fetched groups from LDAP and assign user
176199 to Django's group.
177200 """
178-
179201 if not self .group_users :
180202 return
181203 for group_name , users in self .group_users .items ():
182204 if user .username in users :
183205 group = self .get_group_from_db (group_name )
184- user .groups .add (group )
185- logger .info ("Added {} to {}" .format (user .username , group_name ))
206+ assign_user_to_group (user , group )
186207
187208
188209class Command (BaseCommand ):
0 commit comments