Search This Blog

Wednesday, December 18, 2019

SailPoint issues with creating duplicate Entitlements

I experienced issues with duplicate entitlements being created for an Active Directory application.  The issue appeared when there were nested AD groups that were inheriting other groups.

The symptom was some rogue ManagedAttribute objects with type="Entitlement" instead of "group" which caused a failure "Exception during aggregation of <group>. Reason: could not insert: [sailpoint.object.ManagedAttribute]

The issue came down to some bad settings:

First, in the Active Directory account aggregation, the Promote Managed Attributes checkbox was checked.  This should only be checked if there is NO account group aggregation.  The account group aggregation replaces this checkbox.

Second, the memberOf schema value on the account was not set to schemaObjectType of group.  This, along with Managed, Entitlement, and Multi-Valued, are required for this field.

Finally, the memberOf schema value on the group was not set to schemaObjectType of group.  Also while the Entitlement and Multi-Valued checkboxes were set, the Indexed was not, and so I set that Indexed in order to match another successfully running application on a different AD domain.

To summarize, for AD connections:

On account aggregation, do NOT select "Promote Managed Attributes"
On the account schema, select group as the schemaObjectType, plus Managed, Entitlement, and Multi-Valued
On the group schema, select group as the schemaObjectType, plus Entitlement, Multi-Valued, and Indexed.

 

Monday, December 2, 2019

Figuring out how to work with getOp or getOperation

The classes ProvisioningPlan.AccountRequest and ProvisioningPlan.AttributeRequest have operations associated with them.  Here's how to query and use them.  This might be updated as I gather more info.

AccountRequest actually has two flavors:

sailpoint.object.ProvisioningPlan.AccountRequest
sailpoint.integration.ProvisioningPlan.AccountRequest

The former is used internally for building and requesting, the latter is passed into IntegrationConfig classes.

Starting with the former, it has the following operation method:

sailpoint.object.ProvisioningPlan.AccountRequest.Operation getOperation()
This returns an enum one of the following:

Create
Delete
Disable
Enable
Lock
Modify
Unlock

Unless there is an account type request, most of the time this will be Modify, for modifying data or adding or removing entitlements.  Two easy ways to deal with this are:

if (AccountRequest.Operation.Enable == acctReq.getOperation()) {

This defends against an NPE

and the less preferred

if("Enable".equals(acctReq.getOperation().valueOf()) {

For the AttributeRequests, that class does not have its own getOperation method, it inherits the following method from sailpoint.object.ProvisioningPlan.GenericRequest:

sailpoint.object.ProvisioningPlan.Operation getOp()

This returns an enum one of the following:
Add
Remove
Retain
Revoke
Set

You will most likely see Add, Remove, and Set and can use:

if (ProvisioningPlan.Operation.Add == attrReq.getOp()) {

or the less preferred:

if ("Add".equals(attrReq.getOp().valueOf())) {

For sailpoint.integration.ProvisioningPlan.AccountRequest the following method is provided:

String getOperation()
Which returns the valueOf for one of the ProvisioningPlanAccountRequest.Operation constants

and for sailpoint.integration.ProvisioningPlan.AttributeRequest the following method is provided:

String getOperation()
Which returns the valueOf for one of the ProvisioningPlan.Operation constants.


Friday, October 25, 2019

Fixing SailPoint WorkItem pages

Fixing the SailPoint WorkItem pages so that it displays type, owner, requester and allows searches.

<entry key="debugWorkItemArchiveSearchProperties" value="id,name,type,description,owner.name,requester.name"/>
      <entry key="debugWorkItemArchiveGridColumns">
        <value>
          <List>
            <ColumnConfig dataIndex="id" groupProperty="id" headerKey="Id" property="id" sortProperty="id" sortable="true" stateId="id" width="250"/>
            <ColumnConfig dataIndex="name" groupProperty="name" headerKey="Name" property="name" sortProperty="name" sortable="true" stateId="name" width="150"/>
            <ColumnConfig dataIndex="type" groupProperty="type" headerKey="Type" property="type" sortProperty="type" sortable="true" stateId="type" width="150"/>
            <ColumnConfig dataIndex="description" groupProperty="description" headerKey="Description" property="description" sortProperty="description" sortable="true" stateId="description" width="400"/>
            <ColumnConfig dataIndex="created" dateStyle="short" groupProperty="created" headerKey="Created" property="created" sortProperty="created" sortable="true" stateId="created" width="150"/>
            <ColumnConfig dataIndex="modified" dateStyle="short" groupProperty="modified" headerKey="Modified" property="modified" sortProperty="modified" sortable="true" stateId="modified" width="150"/>
            <ColumnConfig dataIndex="owner" groupProperty="owner.name" headerKey="Owner" property="owner.name" sortProperty="owner.name" sortable="true" stateId="owner" width="150"/>
            <ColumnConfig dataIndex="requester" groupProperty="requester.name" headerKey="Requester" property="requester.name" sortProperty="requester.name" sortable="true" stateId="requester" width="150"/>
          </List>
        </value>
      </entry>
      <entry key="debugWorkItemSearchProperties" value="id,name,type,description,owner.name,requester.name"/>
      <entry key="debugWorkItemGridColumns">
        <value>
          <List>
            <ColumnConfig dataIndex="id" groupProperty="id" headerKey="Id" property="id" sortProperty="id" sortable="true" stateId="id" width="250"/>
            <ColumnConfig dataIndex="name" groupProperty="name" headerKey="Name" property="name" sortProperty="name" sortable="true" stateId="name" width="250"/>
            <ColumnConfig dataIndex="type" groupProperty="type" headerKey="Type" property="type" sortProperty="type" sortable="true" stateId="type" width="150"/>
            <ColumnConfig dataIndex="description" groupProperty="description" headerKey="Description" property="description" sortProperty="description" sortable="true" stateId="description" width="400"/>
            <ColumnConfig dataIndex="created" dateStyle="short" groupProperty="created" headerKey="Created" property="created" sortProperty="created" sortable="true" stateId="created" width="150"/>
            <ColumnConfig dataIndex="modified" dateStyle="short" groupProperty="modified" headerKey="Modified" property="modified" sortProperty="modified" sortable="true" stateId="modified" width="150"/>
            <ColumnConfig dataIndex="owner" groupProperty="owner.name" headerKey="Owner" property="owner.name" sortProperty="owner.name" sortable="true" stateId="owner" width="150"/>
            <ColumnConfig dataIndex="requester" groupProperty="requester.name" headerKey="Requester" property="requester.name" sortProperty="requester.name" sortable="true" stateId="requester" width="150"/>
          </List>
        </value>
      </entry>

Wednesday, October 16, 2019

Finding all children of a Role

When you search on a Role and need all of its children, you can't just call getInheritance() method on the role.  That method returns its parents, either an Organizational role or another Business role.

To get the children there is a method getHierarchy(Resolver r) but not much info on how this works.  Starting with null in the method call, this generates an error.  The resolver is context itself.

String testRole="TestOrg";
Bundle btest=context.getObjectByName(Bundle.class,testRole);
List children=btest.getHierarchy(context);

You will have to pick through the list to see if it's a self reference, and also have to determine what depth you want to read.