HI @ismaelmoreno1
thank you for taking time to check. When i check the the payload and POST, it does not seem correlate with the methods you shared. I am sharing the screenshots and information below. I will also share the Violation form that I have.
Is it also possible to provide/check the javascript? It seems using the same functions, but for multiple items it is skipped. List listOfViolations is a name, it is custom validation.
I can see from the network logs that it choose different path and the difference is response. Single item vs multiple items.
Multiple identities:
requestAccess POST
accessRequest.jsf - message
home - dashboard
Multiple identities workitems:
cannot add image
Payload:
{identities: ["0a017c5a8bf71d1e818bf7c0587e065f", "0a017c5a8bf71d1e818bf7c0372b0417"], addedRoles: [],…}
addedEntitlements
:
[{id: "0a017c5a8b8b1c33818b94e882fc1cc3", comment: null, sunrise: null, sunset: null,…}]
addedRoles
:
[]
identities
:
["0a017c5a8bf71d1e818bf7c0587e065f", "0a017c5a8bf71d1e818bf7c0372b0417"]
priority
:
null
quickLink
:
"Request Access"
removedEntitlements
:
[]
removedRoles
:
[]
Response:
[
{
"identityRequestId": "",
"workflowStatus": "approving",
"workflowWorkItemType": "Form",
"workflowWorkItemId": "0a017c5a8c5d18ef818c5db3ec0e00a9",
"messages": [],
"approvalItems": [],
"allowViolations": false,
"requireViolationComment": false
},
{
"identityRequestId": "",
"workflowStatus": "approving",
"workflowWorkItemType": "Form",
"workflowWorkItemId": "0a017c5a8c5d18ef818c5db3ef4800ac",
"messages": [],
"approvalItems": [],
"allowViolations": false,
"requireViolationComment": false
}
]
Single identity:
requestAccess POST
load FORM workitem details
load FORM workitem details
submit - cancel request
accessRequest.jsf - message
home - dashboard
Javascript same for both cases in requestAccess POST:
cannot add image
The form is displayed at the end of access request page.
cannot add image
Custom Validate Access Request – Subprocess
Before LCM Provisioning Initialize
Then Initialize is called and if listOfViolations exist and ends the workflowcase.
<Step action="rule:Validate If AAD Account Exists Rule" icon="Default" name="Validate AAD Account Exists" posX="668" posY="208" resultVariable="listOfViolations">
<Transition to="Build Violations Form" when="!sailpoint.tools.Util.isEmpty(listOfViolations);"/>
<Transition to="end"/>
</Step>
<Step action="rule:Build Violations Form Rule" icon="Default" name="Build Violations Form" posX="730" posY="36" resultVariable="violationsForm">
<Transition to="Show Violations Info"/>
</Step>
<Step icon="Default" name="Show Violations Info" posX="905" posY="35">
<Approval name="Show Access Request Violations Form" owner="ref:launcher">
<Arg name="workItemType" value="Form"/>
<Arg name="workItemDescription" value="List of Violations"/>
<Arg name="workItemForm" value="ref:violationsForm"/>
</Approval>
<Transition to="Add WF Message"/>
</Step>
Form, go through list of policyViolations and add Fields:
When i was running debug. The list of listOfViolations is always 1, not 2 or 3 based on number of identities. Therefore the violation seems to be split to each workflowCase
cannot add image
public static Form runBuildFormRule(List<Map<Object,Object>> listOfViolations)
{
Form form = new Form();
form.put(Form.ATT_PAGE_TITLE, Utils.getLocalizedMessage("access_request_violation_pagetitle"));
form.put(Form.ATT_SUBTITLE, Utils.getLocalizedMessage("access_request_violation_subtitle"));
int counter = 1;
if (log.isDebugEnabled()) {
log.debug("number of violations: " + listOfViolations.size());
for (Map<Object,Object> violationMap : Util.safeIterable(listOfViolations)) {
for (Map.Entry<Object, Object> entry : violationMap.entrySet()) {
String key = (String) entry.getKey();
String value = (String) entry.getValue();
log.debug("key: " + key + " value: " + value);
}
}
}
// Build and populate the violation form
// Code Review: Replaced 'Map' with 'Map<Object,Object>' on following line:
for (Map<Object,Object> violationMap : Util.safeIterable(listOfViolations)) {
String violationApplicationName = (String) violationMap.get("applicationName");
String violationAttributeName = (String) violationMap.get("name");
String violationAttributeValue = (String) violationMap.get("value");
String violationMessage = (String) violationMap.get("violationMessage");
String violationDescription = (String) violationMap.get("violationDescription");
String violationIdentityName = (String) violationMap.get("identityName");
String violationNativeIdentity = (String) violationMap.get("nativeIdentity");
Form.Section violationsSection = new Form.Section();
violationsSection.setLabel("Error: " + violationMessage);
violationsSection.setType("datatable");
violationsSection.setName("Violation" + counter);
if (Util.isNotNullOrEmpty(violationIdentityName)) {
addFieldToViolationsSection(violationsSection, "identityName", "Identity", violationIdentityName);
}
if (Util.isNotNullOrEmpty(violationNativeIdentity)) {
addFieldToViolationsSection(violationsSection, "nativeIdentity", "Native Identity", violationNativeIdentity);
}
if (Util.isNotNullOrEmpty(violationApplicationName)) {
addFieldToViolationsSection(violationsSection, "applicationName", "Application", violationApplicationName);
}
if (Util.isNotNullOrEmpty(violationAttributeName)) {
addFieldToViolationsSection(violationsSection, "attributeName", "Attribute", violationAttributeName);
}
if (Util.isNotNullOrEmpty(violationAttributeValue)) {
addFieldToViolationsSection(violationsSection, "attributeValue", "Value", violationAttributeValue);
}
if (Util.isNotNullOrEmpty(violationMessage)) {
addFieldToViolationsSection(violationsSection, "violationMessage", "Message", violationMessage);
}
if (Util.isNotNullOrEmpty(violationDescription)) {
addFieldToViolationsSection(violationsSection, "violation", "Description", violationDescription);
}
form.add(violationsSection);
counter++;
}
Form.Button button = new Form.Button();
button.setAction("next");
button.setLabel("Cancel Request");
button.setValue("next");
form.add(button);
return form;
}
// private method to add a filed to the form
private static void addFieldToViolationsSection(Form.Section section, String name, String displayName, String value) {
Field violationField = new Field();
violationField.setDisplayName(displayName);
violationField.setName(name);
violationField.setValue(value);
violationField.setType("string");
violationField.setReadOnly(true);
section.add(violationField);
}