cc @kenilelk1 @rrivera1109 @RArroyo
I don’t use a public git repo so just gonna post it here for now - don’t see myself updating it much anyway. Also - hope it’s readable and if you have any feedback, feel free to shoot. Not a python expert in any capacity so always happy to improve.
import csv
import re
import requests as r
import json
import os
# Update the below values to match your installation
sp_api_url = "https://<tenant>.api.identitynow.com"
clientid = ""
secret = ""
# Get a bearer token
def get_sp_api_token():
body = {
"grant_type": "client_credentials",
"client_id": clientid,
"client_secret": secret
}
response = r.post(sp_api_url + "/oauth/token", body)
if response.ok:
print("API access token obtained")
return response.json()['access_token']
else:
print(response.json())
print("Error while obtaining access token")
# get all controlled applications, store name, ID & description
def get_all_apps():
apps = []
response = r.get(sp_api_url + "/cc/api/app/list?filter=org", headers=apiCallHeaders)
if response.ok:
print("Applications found")
for item in response.json():
if item['controlType'] != "PERSONAL":
print(item['name'])
apps.append({"appid": item['id'], "appName": item['name'], "appDescription": item['description']})
else:
print("Error fetching applications: ")
print(response)
return apps
# get all access profiles assigned to each application. Store access profiel name, description and approvalSchemes
def get_app_access_profiles():
apps = applications
for app in applications:
response = r.get(sp_api_url + "/cc/api/app/getAccessProfiles/" + app['appid'], headers=apiCallHeaders2)
if response.ok:
if response.json()['count'] != 0:
print("Found " + str(response.json()['count']) + " access profiles for " + app['appName'])
accessprofiles = []
for item in response.json()['items']:
accessprofiles.append({"accessprofile": item['name'], "description": item['description'],
"approvals": item['approvalSchemes']})
app["accessprofiles"] = accessprofiles
else:
print("No access profiles assigned to " + app['appName'])
else:
print("Error fetching access profiles for " + app['appName'])
print(response)
return apps
# get membership of each governance group per access profile - you could optimise this and fetch all governance groups separately and store in a variable to iterate over later. At the moment this fetches all approvers and also updates the apps list
def get_workgroup_membership():
apps = access_profiles
for app in apps:
if "accessprofiles" in app:
for ap in app['accessprofiles']:
if ap['approvals'] is not None:
if "," in str(ap['approvals']):
ap.update({"approvals": ap['approvals'].split(",")})
workgroups = []
for approver in ap['approvals']:
if "workgroup" in approver:
members = []
workgroup = r.get(sp_api_url + "/v2/workgroups/" + (approver.split(":")[1]).strip(), headers=apiCallHeaders2)
membership = r.get(sp_api_url + "/v2/workgroups/" + (approver.split(":")[1]).strip() + "/members", headers=apiCallHeaders2)
for member in membership.json():
members.append(member['email'])
workgroups.append({workgroup.json()['name']: members})
else:
workgroups.append(approver)
ap['approvals'] = workgroups
else:
if "workgroup" in ap['approvals']:
members = []
workgroup = r.get(sp_api_url + "/v2/workgroups/" + (ap['approvals'].split(":")[1]).strip(), headers=apiCallHeaders2)
membership = r.get(sp_api_url + "/v2/workgroups/" + (ap['approvals'].split(":")[1]).strip() + "/members", headers=apiCallHeaders2)
for member in membership.json():
members.append(member['email'])
ap['approvals'] = {workgroup.json()['name']: members}
print("Approval values updated with governance group names and membership")
appson = apps
return appson
# save to file
def save_file():
with open('data.json', 'w') as file:
json.dump(alldata, file, indent=4)
return
token = get_sp_api_token()
apiCallHeaders = {'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json'}
apiCallHeaders2 = {'Authorization': 'Bearer ' + token}
applications = get_all_apps()
access_profiles = get_app_access_profiles()
alldata = get_workgroup_membership()
save_file()