Fetching assigned Roles

Hi, I am making forms and in a field I need to display assigned roles of an account which is under selected Application.
I am using below script for the same but the roles are not getting displayed in the field.

What am I doing wrong here?

<Field displayName="Remove Roles" dynamic="true" multi="true" name="removeRoles" postBack="true" type="string">
      <AllowedValuesDefinition>
        <Script>
          <Source>
import sailpoint.object.Application;
import sailpoint.object.Bundle;
import sailpoint.object.Identity;
import sailpoint.object.Link;
import sailpoint.object.RoleAssignment;
import sailpoint.tools.Util;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

    Set roleSet = new HashSet(); // Using Set to avoid duplicates

    // Fetch selected application
    String appName = form.getField("applicationName").getValue();
    if (Util.isNullOrEmpty(appName)) {
      return new ArrayList(roleSet); // No application selected
    }

    Application selectedApp = context.getObjectByName(Application.class, appName);
    if (selectedApp == null) {
      return new ArrayList(roleSet); // Application does not exist
    }

    // Fetch selected account
    String selectedAccount = form.getField("selectAccount").getValue();
    if (Util.isNullOrEmpty(selectedAccount)) {
      return new ArrayList(roleSet); // No account selected
    }

    // Extract the account identifier from "Application Name : Account Name" format
    String[] accountParts = selectedAccount.split(" : ");
    if (accountParts.length &lt; 2) {
      return new ArrayList(roleSet); // Invalid format
    }
    String accountId = accountParts[1].trim();

    // Get identity object (current user)
    Identity identity = context.getObjectByName(Identity.class, context.getUserName());
    if (identity == null) {
      return new ArrayList(roleSet); // Identity not found
    }

    // Fetch accounts (links) for this identity
    List links = identity.getLinks();
    if (links != null &amp;&amp; links.size() > 0) {
      for (int i = 0; i &lt; links.size(); i++) {
        Link link = (Link) links.get(i);
        if (link.getNativeIdentity().equals(accountId) &amp;&amp; link.getApplication().getName().equals(appName)) {
          
          // Fetch assigned roles
          List roleAssignments = link.getRoleAssignments();
          if (roleAssignments != null) {
            for (int j = 0; j &lt; roleAssignments.size(); j++) {
              RoleAssignment roleAssignment = (RoleAssignment) roleAssignments.get(j);
              Bundle role = roleAssignment.getRole();
              if (role != null) {
                roleSet.add(role.getName()); // Add assigned role to the set
              }
            }
          }
        }
      }
    }

    // Fetch detected roles
    List detectedRoles = identity.getDetectedRoles();
    if (detectedRoles != null) {
      for (int k = 0; k &lt; detectedRoles.size(); k++) {
        Bundle detectedRole = (Bundle) detectedRoles.get(k);
        if (detectedRole != null) {
          String detectedRoleApp = (String) detectedRole.getAttribute("application"); // Get application name
          if (detectedRoleApp != null &amp;&amp; detectedRoleApp.equals(appName)) {
            roleSet.add(detectedRole.getName()); // Add detected role to the set
          }
        }
      }
    }

    if (roleSet.isEmpty()) {
      roleSet.add("No Roles Found");
    }

    return new ArrayList(roleSet); // Return list of roles (assigned + detected)
  </Source>
        </Script>
      </AllowedValuesDefinition>
    </Field>

Hi @pctripathi,

You actually cannot retrieve assigned and detected roles from a Link object. Instead, you must get them from the Identity object.

Try replacing this part of your code:

// Fetch accounts (links) for this identity
    List links = identity.getLinks();
    if (links != null &amp;&amp; links.size() > 0) {
      for (int i = 0; i &lt; links.size(); i++) {
        Link link = (Link) links.get(i);
        if (link.getNativeIdentity().equals(accountId) &amp;&amp; link.getApplication().getName().equals(appName)) {
          
          // Fetch assigned roles
          List roleAssignments = link.getRoleAssignments();
          if (roleAssignments != null) {
            for (int j = 0; j &lt; roleAssignments.size(); j++) {
              RoleAssignment roleAssignment = (RoleAssignment) roleAssignments.get(j);
              Bundle role = roleAssignment.getRole();
              if (role != null) {
                roleSet.add(role.getName()); // Add assigned role to the set
              }
            }
          }
        }
      }
    }

    // Fetch detected roles
    List detectedRoles = identity.getDetectedRoles();
    if (detectedRoles != null) {
      for (int k = 0; k &lt; detectedRoles.size(); k++) {
        Bundle detectedRole = (Bundle) detectedRoles.get(k);
        if (detectedRole != null) {
          String detectedRoleApp = (String) detectedRole.getAttribute("application"); // Get application name
          if (detectedRoleApp != null &amp;&amp; detectedRoleApp.equals(appName)) {
            roleSet.add(detectedRole.getName()); // Add detected role to the set
          }
        }
      }
    }

with this updated approach:

  if(identity.getRoleAssignments() != null){
    for(roleAssig : identity.getRoleAssignments()){
      if(roleAssig.getTargets() != null){
        for(roleTarget : roleAssig.getTargets()){
          if(roleTarget.getApplicationName().equals(appName)){
            roleSet.add(roleAssig.getRoleName());
          }
        }
      }
    }
  }
  
  if(identity.getRoleDetections() != null){
    for(roleDetec : identity.getRoleDetections()){
      if(roleDetec.getTargets() != null){
        for(roleTarget : roleDetec.getTargets()){
          if(roleTarget.getApplicationName().equals(appName)){
            roleSet.add(roleDetec.getRoleName());
          }
        }
      }
    }
  }

Let me know if this helps!

Hi @angelborrego
I replaced suggested code with the one you suggested. After that I selected the application from my form and the account which is part of that application.
Still getting no roles selected but I can see there is a role associated with the selected application as well as the account.

When you say no roles are being selected but you can see there is a role associated with the account and application, are you referring to the field not being automatically populated with roles? Or do you mean the roles are not showing at all in the dropdown menu for the field?

Roles are not being displayed in the dropdown of the Remove Role Field

Hi,

I tested the code in my SailPoint environment, and it worked correctly, so the issue might lie earlier in the process.

I recommend adding some System.out.println() statements inside your if conditions to check the values of the variables (like appName, selectedApp, selectedAccount, accountId, or the identity object). This will help you identify if any of them are returning a null value.

I’m glad to hear you found a solution and that it’s working now! If my suggestions helped you find the issue, it would be great if you could mark my post as the solution. It would really help me out as I work towards becoming a SailPoint Ambassador.

Thanks again for the update, and feel free to reach out if you have any more questions!