#!/usr/bin/python3 """ Find all groups the subject is a direct member of. Subject can be a UNI or a group. Examples: grouper_find_members.py -m dev -u abc1234 grouper_find_members.py -m dev -u this:group """ import argparse import requests from requests.auth import HTTPBasicAuth import json import sys,string def grouperGetImmediateGroups(grouper_credentials, grouper_ws_uri, subjectId): """Find groups this subject is a direct (immediate) member of""" body = { "WsRestGetGroupsRequest": { "memberFilter": "Immediate", "subjectLookups": [{ "subjectId": subjectId }] } } result = grouperWSRequest(grouper_credentials, grouper_ws_uri+"/subjects", "POST", body) return result def grouperGetUuid(grouper_credentials, grouper_ws_uri, groupName): """Get UUID for the specified group""" thisuuid = 0 body = { "WsRestFindGroupsRequest": { "wsQueryFilter": { "groupName": groupName, "queryFilterType": "FIND_BY_GROUP_NAME_EXACT", } } } findGroups = grouperWSRequest(grouper_credentials, grouper_ws_uri+"/groups", "POST", body) if findGroups and findGroups['WsFindGroupsResults']['resultMetadata']['success'] and 'groupResults' in findGroups['WsFindGroupsResults']: thisuuid = findGroups['WsFindGroupsResults']['groupResults'][0]['uuid'] return thisuuid def grouperWSRequest(grouper_credentials, url, method, body=None): """Send a request to the Grouper Web Service.""" try: response = requests.request(method, url, json=body, auth=grouper_credentials) response.raise_for_status() except requests.RequestException as e: raise SystemExit(e) from None return response.json() def find_groups(mode, subject): """Find groups this subject is a direct member of Args: mode (str): The environment mode ('dev', 'prod'). subject (str): The subject can be a UNI or a group. """ # set the Grouper Web Service username and password grouper_username = 'abc1234' grouper_password = 'xxxxxxxxxxxxxxxxxxxx' grouper_credentials = HTTPBasicAuth(grouper_username,grouper_password) # the Grouper Web Service URI should point to dev or prod Grouper devGrouperURI = 'https://grouper-dev.cc.columbia.edu/grouper-ws/servicesRest/v2_4_000' prodGrouperURI = 'https://grouper.cc.columbia.edu/grouper-ws/servicesRest/v2_4_000' if mode == 'prod': grouper_ws_uri = prodGrouperURI else: grouper_ws_uri = devGrouperURI # If subject is a group ID path, get the UUID this_subject = subject if ":" in subject: subject_uuid = grouperGetUuid(grouper_credentials,grouper_ws_uri,subject) if subject_uuid == 0: print(f"{subject} group not found (does not exist or is not accessible)") return this_subject = subject_uuid # Find the groups result = grouperGetImmediateGroups(grouper_credentials,grouper_ws_uri,this_subject) if (not result or not result['WsGetGroupsResults']['resultMetadata']['success']): print(f"Unable to get group list for {subject}") return if 'wsGroups' not in result['WsGetGroupsResults']['results'][0]: print(f"{subject} is not a direct member of any groups") return groups = result['WsGetGroupsResults']['results'][0]['wsGroups'] for ngroups in range(0,len(groups)): thisgroup = groups[ngroups] groupName = thisgroup['name'] print(groupName) def main(): """Parses command-line arguments and calls find_groups.""" parser = argparse.ArgumentParser( description="Get the list of groups this subject is a direct member of.", ) parser.add_argument( "-m", action="store", dest="mode", required=True, choices=["dev", "prod"], type=str.lower, help="the Grouper environment mode", ) parser.add_argument( "-u", action="store", dest="subject", required=True, help="the subject can be a UNI or a group", ) args = parser.parse_args() find_groups(args.mode, args.subject) if __name__ == "__main__": main()