Search code examples
javajasper-reportsbeanshellsailpoint

SailPoint reporting limit user view


We have 5 custom reports for our 94 districts. A capability grants access to these custom reports.

The issue is that each district should not see the report results from another district.

Currently, the only alternative is to create 5 * 94 = 470 custom reports, granting a set of 5 to each district. However, this is cumbersome when a report needs to be updated. TaskDefinitions (Reports) create TaskResult objects (the result of a report). In addition, to the TaskResult object, a JasperReport object is created. Neither the TaskResult/JasperResult object "re-executes" BeanShell when you open the task result.

Is there a way to only have 5 reports and scope the results so that only users in that district can see them?

I have an example of how this might be achieved when based on this code below which will look at the scope(s) of the one who is running the report. It will only return identities that are in the same scope as the one that is running the report

// Retrieve Scope of Executor then filter all Identities on that Scope only
import org.apache.commons.logging.Log;
import sailpoint.object.Filter;
import sailpoint.object.Identity;
import sailpoint.object.Scope;
                      

Identity identity = context.getObjectByName(Identity.class, arguments.get("launcher"));
                      
if (identity != null) {
  String scopeName = identity.getAssignedScope().getDisplayableName();
  List roleFilters = new ArrayList();
    
  if (scopeName!= null) {                          
    roleFilters.add(Filter.eq("identity.assignedScope.name", scopeName));
  }
                    
  if (!roleFilters.isEmpty()) {
    queryOptions.addFilter(Filter.or(roleFilters));
  }
} else {
  // When Saving with Preview or Execute the Launcher is empty so all results would be shown.
  // This filter will prevent that (creates empty report, it works when executed from the My Reports 
  queryOptions.addFilter(Filter.eq("identity.name", "xxx"));
}

return queryOptions;

The problem with the code sample above:

This will create the report intended for Group A, however Group B, and C will also be able to view it.

So the end goal is to have one report that anyone can run, however only the data that is associated with that scope is visible no matter what user group is involved (scope). So Group B would only be able to view Group B even if Group A ran it.


Solution

  • I think you don't have good options here.

    What comes to my mind is to create these reports programatically (writing some script to generate the XML artifact for the TaskDefinition and importing/exporting using IIQDA for example) and maintain them in the same way, so everytime you need to change each one of these hundreds of artifacts, you can just re-generate them via code.

    The only thing I'd do in a different way is to use 94 scopes for each 5-set report instead of using capabilities.