Hi All,
I have integrated one Web Service application with our tenant.
For remove entitlement we are having API where we need to PATCH the roles again, removing that role which we want to revoke.
eg.
User is having role1, role2 and role3 assigned. If role2 is getting revoked then we are using Update user API and PATCH the body
{
"roles": ["role1" , "role3"]
}
From postman this is working fine, how to implement this in Sailpoint?
Did anyone came across this scenario . What could be done in this situation?
Thanks
I just wanted to clarify something—when one role is revoked, it seems like the system also revokes other associated roles. In such cases, do we need to manually patch and update the other roles to reassign them?
Is my understanding correct? Could you help me with a clearer query or explanation?
So we are not having remove entitlement API. We can do it using update user only. And In Update user API we need to patch the body with all the roles except ‘the revoked one’
In simple terms we need to override the existing roles.
For this I would use a combination of two different HTTP operations and a before operation rule.
HTTP Operation 1 is set to ‘remove entitlement’ type, but actually calls out to the Webservice API to get all entitlements of the current user. Ensure you properly map the response so you can use it in the next operation.
HTTP Operation 2 is your ‘Patch’ operation type, with type ‘get object’ and should have as it’s parent the previous operation. The body can be something like $plan.groups$ (depending on what you call your entitlements in the schema)
Then you create a before operation rule that takes what is in the body and what was retrieved from the first operation and then remove from the response of HTTP operation 1 whatever is in your $plan.groups$.
Here is an example of something I created for a similar use case:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import connector.common.JsonUtil;
import connector.common.Util;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
Map body = requestEndPoint.getBody();
String jsonBody = (String) body.get("jsonBody");
List capabilities = new ArrayList();
List currentCapabilities = oldResponseMap.get("capabilities");
currentCapabilities.remove(jsonBody);
for (String cap: currentCapabilities) {
capabilities.add(cap);
}
Map authUserMap = new HashMap();
authUserMap.put("op", "replace");
authUserMap.put("path","/capabilities");
authUserMap.put("value",capabilities);
List authUserList = new ArrayList();
authUserList.add(authUserMap);
String finalBody = JsonUtil.render(authUserList);
body.put("jsonBody", finalBody);
requestEndPoint.setBody(body);
For this you can use the Before Operation rule, in which you call an another API to get the user’s assigned entitlements, compare them with the requested entitlement for removal, and use the remaining entitlements in the PATCH body in update user API.
Hi @sauvee I am trying to write single rule for all. I am adding the rule here. I am getting error
Error in method invocation: Method executeGet(java.lang.String, java.util.HashMap) not found in class\u0027sailpoint.connector.webservices.WebServicesClient\u0027 : at Line: 50 : in file: inline evaluation of: ``import java.util.; import sailpoint.tools.; import connector.common.JsonUtil; . . . \u0027\u0027 : restClient .executeGet ( getUrl , headers ) \n BSF info: SplunkRoleRemove at line: 0 column: columnNo"]
Checked everywhere on executeGet not sure why getting this error, do you have any idea ?
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule name="SplunkRoleRemoval" type="WebServiceBeforeOperationRule">
<Description>Removes a role and updates user roles in Splunk</Description>
<Source><![CDATA[
import java.util.*;
import sailpoint.tools.*;
import connector.common.JsonUtil;
import sailpoint.object.*;
import connector.common.Util;
import org.json.JSONObject;
import org.json.JSONArray;
log.debug("WSBO Rule Started");
try {
// STEP 1: Retrieve the userId and role to remove from the provisioning plan
String userId = null;
String roleToRemove = null;
if (provisioningPlan != null) {
for (AccountRequest accReq : Util.iterate(provisioningPlan.getAccountRequests())) {
userId = accReq.getNativeIdentity();
log.debug("UserId to update: " + userId);
for (ProvisioningPlan.AttributeRequest attReq : Util.iterate(accReq.getAttributeRequests())) {
String attrName = attReq.getName();
if ("roles".equalsIgnoreCase(attrName)) {
roleToRemove = (String) attReq.getValue();
}
}
}
}
if (userId == null || roleToRemove == null) {
throw new IllegalArgumentException("UserId or role to remove not found in the provisioning plan.");
}
log.debug("Role to remove: " + roleToRemove);
// STEP 2: Get the user's current roles from Splunk via API (GET)
String bearerToken = "xxxx"; // Use your actual token
String baseUrl = "xxxxxx";
String getUrl = baseUrl + userId; // Full URL to call the API with userId
// Headers setup
Map headers = new HashMap();
headers.put("Authorization", "Bearer " + bearerToken);
// RestClient setup
Map args = new HashMap();
args.put(WebServicesClient.ARG_URL, baseUrl); // Set the base URL
restClient.configure(args); // Configure the restClient with base URL
// STEP 3: Execute GET request to retrieve current roles using `executeGet` method
String response = restClient.executeGet(getUrl, headers); // This is the key change
// Parse the response JSON to get the roles
JSONObject jsonResponse = new JSONObject(response);
JSONArray currentRolesArray = jsonResponse.getJSONArray("roles");
List updatedRoles = new ArrayList();
for (int i = 0; i < currentRolesArray.length(); i++) {
String role = currentRolesArray.getString(i);
if (!role.equalsIgnoreCase(roleToRemove)) {
updatedRoles.add(role);
}
}
// STEP 4: Create PATCH body to update the roles in Splunk
Map updatePayload = new HashMap();
updatePayload.put("roles", updatedRoles);
// Convert the payload to JSON
String jsonPayload = JsonUtil.render(updatePayload);
log.debug("Final PATCH Payload for Splunk API: " + jsonPayload);
// STEP 5: Send the PATCH request to Splunk API to update roles
String patchUrl = baseUrl + userId;
String patchResponse = restClient.executePatch(patchUrl, jsonPayload, headers);
log.debug("Splunk API PATCH Response: " + patchResponse);
// STEP 6: Set the updated payload to the request body
Map body = requestEndPoint.getBody(); // Access the existing requestEndPoint
body.put("jsonBody", jsonPayload);
requestEndPoint.setBody(body); // Set the updated body
} catch (Exception e) {
log.debug("Error in WebServiceBeforeOperationRule: " + e.getMessage());
throw e; // Re-throw the exception to indicate failure in the rule
}
return requestEndPoint;
]]></Source>
</Rule>
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule name="SplunkRoleRemoval" type="WebServiceBeforeOperationRule">
<Description>Removes a role and updates user roles in Splunk</Description>
<Source><![CDATA[
import java.util.*;
import sailpoint.tools.*;
import connector.common.JsonUtil;
import sailpoint.object.*;
import connector.common.Util;
import org.json.JSONObject;
import org.json.JSONArray;
log.debug("WSBO Rule Started");
try {
// STEP 1: Retrieve the userId and role to remove from the provisioning plan
String userId = null;
String roleToRemove = null;
if (provisioningPlan != null) {
for (AccountRequest accReq : Util.iterate(provisioningPlan.getAccountRequests())) {
userId = accReq.getNativeIdentity();
log.debug("UserId to update: " + userId);
for (ProvisioningPlan.AttributeRequest attReq : Util.iterate(accReq.getAttributeRequests())) {
String attrName = attReq.getName();
if ("roles".equalsIgnoreCase(attrName)) {
roleToRemove = (String) attReq.getValue();
}
}
}
}
if (userId == null || roleToRemove == null) {
throw new IllegalArgumentException("UserId or role to remove not found in the provisioning plan.");
}
log.debug("Role to remove: " + roleToRemove);
// STEP 2: Get the user's current roles from Splunk via API (GET)
String bearerToken = "xxxx"; // Use your actual token
String baseUrl = "xxxxxx";
String getUrl = baseUrl + userId; // Full URL to call the API with userId
// Headers setup
Map headers = new HashMap();
headers.put("Authorization", "Bearer " + bearerToken);
// RestClient setup
Map args = new HashMap();
args.put(WebServicesClient.ARG_URL, baseUrl); // Set the base URL
restClient.configure(args); // Configure the restClient with base URL
List allowedStatuses = new ArrayList();
allowedStatuses.add("2**");
// STEP 3: Execute GET request to retrieve current roles using `executeGet` method
String response = restClient.executeGet(getUrl, headers, allowedStatuses); // This is the key change
// Parse the response JSON to get the roles
JSONObject jsonResponse = new JSONObject(response);
JSONArray currentRolesArray = jsonResponse.getJSONArray("roles");
List updatedRoles = new ArrayList();
for (int i = 0; i < currentRolesArray.length(); i++) {
String role = currentRolesArray.getString(i);
if (!role.equalsIgnoreCase(roleToRemove)) {
updatedRoles.add(role);
}
}
// STEP 4: Create PATCH body to update the roles in Splunk
Map updatePayload = new HashMap();
updatePayload.put("roles", updatedRoles);
// Convert the payload to JSON
String jsonPayload = JsonUtil.render(updatePayload);
log.debug("Final PATCH Payload for Splunk API: " + jsonPayload);
// STEP 5: Send the PATCH request to Splunk API to update roles
String patchUrl = baseUrl + userId;
String patchResponse = restClient.executePatch(patchUrl, jsonPayload, headers);
log.debug("Splunk API PATCH Response: " + patchResponse);
// STEP 6: Set the updated payload to the request body
Map body = requestEndPoint.getBody(); // Access the existing requestEndPoint
body.put("jsonBody", jsonPayload);
requestEndPoint.setBody(body); // Set the updated body
} catch (Exception e) {
log.debug("Error in WebServiceBeforeOperationRule: " + e.getMessage());
throw e; // Re-throw the exception to indicate failure in the rule
}
return requestEndPoint;
]]></Source>
</Rule>