From ddb0508fc6b7f2e764f09289ec29c05263121e66 Mon Sep 17 00:00:00 2001 From: Murali Shankar Date: Mon, 7 Apr 2025 15:11:58 -0700 Subject: [PATCH 1/2] Add grouper samples. --- commands/grpr/addMemberToGroup.py | 59 ++++++++++++++++++++++++++++ commands/grpr/findGroups.py | 54 +++++++++++++++++++++++++ commands/grpr/findUser.py | 50 +++++++++++++++++++++++ commands/grpr/getGroupMembers.py | 47 ++++++++++++++++++++++ commands/grpr/removeMemberToGroup.py | 56 ++++++++++++++++++++++++++ 5 files changed, 266 insertions(+) create mode 100755 commands/grpr/addMemberToGroup.py create mode 100755 commands/grpr/findGroups.py create mode 100755 commands/grpr/findUser.py create mode 100755 commands/grpr/getGroupMembers.py create mode 100755 commands/grpr/removeMemberToGroup.py diff --git a/commands/grpr/addMemberToGroup.py b/commands/grpr/addMemberToGroup.py new file mode 100755 index 0000000..a6219f9 --- /dev/null +++ b/commands/grpr/addMemberToGroup.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 + +""" +Add to a group a list of users +""" + + +import os +import requests +from requests.auth import HTTPBasicAuth +import logging +import argparse +import json + + +logger = logging.getLogger(__name__) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("-v", "--verbose", action='store_true', help="Turn on verbose logging") + parser.add_argument("--url", help="URL to the grouper web service", default="https://identity.slac.stanford.edu/grouper-ws/servicesRest/v5_17_000/") + parser.add_argument("--stem", help="The stem where we can find the groups ", default="app:Unix:posixGroups:s3df") + parser.add_argument("--user", help="The user id to use", default="osmaint@slac.stanford.edu") + parser.add_argument("--pwdfile", help="File containing the password", default=".pass") + parser.add_argument("groupname", help="The name of the group") + parser.add_argument("usernames", help="The names of the users", nargs="+") + args = parser.parse_args() + logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) + logging.getLogger("requests.packages.urllib3").setLevel(logging.DEBUG) + + with open(args.pwdfile, "r") as f: + auth=HTTPBasicAuth(args.user, f.read()) + + reqjson = { + "WsRestAddMemberRequest":{ + "wsGroupLookup":{ + "groupName": args.stem + ":" + args.groupname + }, + "subjectLookups": [ + ] + } + } + + for user in args.usernames: + reqjson["WsRestAddMemberRequest"]["subjectLookups"].append({ + "subjectId": user + }) + + logger.debug("Req json %s", json.dumps(reqjson, indent=4)) + + resp = requests.post(args.url + "groups", auth=auth, json=reqjson) + resp.raise_for_status() + ret = resp.json() + logger.debug(json.dumps(ret, indent=4)) + + status = ret.get("WsAddMemberResults", {}).get("resultMetadata").get("resultCode",None) + if status != "SUCCESS": + raise Exception("Invalid Status") + diff --git a/commands/grpr/findGroups.py b/commands/grpr/findGroups.py new file mode 100755 index 0000000..a2c6a10 --- /dev/null +++ b/commands/grpr/findGroups.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 + +""" +Get the groups in the S3DF stem +""" + + +import os +import requests +from requests.auth import HTTPBasicAuth +import logging +import argparse +import json + + +logger = logging.getLogger(__name__) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("-v", "--verbose", action='store_true', help="Turn on verbose logging") + parser.add_argument("--url", help="URL to the grouper web service", default="https://identity.slac.stanford.edu/grouper-ws/servicesRest/v5_17_000/") + parser.add_argument("--stem", help="The stem where we can find the groups ", default="app:Unix:posixGroups:s3df") + parser.add_argument("--user", help="The user id to use", default="osmaint@slac.stanford.edu") + parser.add_argument("--pwdfile", help="File containing the password", default=".pass") + args = parser.parse_args() + logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) + + with open(args.pwdfile, "r") as f: + auth=HTTPBasicAuth(args.user, f.read()) + + resp = requests.post(args.url + "groups", auth=auth, json={ + "WsRestFindGroupsRequest":{ + "wsQueryFilter":{ + "queryFilterType":"FIND_BY_STEM_NAME", + "stemName": args.stem + } + } + }) + resp.raise_for_status() + ret = resp.json() + logger.debug(json.dumps(ret, indent=4)) + + status = ret.get("WsFindGroupsResults", {}).get("resultMetadata").get("resultCode",None) + if status != "SUCCESS": + raise Exception("Invalid Status") + + for grp in ret.get("WsFindGroupsResults", {}).get("groupResults", []): + print("Group " + + grp.get("extension") + + " Full name: " + + grp.get("name") + + " integer index " + + grp.get("idIndex") + ) diff --git a/commands/grpr/findUser.py b/commands/grpr/findUser.py new file mode 100755 index 0000000..b9527a7 --- /dev/null +++ b/commands/grpr/findUser.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +""" +Find the user ( so that we can get their ID ) given their SLAC user id ( most likely AD ) +""" + + +import os +import requests +from requests.auth import HTTPBasicAuth +import logging +import argparse +import json + + +logger = logging.getLogger(__name__) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("-v", "--verbose", action='store_true', help="Turn on verbose logging") + parser.add_argument("--url", help="URL to the grouper web service", default="https://identity.slac.stanford.edu/grouper-ws/servicesRest/v5_17_000/") + parser.add_argument("--stem", help="The stem where we can find the groups ", default="app:Unix:posixGroups:s3df") + parser.add_argument("--user", help="The user id to use", default="osmaint@slac.stanford.edu") + parser.add_argument("--pwdfile", help="File containing the password", default=".pass") + parser.add_argument("userid", help="The SLAC user id for the user; this will get expanded to userid@slac.stanford.edu") + args = parser.parse_args() + logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) + + with open(args.pwdfile, "r") as f: + auth=HTTPBasicAuth(args.user, f.read()) + + resp = requests.post(args.url + "subjects", auth=auth, json={ + "WsRestGetSubjectsLiteRequest":{ + "searchString": args.userid + } + }) + resp.raise_for_status() + ret = resp.json() + logger.debug(json.dumps(ret, indent=4)) + + status = ret.get("WsGetSubjectsResults", {}).get("resultMetadata").get("resultCode",None) + if status != "SUCCESS": + raise Exception("Invalid Status") + + for sub in ret.get("WsGetSubjectsResults", {}).get("wsSubjects", []): + print("Subject --> " + + sub.get("name") + + " Id: " + + sub.get("id") + ) diff --git a/commands/grpr/getGroupMembers.py b/commands/grpr/getGroupMembers.py new file mode 100755 index 0000000..4974cf9 --- /dev/null +++ b/commands/grpr/getGroupMembers.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 + +""" +Get the members in an S3DF group +""" + + +import os +import requests +from requests.auth import HTTPBasicAuth +import logging +import argparse +import json + + +logger = logging.getLogger(__name__) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("-v", "--verbose", action='store_true', help="Turn on verbose logging") + parser.add_argument("--url", help="URL to the grouper web service", default="https://identity.slac.stanford.edu/grouper-ws/servicesRest/v5_17_000/") + parser.add_argument("--stem", help="The stem where we can find the groups ", default="app:Unix:posixGroups:s3df") + parser.add_argument("--user", help="The user id to use", default="osmaint@slac.stanford.edu") + parser.add_argument("--pwdfile", help="File containing the password", default=".pass") + parser.add_argument("groupname", help="The name of the group") + args = parser.parse_args() + logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) + + with open(args.pwdfile, "r") as f: + auth=HTTPBasicAuth(args.user, f.read()) + + resp = requests.get(args.url + "groups/" + args.stem + ":" + args.groupname + "/members", auth=auth) + resp.raise_for_status() + ret = resp.json() + logger.debug(json.dumps(ret, indent=4)) + + status = ret.get("WsGetMembersLiteResult", {}).get("resultMetadata").get("resultCode",None) + if status != "SUCCESS": + raise Exception("Invalid Status") + + members = [ "--> " + x["id"] for x in ret.get("WsGetMembersLiteResult", {}).get("wsSubjects",[]) if x["sourceId"] == "slacPerson" ] + print("Member for group " + + ret.get("WsGetMembersLiteResult", {}).get("wsGroup", {}).get("extension") + + " integer index " + + ret.get("WsGetMembersLiteResult", {}).get("wsGroup", {}).get("idIndex") + ) + print("\n".join(members)) diff --git a/commands/grpr/removeMemberToGroup.py b/commands/grpr/removeMemberToGroup.py new file mode 100755 index 0000000..cd850a8 --- /dev/null +++ b/commands/grpr/removeMemberToGroup.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 + +""" +Add to a group a list of users +""" + + +import os +import requests +from requests.auth import HTTPBasicAuth +import logging +import argparse +import json + + +logger = logging.getLogger(__name__) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("-v", "--verbose", action='store_true', help="Turn on verbose logging") + parser.add_argument("--url", help="URL to the grouper web service", default="https://identity.slac.stanford.edu/grouper-ws/servicesRest/v5_17_000/") + parser.add_argument("--stem", help="The stem where we can find the groups ", default="app:Unix:posixGroups:s3df") + parser.add_argument("--user", help="The user id to use", default="osmaint@slac.stanford.edu") + parser.add_argument("--pwdfile", help="File containing the password", default=".pass") + parser.add_argument("groupname", help="The name of the group") + parser.add_argument("usernames", help="The names of the users", nargs="+") + args = parser.parse_args() + logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) + logging.getLogger("requests.packages.urllib3").setLevel(logging.DEBUG) + + with open(args.pwdfile, "r") as f: + auth=HTTPBasicAuth(args.user, f.read()) + + reqjson = { + "WsRestDeleteMemberRequest":{ + "subjectLookups": [ + ] + } + } + + for user in args.usernames: + reqjson["WsRestDeleteMemberRequest"]["subjectLookups"].append({ + "subjectId": user + }) + + logger.debug("Req json %s", json.dumps(reqjson, indent=4)) + + resp = requests.post(args.url + "groups/" + args.stem + ":" + args.groupname + "/members", auth=auth, json=reqjson) + resp.raise_for_status() + ret = resp.json() + logger.debug(json.dumps(ret, indent=4)) + + status = ret.get("WsDeleteMemberResults", {}).get("resultMetadata").get("resultCode",None) + if status != "SUCCESS": + raise Exception("Invalid Status") + From 70a17686a940cb8bd102e9a66f351210811febc7 Mon Sep 17 00:00:00 2001 From: Murali Shankar Date: Mon, 7 Apr 2025 17:44:24 -0700 Subject: [PATCH 2/2] Create a new group --- commands/grpr/createNewGroup.py | 62 +++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100755 commands/grpr/createNewGroup.py diff --git a/commands/grpr/createNewGroup.py b/commands/grpr/createNewGroup.py new file mode 100755 index 0000000..da06511 --- /dev/null +++ b/commands/grpr/createNewGroup.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 + +""" +Create a new group +""" + + +import os +import requests +from requests.auth import HTTPBasicAuth +import logging +import argparse +import json + + +logger = logging.getLogger(__name__) + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument("-v", "--verbose", action='store_true', help="Turn on verbose logging") + parser.add_argument("--url", help="URL to the grouper web service", default="https://identity.slac.stanford.edu/grouper-ws/servicesRest/v5_17_000/") + parser.add_argument("--stem", help="The stem where we can find the groups ", default="app:Unix:posixGroups:s3df") + parser.add_argument("--user", help="The user id to use", default="osmaint@slac.stanford.edu") + parser.add_argument("--pwdfile", help="File containing the password", default=".pass") + parser.add_argument("groupname", help="The name of the groupto create") + parser.add_argument("description", help="A description for the group") + args = parser.parse_args() + logging.basicConfig(level=logging.DEBUG if args.verbose else logging.INFO) + logging.getLogger("requests.packages.urllib3").setLevel(logging.DEBUG) + + with open(args.pwdfile, "r") as f: + auth=HTTPBasicAuth(args.user, f.read()) + + reqjson = { "WsRestGroupSaveRequest": { + "wsGroupToSaves" : [{ + "wsGroup" : { + "extension" : args.groupname, + "description" : args.description, + "displayExtension" : args.groupname, + "name" : args.stem + ":" + args.groupname + }, + "wsGroupLookup" : { + "groupName" : args.stem + ":" + args.groupname + } + }] + }} + + logger.debug("Req json %s", json.dumps(reqjson, indent=4)) + + resp = requests.post(args.url + "groups", auth=auth, json=reqjson) + logger.debug(resp.text) + resp.raise_for_status() + ret = resp.json() + logger.debug(json.dumps(ret, indent=4)) + + status = ret.get("WsGroupSaveResults", {}).get("resultMetadata").get("resultCode",None) + if status != "SUCCESS": + raise Exception("Invalid Status") + + groupID = ret.get("WsGroupSaveResults", {}).get("results")[0].get("wsGroup").get("idIndex",None) + print(f"Successfully created group {args.groupname} with unique ID {groupID}") +