Exclusion rule to remove IT roles mapped to business roles for certification review

Which IIQ version are you inquiring about?

Version 8.3

Share all details related to your problem, including any error messages you may have received.

We have set up the rule as per the suggestions we got in this forum however it is showing nothing to certify message and throwing an beanshell error .

import sailpoint.object.Identity;
import sailpoint.object.Bundle;
import sailpoint.api.SailPointContext;
import sailpoint.tools.GeneralException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
 

  
//List<Bundle> excludeITRolesForIdentityInCertification(SailPointContext context, Identity identity, List<Bundle> certificationItems) throws GeneralException {
   List<Bundle> itemsToExclude = new ArrayList();
  List<Bundle> requiredRoles = new ArrayList();
    
  
    for (CertificationItem certItem : certItems) {
    bundleName = certItem.getBundle();
    if (Log.isDebugEnabled()) mgLog.debug("bundleName: " + bundleName);
    Bundle bundle = context.getObjectByName(Bundle.class, bundleName);
      
    //if (bundle.getAttribute("Type") = "Business") 
    if ("Business".equalsIgnoreCase(bundle.getAttribute("Type")){
             requiredRoles = bundle.getRequiredRoles(); // Assuming getRequiredRoles() fetches the underlying roles
              //if(Log.isDebugEnabled())Log.debug(" listofrequiredRoles "+requiredRoles);
      
    } 
      
      for (Bundle requiredRole : requiredRoles) {
                    // Check if the required role is an IT role
                    if ("IT".equalsIgnoreCase(requiredRole.getType())) {
                        // Add IT role to exclusion list if not already added
                        if (!itemsToExclude.contains(requiredRole)) {
                            itemsToExclude.add(requiredRole);
                          if(Log.isDebugEnabled())mgLog.debug(" itemstoExclude "+itemsToExclude);
              
                
                        }
                    }
                }
            }

    // Logic to exclude the identified IT roles from the certification review for the specific identity
    // This might involve removing them from certificationItems or marking them as excluded
  

    return itemsToExclude; // Return the list of excluded items, or adjust as needed based on exclusion logic
}

And we have also tried with below code but it is not excluding the underlying IT roles which are mapped to business role in certification review.

import sailpoint.object.Certifiable;
  import sailpoint.object.Bundle;
  import java.util.List;
  import java.util.Iterator;
  import java.util.ArrayList;

  StringBuffer explanation = new StringBuffer();

    public List getFlattenedRoles(){
    List<RoleAssignment> assignedRoles = identity.getRoleAssignments();
    List<Bundle> flattenedRoles = new ArrayList<Bundle>();
    if (assignedRoles!=null && assignedRoles.size()>0){
      for (RoleAssignment role : assignedRoles){
        Bundle bun = role.getRoleObject(context);
        flattenedRoles.addAll(bun.getFlattenedRequirements());
      }
    }
    return flattenedRoles;
  }
  public List getTobeExcludedRoles(List detectedBundles, List allBundles){
    List tobeExcludedRoles = new ArrayList();
    for (Bundle bun : detectedBundles){
      if (allBundles.contains(bun)){
        tobeExcludedRoles.add(bun);
      }
    }
    return tobeExcludedRoles;
  }

 if (entity instanceof Identity) {
   Identity identity = (Identity) entity;
   Iterator it = items.iterator();
   
      while(it.hasNext()) {
     Certifiable certifiable = (Certifiable) it.next();
     if(certifiable instanceof Bundle) {
       Bundle bundle = (Bundle) certifiable;
       if (toExclude.contains(bundle)){
         itemsToExclude.add(bundle);
         it.remove();
         explanation.append("Exclude \"" + bundle.getName() + "\" from certification. Role is part of an assigned Role.\n");
         continue;
       }
     }
   }
 }

  return (0 != explanation.length()) ? explanation.toString() : null;

Hi @Aradhana_Mohapatra,

can you shere the error? and what is your goal?

It is showing error
An unexpected error occurred: BeanShell script error: bsh.ParseException: Parse error at line 16, column 49. Encountered: > BSF info: Exclusion rule for underlying IT roles at line: 0 column: columnNo"

We want to exclude IT roles which are only mapped to business role in cert review

Can you check if all braces are opened and closed; and if there are other syntax errors?

In the first rule you need one more parenthesis to end:

if (“Business”.equalsIgnoreCase(bundle.getAttribute(“Type”)){

and you have one more “}” at line 38(more o less).

In the second where is defined items variable?

Iterator it = items.iterator();

and try to use a collection like type for flattenedRoles, because getFlattenedRequirements() come back a collection.

@Aradhana_Mohapatra

Hi and Hello,

Try that.

import sailpoint.object.Identity;
import sailpoint.object.Bundle;
import sailpoint.api.SailPointContext;
import sailpoint.tools.GeneralException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;

List<Bundle> itemsToExclude = new ArrayList();
List<Bundle> requiredRoles = new ArrayList();

for (CertificationItem certItem : certItems) {
    String bundleName = certItem.getBundle(); // Added type String to bundleName
    // if (Log.isDebugEnabled()) mgLog.debug("bundleName: " + bundleName);
    Bundle bundle = context.getObjectByName(Bundle.class, bundleName);

    // if (bundle.getAttribute("Type") == "Business")
    if ("Business".equalsIgnoreCase(bundle.getAttribute("Type"))) { // Added missing closing parenthesis
        requiredRoles = bundle.getRequiredRoles(); // Assuming getRequiredRoles() fetches the underlying roles
        // if (Log.isDebugEnabled()) Log.debug("list of requiredRoles: " + requiredRoles);

        for (Bundle requiredRole : requiredRoles) {
            // Check if the required role is an IT role
            if ("IT".equalsIgnoreCase(requiredRole.getType())) {
                // Add IT role to exclusion list if not already added
                if (!itemsToExclude.contains(requiredRole)) {
                    itemsToExclude.add(requiredRole);
                    // if (Log.isDebugEnabled()) mgLog.debug("itemsToExclude: " + itemsToExclude);
                }
            }
        }
    }
}

// Logic to exclude the identified IT roles from the certification review for the specific identity
// This might involve removing them from certItems or marking them as excluded

return itemsToExclude; // Return the list of excluded items, or adjust as needed based on exclusion logic

Key Fixes

  1. Added type String to the variable bundleName.
  2. Changed the comparison operator = to == and fixed the condition: if (bundle.getAttribute("Type") == "Business") to if ("Business".equalsIgnoreCase(bundle.getAttribute("Type"))).
  3. Added the missing closing parenthesis ) in the if statement.

Regards,
Adam

1 Like

So do you mean I have to use getflattenedrequirements() instead og getrequirements();

I am also thinking to add below as per the logics
A manager certification which is staged for the org, it will first get certifier details and then certification items which that certifier owns

String targetIdentity = entity.getCertifiers();
if (Log.isDebugEnabled()) Log.debug("targetIdentity: " + targetIdentity);
List<CertificationItem> certItems = entity.getItems();
ArrayList<String> rolesToBeExcluded = new ArrayList<String>();

for (CertificationItem certItem : certItems) {
    String bundleName = certItem.getBundle();
    if (Log.isDebugEnabled()) Log.debug("bundleName: " + bundleName);
    Bundle bundle = context.getObjectByName(Bundle.class, bundleName);

    if (bundle != null && "business".equalsIgnoreCase(bundle.getType())) {
        List<Bundle> requiredRoles = bundle.getRequirements();
        for (Bundle requiredRole : requiredRoles) {
                rolesToBeExcluded.add(requiredRole.getName());
            
        }
    }
}

// Now, iterate over certItems again to exclude items based on rolesToBeExcluded
List<CertificationItem> itemsToRemove = new ArrayList<CertificationItem>();
for (CertificationItem certItem : certItems) {
    Bundle bundle = context.getObjectByName(Bundle.class, certItem.getBundle());
    if (bundle != null && rolesToBeExcluded.contains(bundle.getName())) {
        itemsToExclude.add(certItem);
    }
}
if (Log.isDebugEnabled()) Log.debug("================== END ======================");
// Remove the IT roles from the items list.
items.removeAll(itemsToExclude);
return "This item has been excluded";

@Aradhana_Mohapatra
In my opinion,

import sailpoint.object.Identity;
import sailpoint.object.Bundle;
import sailpoint.api.SailPointContext;
import sailpoint.tools.GeneralException;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;

String targetIdentity = entity.getCertifiers();
if (Log.isDebugEnabled()) Log.debug("targetIdentity: " + targetIdentity);

List certItems = entity.getItems();
ArrayList rolesToBeExcluded = new ArrayList();

for (CertificationItem certItem : certItems) {
    String bundleName = certItem.getBundle(); // Declare bundleName as String
    if (Log.isDebugEnabled()) Log.debug("bundleName: " + bundleName);

    Bundle bundle = context.getObjectByName(Bundle.class, bundleName);

    if (bundle != null && "business".equalsIgnoreCase(bundle.getType())) { // Ensure bundle is not null and check type
        List<Bundle> requiredRoles = bundle.getRequirements(); // Assuming getRequirements() fetches the required roles
        for (Bundle requiredRole : requiredRoles) {
            rolesToBeExcluded.add(requiredRole.getName()); // Add names of required roles to rolesToBeExcluded
        }
    }
}

// Now, iterate over certItems again to exclude items based on rolesToBeExcluded
ArrayList itemsToExclude = new ArrayList();
for (CertificationItem certItem : certItems) {
    Bundle bundle = context.getObjectByName(Bundle.class, certItem.getBundle());
    if (bundle != null && rolesToBeExcluded.contains(bundle.getName())) {
        itemsToExclude.add(certItem);
    }
}

if (Log.isDebugEnabled()) Log.debug("================== END ======================");

// Remove the IT roles from the items list.
certItems.removeAll(itemsToExclude);

return "This item has been excluded";

Key Points:

  1. Added type String to the variable bundleName:

String bundleName = certItem.getBundle();

  1. Ensured proper usage of curly braces {} in all conditional blocks:
if (bundle != null && "business".equalsIgnoreCase(bundle.getType())) {
    // ...
}
  1. Changed items to certItems in the removal operation:

certItems.removeAll(itemsToExclude);

Regards,
Adam

3 Likes

how you prefer, getflattenedrequirements return a collection, getrequirements a list of bundle

1 Like

Thanks Adam,

Will try with the changes you mentioned.

No problemo,
Give update.

Regards,
Adam

1 Like

Hello Adam,

The above logics are working fine and removing IT roles which are mapped to business role from cert review. Thanks for looking into it.

2 Likes

Hi Emanuele,

Thanks for looking into it. The flattenedrequirements method finally worked .

1 Like

Marked as solution for the rule.

1 Like

@Aradhana_Mohapatra , not sure what your use case is, but beware your usage of this rule in targeted certs :slight_smile:
OOTB, if a user has a business role, that role will be included in a review (which includes roles). However, if the user has accesses which correspond to what is in an IT role, but the user does not have the corresponding business roles, then this access will only be included in a targeted campaign, through an IT role (detected role). Hence, if you exclude the IT roles, those user accesses are not being reviewed - if that’s what you want, great, but if not, you’ll need to make sure you review those accesses in another way.

1 Like

Hi Ann,

The usage of this rule will be in line manager cert review as prior to this we will be setting up role composition cert review for all business roles and IT roles mapped to it.

With the script I can verify that in line manager cert it is removing IT roles as a cert item and only the details are being populated under business roles. So a manager can decide by reviewing the business role as a cert item and can go through the details of IT roles mapped to it.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.