Monday, March 30, 2015

OIM API: Entitlements

Tested On: Oracle Identity Manager 11.1.2.2.0
Description: Given here is code that utilize the OIM Java API to grant, revoke, and update entitlements on a user. Entitlement data is stored in the child process form of a resource. In the test driver, a disconnected resource with multiple columns in the child table (entitlement with attributes) is used as an example.

Child Form with "Type" form field as the Entitlement attribute.

Lookup Definition for Entitlement attribute "Type".

User Entitlements View
User Resource Account View Includes:
Parent data in the Details section
Child data in Laptop_UD_LPTYPE table

Here are some useful OIM tables related to entitlements to look at:
ENT_LIST = List of Entitlement
ENT_ASSIGN = Entitlement Instances assigned to users
UD_* =  Resource account data: Look at the child UD table

References: Java API Reference for Oracle Identity Manager 11.1.2.2
http://docs.oracle.com/cd/E27559_01/admin.1112/e27149/appinstance.htm#OMADM4680


package com.blogspot.oraclestack.testdriver;
import com.blogspot.oraclestack.utilities.EntitlementUtilities;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.platform.OIMClient;
import oracle.iam.provisioning.api.EntitlementService;
import oracle.iam.provisioning.api.ProvisioningService;
/**
* Test Driver for using entitlement API.
* @author rayedchan
*/
public class EntitlementTestDriver
{
// Adjust constant variables according to you OIM environment
public static final String OIM_HOSTNAME = "localhost";
public static final String OIM_PORT = "14000"; // For SSL, use 14001; For non-SSL, use 14000
public static final String OIM_PROVIDER_URL = "t3://"+ OIM_HOSTNAME + ":" + OIM_PORT; // For SSL, use t3s protocol; For non-SSL, use t3 protocol
public static final String AUTHWL_PATH = "lib/config/authwl.conf";
public static final String APPSERVER_TYPE = "wls";
public static final String FACTORY_INITIAL_TYPE = "weblogic.jndi.WLInitialContextFactory";
public static final String OIM_ADMIN_USERNAME = "xelsysadm";
public static final String OIM_ADMIN_PASSWORD = "Password1";
public static void main(String[] args) throws Exception
{
OIMClient oimClient = null;
try
{
// Set system properties required for OIMClient
System.setProperty("java.security.auth.login.config", AUTHWL_PATH);
System.setProperty("APPSERVER_TYPE", APPSERVER_TYPE);
// Create an instance of OIMClient with OIM environment information
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL, FACTORY_INITIAL_TYPE);
env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, OIM_PROVIDER_URL);
// Establish an OIM Client
oimClient = new OIMClient(env);
// Login to OIM with System Administrator Credentials
oimClient.login(OIM_ADMIN_USERNAME, OIM_ADMIN_PASSWORD.toCharArray());
// Get OIM Services
UserManager usrMgr = oimClient.getService(UserManager.class);
ProvisioningService provServOps = oimClient.getService(ProvisioningService.class);
EntitlementService entServ = oimClient.getService(EntitlementService.class);
// Instantiate custom entitlement utils
EntitlementUtilities entUtils = new EntitlementUtilities(provServOps, usrMgr, entServ);
// Print all entitlement definitions
//entUtils.printEntitlementDefinition();
String userLogin = "RSYNGAL";
String appInstName = "Laptop";
String entitlementCode = "Lenovo";
String entitlementDisplayName = "Lenovo";
HashMap<String, Object> entitlementAttributes = new HashMap<String,Object>();
entitlementAttributes.put("UD_LPTYPE_STARTDATE", new Date());
entitlementAttributes.put("UD_LPTYPE_HARDDRIVESPACE", "300GB");
// Print user's entitlements
//entUtils.printUserEntitlementInstances(userLogin);
// Grant Entitlement to user
//entUtils.grantEntitlementToUser(userLogin, appInstName, entitlementCode, entitlementAttributes);
// Update Entitlement on user
//entUtils.updateEntitlementInstanceOnUser(userLogin, entitlementDisplayName, entitlementAttributes);
// Revoke an entitlement from user
//entUtils.revokeEntitlementFromUser(userLogin, entitlementDisplayName);
}
finally
{
if( oimClient != null)
{
oimClient.logout();
}
}
}
}
package com.blogspot.oraclestack.utilities;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import oracle.core.ojdl.logging.ODLLevel;
import oracle.core.ojdl.logging.ODLLogger;
import oracle.iam.identity.exception.NoSuchUserException;
import oracle.iam.identity.exception.UserLookupException;
import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.identity.usermgmt.api.UserManagerConstants;
import oracle.iam.identity.usermgmt.vo.User;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;
import oracle.iam.provisioning.api.EntitlementService;
import oracle.iam.provisioning.api.ProvisioningConstants;
import oracle.iam.provisioning.api.ProvisioningService;
import oracle.iam.provisioning.exception.AccountNotFoundException;
import oracle.iam.provisioning.exception.EntitlementAlreadyProvisionedException;
import oracle.iam.provisioning.exception.EntitlementNotFoundException;
import oracle.iam.provisioning.exception.EntitlementNotProvisionedException;
import oracle.iam.provisioning.exception.GenericEntitlementServiceException;
import oracle.iam.provisioning.exception.GenericProvisioningException;
import oracle.iam.provisioning.exception.ImproperAccountStateException;
import oracle.iam.provisioning.exception.UserNotFoundException;
import oracle.iam.provisioning.vo.Account;
import oracle.iam.provisioning.vo.Entitlement;
import oracle.iam.provisioning.vo.EntitlementInstance;
/**
* Contains methods related to entitlements.
* @author rayedchan
*/
public class EntitlementUtilities
{
// Logger
private static final ODLLogger logger = ODLLogger.getODLLogger(EntitlementUtilities.class.getName());
// OIM API Services
private final ProvisioningService provServOps;
private final UserManager userMgrOps;
private final EntitlementService entServ;
public EntitlementUtilities(ProvisioningService provServOps, UserManager userMgrOps, EntitlementService entServ)
{
this.provServOps = provServOps;
this.userMgrOps = userMgrOps;
this.entServ = entServ;
}
/**
* Get all the entitlements from the OIM environment.
* @throws GenericEntitlementServiceException
*/
public void printEntitlementDefinition() throws GenericEntitlementServiceException
{
// Get all Entitlement Definitions
SearchCriteria criteria = new SearchCriteria(ProvisioningConstants.EntitlementSearchAttribute.ENTITLEMENT_CODE.getId(),"*", SearchCriteria.Operator.EQUAL);
HashMap<String,Object> configParams = new HashMap<String,Object>();
List<Entitlement> entitlements = entServ.findEntitlements(criteria, configParams);
logger.log(ODLLevel.NOTIFICATION, "Entitlement List: {0}", new Object[]{entitlements});
}
/**
* Print all user's entitlement instances.
* @param userLogin OIM.USR_LOGIN
* @throws GenericProvisioningException
* @throws UserNotFoundException
*/
public void printUserEntitlementInstances(String userLogin) throws GenericProvisioningException, UserNotFoundException, NoSuchUserException, UserLookupException
{
// Get user's key
String userKey = this.getUserKeyByUserLogin(userLogin);
logger.log(ODLLevel.NOTIFICATION, "User key: {0}", new Object[]{userKey});
// Get user's entitlements
List<EntitlementInstance> userEntitlements = this.provServOps.getEntitlementsForUser(userKey);
// Iterate each entitlement and print to logs
for(EntitlementInstance userEntitlement : userEntitlements )
{
Long accountId = userEntitlement.getAccountKey(); // OIU_KEY
logger.log(ODLLevel.NOTIFICATION, "Entitlement Instance: {0}, Account ID (OIU_KEY): {1}", new Object[]{userEntitlement, accountId});
}
}
/**
* Add an entitlement to a user. Entitlements are stored
* in a resource account in the form of child data.
* @param userLogin OIM User Login (USR_LOGIN)
* @param appInstName Application Instance Display Name
* @param entitlementCode Entitlement Code (ENT_LIST.ENT_CODE)
* @param entitlementAttributes Attributes on entitlement
* @throws NoSuchUserException
* @throws UserLookupException
* @throws UserNotFoundException
* @throws GenericProvisioningException
* @throws GenericEntitlementServiceException
* @throws AccountNotFoundException
* @throws ImproperAccountStateException
* @throws EntitlementNotFoundException
* @throws EntitlementAlreadyProvisionedException
*/
public void grantEntitlementToUser(String userLogin, String appInstName, String entitlementCode, HashMap<String,Object> entitlementAttributes) throws NoSuchUserException, UserLookupException, UserNotFoundException, GenericProvisioningException, GenericEntitlementServiceException, AccountNotFoundException, ImproperAccountStateException, EntitlementNotFoundException, EntitlementAlreadyProvisionedException
{
// Get user's key
String userKey = this.getUserKeyByUserLogin(userLogin);
logger.log(ODLLevel.NOTIFICATION, "User key: {0}", new Object[]{userKey});
// Get user's account filtered by application instance display name
boolean populateAcctData = false;
SearchCriteria appInstCriteria = new SearchCriteria(ProvisioningConstants.AccountSearchAttribute.DISPLAY_NAME.getId(), appInstName, SearchCriteria.Operator.EQUAL);
HashMap<String,Object> acctConfigParams = new HashMap<String,Object>();
List<Account> userAccounts = this.provServOps.getAccountsProvisionedToUser(userKey, appInstCriteria, acctConfigParams, populateAcctData);
logger.log(ODLLevel.NOTIFICATION, "User accounts fetched: {0}", new Object[]{userAccounts});
// Get specific Entitlement Definitions
SearchCriteria entDefCriteria = new SearchCriteria(ProvisioningConstants.EntitlementSearchAttribute.ENTITLEMENT_CODE.getId(), entitlementCode, SearchCriteria.Operator.EQUAL);
HashMap<String,Object> entConfigParams = new HashMap<String,Object>();
List<Entitlement> entitlements = entServ.findEntitlements(entDefCriteria, entConfigParams);
logger.log(ODLLevel.NOTIFICATION, "Entitlement Definition Fetched: {0}", new Object[]{entitlements});
// Ensure an entitlement can be added to a specific resource on a user
if (userAccounts != null && !userAccounts.isEmpty() && entitlements != null && !entitlements.isEmpty())
{
// Get the first resource account
Account userAccount = userAccounts.get(0);
String accountKey = userAccount.getAccountID(); // OIU_KEY
logger.log(ODLLevel.NOTIFICATION, "Add entitlement to account: Account Key = {0}", new Object[]{accountKey});
// Get first entitlement definition
Entitlement entitlement = entitlements.get(0);
logger.log(ODLLevel.NOTIFICATION, "Entitlement Definition: {0}", new Object[]{entitlement});
// Instantiate Entitlement Instance Object
EntitlementInstance grantEntInst = new EntitlementInstance();
// Set required fields to grant entitlement
grantEntInst.setEntitlement(entitlement); // **
grantEntInst.setAccountKey(Long.parseLong(accountKey)); // ** OIU_KEY
// Set attributes on entitlement if any
grantEntInst.setChildFormValues(entitlementAttributes);
// Add entitlement for user
this.provServOps.grantEntitlement(grantEntInst);
}
else
{
logger.log(ODLLevel.NOTIFICATION, "Did not grant entitlement to user.");
}
}
/**
* Removes an entitlement instance form a user based on the display name of the entitlement.
* @param userLogin Login of OIM user (OIM.USR_LOGIN)
* @param entitlementName Entitlement to remove from user (OIM.ENT_LIST.ENT_DISPLAY_NAME)
* @throws UserNotFoundException
* @throws GenericProvisioningException
* @throws AccountNotFoundException
* @throws EntitlementNotProvisionedException
* @throws NoSuchUserException
* @throws UserLookupException
*/
public void revokeEntitlementFromUser(String userLogin, String entitlementName) throws UserNotFoundException, GenericProvisioningException, AccountNotFoundException, EntitlementNotProvisionedException, NoSuchUserException, UserLookupException
{
// Get user's key
String userKey = this.getUserKeyByUserLogin(userLogin);
logger.log(ODLLevel.NOTIFICATION, "User key: {0}", new Object[]{userKey});
// Get specific entitlement from user filtered by Entitlement Display Name (ENT_LIST.ENT_DISPLAY_NAME)
SearchCriteria criteria = new SearchCriteria(ProvisioningConstants.EntitlementSearchAttribute.ENTITLEMENT_DISPLAYNAME.getId(), entitlementName, SearchCriteria.Operator.EQUAL);
HashMap<String,Object> configParams = new HashMap<String,Object>();
List<EntitlementInstance> userEntitlementInsts = this.provServOps.getEntitlementsForUser(userKey, criteria, configParams);
logger.log(ODLLevel.NOTIFICATION, "Entitlement Instances Fetched: {0}", new Object[]{userEntitlementInsts});
// Check if there is at least one entitlement
if(userEntitlementInsts != null && !userEntitlementInsts.isEmpty())
{
// Get first item in user's entitlement list
EntitlementInstance revokeEntInst = userEntitlementInsts.get(0);
// Remove entitlement from user
this.provServOps.revokeEntitlement(revokeEntInst);
logger.log(ODLLevel.NOTIFICATION, "Removed Entitlement Instance: {0}", new Object[]{revokeEntInst});
}
else
{
logger.log(ODLLevel.NOTIFICATION, "No such entitlement instance to remove: {0}", new Object[]{entitlementName});
}
}
/**
* Update an entitlement on a user.
* @param userLogin User Login
* @param entitlementName Display name of entitlement
* @param entitlementAttributes Attributes to update on entitlement
* @throws NoSuchUserException
* @throws UserLookupException
* @throws UserNotFoundException
* @throws GenericProvisioningException
* @throws AccountNotFoundException
* @throws EntitlementNotFoundException
*/
public void updateEntitlementInstanceOnUser(String userLogin, String entitlementName, HashMap<String,Object> entitlementAttributes) throws NoSuchUserException, UserLookupException, UserNotFoundException, GenericProvisioningException, AccountNotFoundException, EntitlementNotFoundException
{
// Get user's key
String userKey = this.getUserKeyByUserLogin(userLogin);
logger.log(ODLLevel.NOTIFICATION, "User key: {0}", new Object[]{userKey});
// Get specific entitlement from user filtered by Entitlement Display Name (ENT_LIST.ENT_DISPLAY_NAME)
SearchCriteria criteria = new SearchCriteria(ProvisioningConstants.EntitlementSearchAttribute.ENTITLEMENT_DISPLAYNAME.getId(), entitlementName, SearchCriteria.Operator.EQUAL);
HashMap<String,Object> configParams = new HashMap<String,Object>();
List<EntitlementInstance> userEntitlementInsts = this.provServOps.getEntitlementsForUser(userKey, criteria, configParams);
logger.log(ODLLevel.NOTIFICATION, "Entitlement Instances Fetched: {0}", new Object[]{userEntitlementInsts});
// Check if there is at least one entitlement
if(userEntitlementInsts != null && !userEntitlementInsts.isEmpty())
{
// Get first item in user's entitlement list
EntitlementInstance updateEntInst = userEntitlementInsts.get(0);
// Stage updates for entitlement
updateEntInst.setChildFormValues(entitlementAttributes);
// Update entitlement instance on user
this.provServOps.updateEntitlement(updateEntInst);
logger.log(ODLLevel.NOTIFICATION, "Update Entitlement Instance: {0}", new Object[]{updateEntInst});
}
else
{
logger.log(ODLLevel.NOTIFICATION, "No such entitlement instance to update: {0}", new Object[]{entitlementName});
}
}
/**
* Get the OIM User's USR_KEY
* @param userLogin OIM.User Login (USR_LOGIN)
* @return value of USR_KEY
* @throws NoSuchUserException
* @throws UserLookupException
*/
private String getUserKeyByUserLogin(String userLogin) throws NoSuchUserException, UserLookupException
{
boolean userLoginUsed = true;
HashSet<String> attrsToFetch = new HashSet<String>();
attrsToFetch.add(UserManagerConstants.AttributeName.USER_KEY.getId());
attrsToFetch.add(UserManagerConstants.AttributeName.USER_LOGIN.getId());
User user = userMgrOps.getDetails(userLogin, attrsToFetch, userLoginUsed);
logger.log(ODLLevel.NOTIFICATION, "User Details: {0}", new Object[]{user});
return user.getEntityId();
}
}

4 comments:

  1. is it possible to CREATE an entitlement using the API? If so, what's the lookup key value?

    ReplyDelete
    Replies
    1. There are methods in "oracle.iam.provisioning.api.EntitlementService" to create entitlements. I think there might be a bug with the addEntitlement() method. I notice that there is a lookup definition (LKU_KEY) validation check for the field that is set by setLookupValueKey(). Below is sample code I am using to create an entitlement.

      EntitlementService entServ = oimClient.getService(EntitlementService.class);

      Entitlement ent = new Entitlement();
      ent.setDisplayName("GridGuard"); // ENT_DISPLAY_NAME
      ent.setEntitlementCode("21~GridGuard"); // ENT_CODE
      ent.setEntitlementValue("BadgeAccess~GridGuard");// ENT_VALUE
      ent.setItResourceKey(21L); // SVR_KEY
      ent.setObjectKey(21L); // OBJ_KEY
      ent.setFormKey(23L); // SDK_KEY
      ent.setFormFieldKey(74L); // SDC_KEY *Use Key lookup attribute
      ent.setLookupValueKey(1570L); // LKU_KEY *Need setter for LKU

      entServ.addEntitlement(ent); // Call to create entitlement


      When using the add entitlement API, a new record is inserted into the ENT_LIST table. The ENT_LIST.LKV_KEY in the new record would be incorrect though. Also, there is no new entry added to the lookup (LKV) .

      I think the intention of the API is to have the user provide the Lookup Definition Key (LKU_KEY) which there is no setter method for and have OIM generate the LKV_KEY.

      Delete
    2. You can use tcLookupOperationsIntf to add entries to your entitlement lookups and then run the "Entitlement List" and "Catalog Synchronization Job" scheduled jobs.

      Delete
  2. i need a code which can remove entitlements in bulk

    ReplyDelete