@@ -149,6 +149,113 @@ def get_directorship_heads(self, val):
149149 True )
150150 for dn in ret ]
151151
152+ def get_query_for_groups (self , groups = None , excluded_groups = None ):
153+ """Returns the ldap query string to get members in groups but not in others
154+
155+ Argumenets:
156+ groups -- the groups members must be a member of
157+ excluded_groups -- the groups members cannot be a part of
158+ """
159+
160+ group_dns = [f"(memberOf=cn={ group } ,cn=groups,cn=accounts,dc=csh,dc=rit,dc=edu)" for group in groups ]
161+ excluded_group_dns = [
162+ f"(memberOf=cn={ group } ,cn=groups,cn=accounts,dc=csh,dc=rit,dc=edu)"
163+ for group in excluded_groups
164+ ]
165+
166+ query = ""
167+
168+ for group in group_dns :
169+ if query == "" :
170+ query = group
171+ continue
172+
173+ query = f"(&{ query } { group } )"
174+
175+ for group in excluded_group_dns :
176+ group = f"(!{ group } )"
177+ if query == "" :
178+ query = group
179+ continue
180+
181+ query = f"(&{ query } { group } )"
182+
183+ return query
184+
185+ def get_group_member_attributes (self , groups = None , excluded_groups = None , attributes = None ):
186+ """Returns a list of dicts containing all the attributes requested in the groups listed in groups,
187+ but not in exlcuded_groups
188+
189+ Arguements:
190+ groups -- the groups members must be a member of
191+ excluded_groups -- the groups members cannot be a part of
192+ attributues -- the ldap attributes to return, defaults to uid
193+ """
194+
195+ # I HATE PYTHON
196+ if attributes is None :
197+ attributes = ['uid' ]
198+
199+ query_result = self .__con__ .search_s (
200+ "dc=csh,dc=rit,dc=edu" ,
201+ ldap .SCOPE_SUBTREE ,
202+ self .get_query_for_groups (groups = groups , excluded_groups = excluded_groups ),
203+ attributes )
204+
205+ # the rest of this could be one giant list compression but I don't hate you that much so I chose not to
206+
207+ # filter out subgroups, probably the second check all we need
208+ # but if we used just the second one but the first one was empty that would probably be confusing?
209+ byte_result = [member [1 ] for member in query_result if not member [1 ] == {} and "cn=users" in member [0 ]]
210+
211+ result = []
212+
213+ for byte_member in byte_result :
214+ # decoding the byte strings
215+ result .append ({key : value [0 ].decode ('utf-8' ) for (key , value ) in byte_member .items ()})
216+
217+ return result
218+
219+ def get_group_member_uids (self , groups = None , excluded_groups = None ):
220+ """Get a list of member uids in a group
221+
222+ Arguements:
223+ groups -- the groups members must be a member of
224+ excluded_groups -- the groups members cannot be a part of
225+ """
226+
227+ query_result = self .__con__ .search_s (
228+ "dc=csh,dc=rit,dc=edu" ,
229+ ldap .SCOPE_SUBTREE ,
230+ self .get_query_for_groups (groups = groups , excluded_groups = excluded_groups ),
231+ ['uid' ])
232+
233+ return [
234+ member [1 ]['uid' ][0 ].decode ('utf-8' )
235+ for member in query_result
236+ if not member [1 ] == {} and "cn=users" in member [0 ]
237+ ]
238+
239+ def get_group_member_uuids (self , groups = None , excluded_groups = None ):
240+ """Get a list of member uuids in a group (ipaUniqueId)
241+
242+ Arguements:
243+ groups -- the groups members must be a member of
244+ excluded_groups -- the groups members cannot be a part of
245+ """
246+
247+ query_result = self .__con__ .search_s (
248+ "dc=csh,dc=rit,dc=edu" ,
249+ ldap .SCOPE_SUBTREE ,
250+ self .get_query_for_groups (groups = groups , excluded_groups = excluded_groups ),
251+ ['ipaUniqueId' ])
252+
253+ return [
254+ member [1 ]['ipaUniqueId' ][0 ].decode ('utf-8' )
255+ for member in query_result
256+ if not member [1 ] == {} and "cn=users" in member [0 ]
257+ ]
258+
152259 def enqueue_mod (self , dn , mod ):
153260 """Enqueue a LDAP modification.
154261
0 commit comments