Skip to content

Instantly share code, notes, and snippets.

@moosetraveller
Last active November 30, 2023 17:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moosetraveller/a2e8728ecad7a2e5d1d5bd2679dfdcae to your computer and use it in GitHub Desktop.
Save moosetraveller/a2e8728ecad7a2e5d1d5bd2679dfdcae to your computer and use it in GitHub Desktop.
How to update User License Type using ArcGIS REST API?

Looks like there is an undocumented endpoint /portals/self/updateUserLicenseType.

I had to dig deep... Eventually, I came across with this page:

This page mentions updateUserLicenseType and updateUserRole. There is also also a presentation about webhooks.

So I thought I give it a try (there was nothing to loose :)):

  • /portals/self/updateUserLicenseType

And it works (as of June 1, 2022, ArcGIS Enterprise 10.9.1 Base Deployment).

Finding the parameter names required some try and error:

Parameter Name Parameter Value
users array of strings
userLicenseType a string (as documented here)
f json (I don't know if other formats works?)
token your token

The return value seems to be:

{"results": [{"username": "joe", "status": true}]}

Assuming status is false if not successful.

Warning: Esri may have a reason why they did not add it to their REST API documentation (yet?), they may plan changes in the future or remove the endpoint altogether. Although, I assume they just did not update their documentation but it's an assumption.

However, it looks like the response diverges from the pattern seen in /portals/self/updateUserLevel and /portals/self/updateUserRole which is {"success": true}.

By the way, it looks like ArcGIS API for Python has a function arcgis.gis.User.update_license_type. It's the only documented way I found providing the functionality needed. Ideal for those writing Python scripts.

So I went verifying my findings by testing and logging ArcGIS API for Python:

import logging
import arcgis.gis

logging.basicConfig(format="%(message)s")
logging.getLogger().setLevel(logging.DEBUG)

gis = arcgis.gis.GIS("http://servername.com/portal", "foo", "bar")

user = arcgis.gis.User(gis, "joe")
user.update_license_type("GISProfessionalAdvUT")

And here is a part of the log confirming that the endpoint exists:

enter image description here

@FaCoffee1984
Copy link

To be able to perform this, doesn't the user executing this snippet need to be an admin? Running this with a service account returns a 403 error:

---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
Cell In[21], [line 2](vscode-notebook-cell:?execution_count=21&line=2)
      [1](vscode-notebook-cell:?execution_count=21&line=1) user = arcgis.gis.User(gis, "name.surname@domain.com")
----> [2](vscode-notebook-cell:?execution_count=21&line=2) user.update_license_type("MobileWorkerUT")

File [c:\Users\abc\Anaconda3\envs\fdc397\lib\site-packages\arcgis\gis\__init__.py:10978](file:///C:/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py:10978), in User.update_license_type(self, user_type)
  [10972](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py?line=10971) url = "%s/portals/self/updateUserLicenseType" % self._portal.resturl
  [10973](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py?line=10972) params = {
  [10974](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py?line=10973)     "users": [self.username],
  [10975](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py?line=10974)     "userLicenseType": user_type,
  [10976](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py?line=10975)     "f": "json",
  [10977](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py?line=10976) }
> [10978](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py?line=10977) res = self._gis._con.post(url, params)
  [10979](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py?line=10978) status = [r["status"] for r in res["results"]]
  [10980](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/__init__.py?line=10979) self._hydrated = False

File [c:\Users\abc\Anaconda3\envs\fdc397\lib\site-packages\arcgis\gis\_impl\_con\_connection.py:1557](file:///C:/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py:1557), in Connection.post(self, path, params, files, **kwargs)
   [1555](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1554) if return_raw_response:
   [1556](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1555)     return resp
-> [1557](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1556) return self._handle_response(
   [1558](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1557)     resp=resp,
   [1559](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1558)     out_path=out_path,
   [1560](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1559)     file_name=file_name,
   [1561](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1560)     try_json=try_json,
   [1562](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1561)     force_bytes=kwargs.pop("force_bytes", False),
   [1563](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1562) )

File [c:\Users\abc\Anaconda3\envs\fdc397\lib\site-packages\arcgis\gis\_impl\_con\_connection.py:1027](file:///C:/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py:1027), in Connection._handle_response(self, resp, file_name, out_path, try_json, force_bytes, ignore_error_key)
   [1023](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1022)             return data
   [1024](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1023)         errorcode = (
   [1025](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1024)             data["error"]["code"] if "code" in data["error"] else 0
   [1026](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1025)         )
-> [1027](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1026)         self._handle_json_error(data["error"], errorcode)
   [1028](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1027)     return data
   [1029](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1028) else:

File [c:\Users\abc\Anaconda3\envs\fdc397\lib\site-packages\arcgis\gis\_impl\_con\_connection.py:1052](file:///C:/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py:1052), in Connection._handle_json_error(self, error, errorcode)
   [1047](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1046)                 # _log.error(errordetail)
   [1049](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1048) errormessage = (
   [1050](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1049)     errormessage + "\n(Error Code: " + str(errorcode) + ")"
   [1051](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1050) )
-> [1052](file:///c%3A/Users/abc/Anaconda3/envs/fdc397/lib/site-packages/arcgis/gis/_impl/_con/_connection.py?line=1051) raise Exception(errormessage)

Exception: You do not have permissions to access this resource or perform this operation.
(Error Code: 403)

@LukeBrayy
Copy link

@moosetraveller Thanks heaps for posting your writeup of this! Worked like a charm :)

@moosetraveller
Copy link
Author

moosetraveller commented Nov 30, 2023

To be able to perform this, doesn't the user executing this snippet need to be an admin?

@FaCoffee1984, Yes.

@moosetraveller
Copy link
Author

@moosetraveller Thanks heaps for posting your writeup of this! Worked like a charm :)

@LukeBrayy, You are welcome. I am glad it helped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment