Note:
- This tutorial requires access to Oracle Cloud. To sign up for a free account, see Get started with Oracle Cloud Infrastructure Free Tier.
- It uses example values for Oracle Cloud Infrastructure credentials, tenancy, and compartments. When completing your lab, substitute these values with ones specific to your cloud environment.
Generate User Group membership report from OCI IAM Identity Domains using Python
Introduction
Oracle Cloud Infrastructure (OCI) is a cloud platform capable of providing a range of cloud services, including storage, networking and infrastructure. Oracle Cloud Infrastructure Identity and Access Management (OCI IAM) is a service that enables you to manage access to OCI resources. It provides authentication and authorization for users and groups.
One of the key features of OCI IAM is the ability to assign users to groups to simplify access management. Among customers of OCI IAM, one common scenario is to generate reports from OCI IAM Identity Domains. There are several IAM reports which get generated easily from the OCI IAM Identity Domains console. However, obtaining user group membership reports is not an out-of-the-box feature in OCI IAM for now, but can be easily generated using REST API calls.
Audience
This tutorial is intended for IAM professionals and administrators.
Objective
In this tutorial, we will explore a method to generate user group membership reports from OCI IAM Identity Domains using the REST API with Python.
Prerequisites
- An active OCI subscription.
- Familiarity with OCI IAM and Python.
- Knowledge of using OCI IAM Identity Domains REST API is required.
- An IAM user with authorization to manage Applications (Identity Domain Administrator, Security Administrator, or Application Administrator).
- Python 3.x installed on your system.
- ‘urllib3’, ‘requests’ and ‘pandas’ Python packages installed.
Task 1: Create a confidential application in OCI IAM Identity Domain
Follow the tutorial to create a confidential application and retrieve client ID and client secret, which can then be used to perform a REST API call to OCI IAM for retrieving Access Token and subsequent API endpoints.
Task 2: Set up the config.json
file
Set up the config file on your local machine. The config.json
file has information about the Identity Domain URL, Client ID and Client Secret which is used to generate the Access Token.
{
"iamurl" : "https://idcs-###########.identity.oraclecloud.com",
"client_id" : "#######################",
"client_secret" : "#######################"
}
Task 3: Get the Access Token
Once the config.json
file is in place, the first thing you need to do is to generate the Access Token, which can be used to make further REST API calls to the OCI IAM endpoints.
In the below code snippet, the function get_encoded takes in Client ID and Client Secret as arguments and returns the base64-encoded string.
This encoded string is further passed as an argument to the function get_access_token
as an Authorization header, to obtain the Access Token by performing a POST request.
#get base64 encoded
def get_encoded(self,clid, clsecret):
encoded = clid + ":" + clsecret
baseencoded = base64.urlsafe_b64encode(encoded.encode('UTF-8')).decode('ascii')
return baseencoded
#get access token
def get_access_token(self,url, header):
para = "grant_type=client_credentials&scope=urn:opc:idm:__myscopes__"
response = requests.post(url, headers=header, data=para, verify=False)
jsonresp = json.loads(response.content)
access_token = jsonresp.get('access_token')
return access_token
#print access token
def printaccesstoken(self):
obj = IAM()
encodedtoken = obj.get_encoded(clientID, clientSecret)
extra = "/oauth2/v1/token"
headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Authorization': 'Basic %s' % encodedtoken, 'Accept': '*/*'}
accesstoken = obj.get_access_token(idcsURL + extra, headers)
return accesstoken
Task 4: Retrieve user information - usernames and group membership
Now we have the access token, using which we can make further REST API calls to different OCI IAM Identity Domains REST endpoints. The code snippet below shows how we are making a GET request with necessary headers and parameters to the /admin/v1/Users
endpoint, in order to retrieve the total number of results and then calculate the number of iterations (loop) needed based on the total number of results and the count per request.
-
The function initializes an empty list to store all the user information. It has a loop to retrieve user information in batches.
-
In each iteration, it sends a GET request with the appropriate parameters to retrieve a batch of user information (username and group membership) and then add them in an empty dictionary.
-
If the user belongs to one or more groups, it enters another loop to retrieve each group name. And if the user does not belong to any group, it sets the value as None and then appends the copy of the dictionary to the list.
-
After all the iterations, the function returns the main list with all the required user information.
def searchusers(self):
obj = IAM()
accesstoken = obj.printaccesstoken()
startIndex = 0
count = 50
extra = "/admin/v1/Users"
headers = {'Accept': '*/*', 'Authorization': 'Bearer ' + accesstoken}
param = {'attributes': "userName,groups.display", 'startIndex': startIndex, 'count': count}
resp = requests.get(idcsURL + extra, headers=headers, verify=False, params=param)
jsonresp = json.loads(resp.content)
total = jsonresp.get("totalResults")
print(total)
tCount = total
loop = int(tCount / count)
print(loop)
mainlist = []
for i in range(loop + 1):
param1 = {'attributes': "userName,groups.display", 'startIndex': startIndex, 'count': count}
resp1 = requests.get(idcsURL + extra, headers=headers, verify=False, params=param1)
startIndex += count
jsonresp1 = json.loads(resp1.content)
tempjsn = jsonresp1.get("Resources")
for x in tempjsn:
trimjsn ={}
user = trimjsn["Username"] = x.get("userName")
grp = x.get("groups")
if grp is None:
trimjsn["Groups"] = "None"
mainlist.append(trimjsn.copy())
continue
for i in grp:
grpname = trimjsn["Groups"] = i.get("display")
print(trimjsn)
mainlist.append(trimjsn.copy())
print(mainlist)
return mainlist
Task 5: Convert the list to a CSV report
Once we have the user information, below code snippet will help to create a DataFrame from the main list data and then save the DataFrame to a CSV file named mainlist.csv
in the current working directory.
df_mainlist = pd.DataFrame(mainlist)
print(df_mainlist)
df_mainlist.to_csv('mainlist.csv')
Task 6: Use the script in the Cloud Shell
Once the script is ready, it can be easily executed on the local machine (with Python Installed) or on any IDE that supports Python development. Here, we are using OCI Cloud Shell to run the script and get the desired report.
-
Log in to the OCI Console, open the Cloud Shell from the top right corner of the screen and then upload the Python script and
config.json
file. -
Execute the command
pip3 install pandas --user
, to install the module.Note: Execute the command for any module error. The modules should be installed prior to using it.
-
Now execute
python GroupMembership_Pagination.py
. -
Download
mainlist.csv
.Note: The
mainlist.csv
file contains all the user groups membership details. If the user does not belong to any group, then the value is set as None.
Related Links
Acknowledgments
Author - Gautam Mishra (Senior Cloud Engineer)
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.
Generate User Group membership report from OCI IAM Identity Domains using Python
F82226-01
May 2023
Copyright © 2023, Oracle and/or its affiliates.