Hello,
Currently working to have a python script to find all the disabled users in Portal and then unassign all the Portal User Extension licenses (for example: Utility Network, Workflow Manager, Trace Network) for one user and then delete the user, then find the next user until no more. Would like to run this script weekly to do automated cleanup.
First, I tried this using from arcgis.gis import GIS module to find disabled users, while this is working, however, cannot find any module to remove the user's provisionUserEntitlements User Type license extensions.
Second: found the REST API provision-user-entitlements ArcGIS REST API and this request method to do this but it is not working (no license is revoked in Portal) - it does not error out. Not sure is the json format is correct to pass to the request to Portal?
I tested using PostMan and the request works using the header= application/x-www-form-urlencoded in the Body Form-Data but when I tried to match the Python script to this setup, it does not update the user's profile.
Can someone please let me know what am I doing wrong?
Thanks !
Code :
from arcgis.gis import GIS
from IPython.display import display
import os,sys, time
from arcgis.gis.admin import PortalAdminManager
import requests
import json
username = 'xyz'
password = 'xyz'
portal_url = 'https://myportal.com/portal'
token_url = f"{portal_url}/sharing/rest/generateToken"
token_params = {
"username": username,
"password": password,
"referer": portal_url, # Or the URL of your application
"f": "json"
}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
try:
#get a list of all disabled users list
source = GIS(myPortal, "xyz", "xyz")
sourceusers = source.users.search(max_users=1000)
disabled_users = []
#get disabled user - one by one
for user in sourceusers:
if user.disabled:
print("in disabled user")
disabled_users.append(user.username)
print(user.username)
#user.enable()
#get token to get find one Disabled User Entitlement at a time
token_response = requests.post(token_url, data=token_params)
token_response.raise_for_status() # Raise an exception for bad status codes
token_data = token_response.json()
token = token_data.get("token")
if not token:
print(f"Error generating token: {token_data.get('error', {}).get('message', 'Unknown error')}")
exit()
else:
print(f"Successfully obtained token: {token}")
print(f"Successfully obtained user: {user.username}")
#UN license extension
check_user_item = f"{portal_url}/sharing/rest/content/listings/aiwhtiaht;whatawt/provisionUserEntitlements"
params = {
"token": token,
"f": "json",
"userEntitlements":{
"users":[user.username],
"entitlements":[]
}
#"standard" is an entitlement string that uniquely identifies entitlement, listing itemId is used typically for provider apps}
}
print("\n params")
print(params)
json_string = json.dumps(params)
print("DUMPS json_string : \n")
print(json_string)
#find UN License Entitlement for user
UNentitlement_response = requests.post(check_user_item,data=params,headers=headers)
#UNentitlement_response = requests.post(check_user_item,data=json_string,headers=headers)
#print("UNentitlement_response \n")
print(UNentitlement_response)
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
except json.JSONDecodeError:
print("Failed to parse JSON response.")