#!/usr/bin/python2.7 # grouper_find_members # get the list of group members, select one of these options: # all members # effective (indirect) # immediate (direct) # composite # nonimmediate import httplib2 import json import sys,string def usage(): print('usage: grouper_find_members -g -f ') print('-g group ID path') print('-f memberFilter can be All, Effective, Immediate, Composite, or NonImmediate') exit(1) def main(): # parse the command line arguments if len(sys.argv) != 5: usage() if sys.argv[1] != '-g': usage() thisGroup = sys.argv[2] if sys.argv[3] != '-f': usage() thisFilter = string.upper(sys.argv[4]) # initialize httplib2 http = httplib2.Http() # set the grouper URI (dev or prod), username, password grouper_ws_uri = grouperWSParameters(http) # get group members getMembers = grouperGetMembersWithFilter(http,grouper_ws_uri,thisGroup,thisFilter) if getMembers and getMembers['WsGetMembersResults']['resultMetadata']['resultCode'] == 'SUCCESS': if 'wsSubjects' not in getMembers['WsGetMembersResults']['results'][0]: # no members found using this member filter print("None") exit(0) members = getMembers['WsGetMembersResults']['results'][0]['wsSubjects'] for nmembers in range(0,len(members)): member = members[nmembers] name = member['name'] source = member['sourceId'] subjectId = member['id'] # there are three member types, identified by their source # if source=idm then subjectId contains the UNI # and name contains the person's name # if source=g:gsa then subjectId contains the UUID of the subgroup # and name contains the groupd ID path of the subgroup # if source=externalUsers then subjectId contains the email address # and name contains the person's name print(source+" - "+subjectId+" - "+name) else: print(thisGroup + " group not found (does not exist or is not accessible)") def grouperGetMembersWithFilter(http, grouper_ws_uri, groupName, memberFilter): if memberFilter == '': memberFilter = 'ALL' if memberFilter != 'ALL' and memberFilter != 'EFFECTIVE' and memberFilter != 'IMMEDIATE' and memberFilter != 'COMPOSITE' and memberFilter != 'NONIMMEDIATE': print("memberFilter "+memberFilter+" must be ALL or EFFECTIVE or IMMEDIATE or COMPOSITE or NONIMMEDIATE") exit(1) body = { "WsRestGetMembersRequest": { "includeSubjectDetail": "T", "memberFilter": memberFilter, "wsGroupLookups": [{ "groupName": groupName }] } } result = grouperWSRequest(http, grouper_ws_uri+"/groups", "POST", body) return result def grouperWSRequest(http, url, method, body): # send a request to the Grouper Web Service # method can be GET, POST, or PUT content_type = 'application/x-www-form-urlencoded' if method == "POST" or method == "PUT": content_type = 'text/x-json; charset=UTF-8' try: resp, content = http.request(uri=url, method=method, body=json.dumps(body), headers={'Content-Type': content_type}) if resp.status == 200 or resp.status == 201: result = json.loads(content.decode('utf-8')) return result except httplib2.ServerNotFoundError as err: print("Unable to connect to Grouper Web Service") print(err) return None # http request failed, print the response status and content print("http response status "+str(resp.status)) print("http response content "+content) return None def grouperWSParameters(http): # set the Grouper Web Service username and password grouper_username = 'abc1234' grouper_password = 'xxxxxxxxxxxxxxxxxxxx' http.add_credentials(name=grouper_username, password=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' return devGrouperURI if __name__ == '__main__': main()