Tuesday 30 May 2017

Decrypt user's password in OIM 11gR2 PS3

In OIM 11gR2 PS1 we were able to get the user's password in clear text using below java code

tcDataProvider dbProvider = new tcDataBaseClient();
String query = "select USR_LOGIN,USR_PASSWORD from USR where USR_LOGIN=UPPER('"+uid+"')";
tcDataSet dataSet = new tcDataSet();
dataSet.setQuery(dbProvider, query);
dataSet.executeQuery();
System.out.println("Password:: "+dataSet.getString("USR_PASSWORD"));

Starting from OIM 11gR2 PS2 this process no longer applicable, even if you run the above code in PS2 or PS3 version, this will give you ********* instead of clear text password.


I have found a way to get the user's password in clear text in OIM 11gR2 PS3 version. Execute the below procedure to get the same

1. take an ITResource in OIM and update password in password field.

     In my case I choose ITResource "Directory Server" and update "Admin Password" field.
    

2. From SQL Developer run the below query to get the database field of that ITResource

       select spd.SPD_FIELD_NAME, svp.SVP_FIELD_VALUE from spd, svp where
        spd.spd_key = svp.spd_key and
        spd.svd_key = (select svd_key from svr where svr_name = 'Directory Server') and
        svp.svr_key = (select svr_key from svr where svr_name = 'Directory Server')

        Output
       



3. Find out the password field that you updated from sysadmin console. You can see the password is encrypted.

4. Now run below query to get the encrypted password of OIM user

     select USR_PASSWORD from USR where USR_LOGIN='XELSYSADM';

     Output: 3412:ElLNJh2hLSqX+OdI9CxS8Q==

5. Now copy the password of XELSYSADM and update the "Admin Password" field in ITResource from database table.

6. Now run the below method to get the password of XELSYSADM in clear text


public void getITResourceParameter() throws Exception {


final String methodName = "::getITResourceParameter::";


Map phAttributeList = new HashMap();
phAttributeList.put("IT Resources.Name", "Directory Server");


HashMap paramMap = new HashMap();


tcITResourceInstanceOperationsIntf ITResourceAPI = (tcITResourceInstanceOperationsIntf)oimClient.getService(tcITResourceInstanceOperationsIntf.class);

tcResultSet itresSet = ITResourceAPI.findITResourceInstances(phAttributeList);
itresSet.goToRow(0);

String ITResourceKey = itresSet.getStringValue("IT Resources.Key");
System.out.println("ITResourceKey::"+ITResourceKey);

tcResultSet paramValuesRS = ITResourceAPI.getITResourceInstanceParameters(Long.parseLong(ITResourceKey));

for(int j=0;j<paramValuesRS.getTotalRowCount();j++){

paramValuesRS.goToRow(j);
paramMap.put(paramValuesRS.getStringValue("IT Resources Type Parameter.Name"), paramValuesRS.getStringValue("IT Resources Type Parameter Value.Value"));

}


String adminPassword = (String) paramMap.get("Admin Password");


System.out.println("adminPassword ::"+adminPassword);

}


You can use any user instead of XELSYSADM to get their OIM password in clear text.

Explanation    
1. Even if in OIM PS3 version, they block the dataset API to get the password in clear text from USR table, but ITResource API still capable of getting ITResource password in clear text from database.

2. OIM still use single encryption mechanism to encrypt all of its password.

Now if you can replace the encrypted password from USR table to SVP table of ITResource, then you can use the ITResource API to get the password.

** Oracle still need to work on this to enhance the security of user's password.

Monday 29 May 2017

Get Parrent and Child request details of OIM

The below code snippet will give u the details of the Parent and Child request details of a given request id.



public void getRequestDetails(String reqId) throws Exception{

OIMClient oimClientObj = getRequesterConnection("xelsysadm");
RequestService reqAPI = (RequestService)oimClientObj.getService(RequestService.class);

/**
* Get parent request details
*/

Request req = reqAPI.getBasicRequestData("34002");
Request pReq = req.getParentRequest();
System.out.println("Parent Request: "+pReq.getRequestID());

/**
* get the child request details
*/
pReq = reqAPI.getBasicRequestData(pReq.getRequestID());
List<Request> cReqs = pReq.getChildRequests();

System.out.println("Other Chlied request for entitlements");


for (int i=0; i<cReqs.size(); i++){

System.out.println(cReqs.get(i).getRequestID()+" : "+cReqs.get(i).getRequestModelName());

}

}

Output

Parrent Request: 34001
Other Chlied request for entitlements
34002 : Provision ApplicationInstance
34003 : Provision Entitlement
34004 : Assign Roles



Approving OIM request programatically using BEPL APIs

Using BEPL APIs one can programmatically perform actions on a OIM request. Below is an example of the same.

1. Create a project in eclipse.
2. Copy the below jars from servers

            [WL_HOME]/server/lib/weblogic.jar
      [SOA_HOME]/soa/modules/oracle.soa.fabric_11.1.1/bpm-infra.jar
      [SOA_HOME]/soa/modules/oracle.soa.fabric_11.1.1/fabric-runtime.jar
      [SOA_HOME]/soa/modules/oracle.soa.workflow_11.1.1/bpm-services.jar
      [WL_HOME]/server/lib/wlfullclient.jar

      [OIM_HOME]/server/ext/spml/wsclient_extended.jar

3. Set the above jars in your project classpath
4. Use the below code in your project.


import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;


import com.bea.security.providers.xacml.entitlement.parser.Predicate;
import oracle.bpel.services.workflow.WorkflowException;
import oracle.bpel.services.workflow.client.config.RemoteClientType;
import oracle.bpel.services.workflow.client.config.RemoteClientType.Password;
import oracle.bpel.services.workflow.client.config.ServerType;
import oracle.bpel.services.workflow.client.config.WorkflowServicesClientConfigurationType;
import oracle.bpel.services.workflow.client.IWorkflowServiceClient;
import oracle.bpel.services.workflow.client.WorkflowServiceClientFactory;
import oracle.bpel.services.workflow.query.ITaskQueryService;
import oracle.bpel.services.workflow.query.ITaskQueryService.AssignmentFilter;
import oracle.bpel.services.workflow.repos.TableConstants;
import oracle.bpel.services.workflow.task.ITaskService;
import oracle.bpel.services.workflow.task.model.Task;
import oracle.bpel.services.workflow.verification.IWorkflowContext;



 

public class ApproveOIMRequest {

public void approveRequest(String reqId) throws Exception{
Logger logger = Logger.getLogger(ApproveOIMRequest.class.getName());

/**
* Adding SOA server and its properties into the WorkflowServicesClientConfigurationType
*/

WorkflowServicesClientConfigurationType wssst = new WorkflowServicesClientConfigurationType();
List<ServerType> servers = wssst.getServer();
ServerType server = new ServerType();
server.setDefault(true);
server.setName("soa");

servers.add(server);


/**
* Creating remote client with all the SOA server connection parameters including login user as xelsysadm.
*/

RemoteClientType rct = new RemoteClientType();
rct.setServerURL("t3://ess.com:8001");
rct.setUserName("xelsysadm");
Password weblogicPWD = new Password();
weblogicPWD.setValue("Welcome1");
rct.setPassword(weblogicPWD);
rct.setInitialContextFactory("weblogic.jndi.WLInitialContextFactory");
rct.setParticipateInClientTransaction(false);

server.setRemoteClient(rct);

/**
* Creating remote enterprise java bean interface to invoke workflow
* service located remotely from the client.
*
* After creating IWorkflowServiceClient object, get the Query Service.
*/

IWorkflowServiceClient wfsc = WorkflowServiceClientFactory.getWorkflowServiceClient(WorkflowServiceClientFactory.REMOTE_CLIENT,wssst,logger);

ITaskQueryService qService = wfsc.getTaskQueryService();

/**
* Authenticating using xelsysadm
*/

String xelsysadmPassword = "Welcome1";
IWorkflowContext wctx = qService.authenticate("xelsysadm", xelsysadmPassword.toCharArray(), null);

/**
* List the column name to get the value from query service.
* the columns are all from WFTASK table in SOAINFRA schema.
*/

List queryColumns = new ArrayList();
queryColumns.add("TASKID");
queryColumns.add("TASKNUMBER");
queryColumns.add("TITLE");
queryColumns.add("OUTCOME");
queryColumns.add("IDENTIFICATIONKEY");


/**
* Assigning filter for selecting assigned tasks
*/

AssignmentFilter assignmentFilter = AssignmentFilter.ALL;
/**
* List all the assignd tasks for logged in user.
*/

List tasks = qService.queryTasks(wctx, queryColumns, null, assignmentFilter, null, null, null, 0, 0);


/**
* get the object of task service in order to perform actions on tasks.
*/
ITaskService taskService = wfsc.getTaskService();

System.out.println("tasks.size() :"+tasks.size());
/**
* Iterate the list of tasks and check for the request id and status.
* if the status is not APPROVED and request id gets matched, then
* perform update task like APPROVE the task
*/

for (int i=0; i<tasks.size(); i++){

//System.out.println("Task found for request id: "+reqId);
Task task = (Task) tasks.get(i);
int taskNumber = task.getSystemAttributes().getTaskNumber();
String taskTitle = task.getTitle();
String taskId = task.getSystemAttributes().getTaskId();
String taskOutcome = task.getSystemAttributes().getOutcome();
String identificationKey = task.getIdentificationKey();

//System.out.println(taskNumber+" "+taskTitle+" "+taskOutcome+" "+identificationKey);

if (identificationKey.equalsIgnoreCase(reqId) && taskOutcome == null){
System.out.println(taskNumber+" "+""+" "+taskOutcome+" "+identificationKey);
taskOutcome = "APPROVE";
taskService.updateTaskOutcome(wctx, taskId, taskOutcome);

}

}

System.out.println("Done");
}


public static void main(String[] args) {

ApproveOIMRequest a = new ApproveOIMRequest();

try {
a.approveRequest("32001"); //Request Id is the input parameter.
} catch (Exception e) {

e.printStackTrace();

}

}

}


Wednesday 24 May 2017

Weblogic bsu - java.lang.OutOfMemoryError

sometime you can find the java heap space issue while applying weblogic patches using bsu. The error looks like below


Exception in thread "main" Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
        at java.util.HashMap.createEntry(HashMap.java:897)
        at java.util.HashMap.addEntry(HashMap.java:884)
        at java.util.HashMap.put(HashMap.java:505)
        at com.bea.cie.common.dao.xbean.XBeanDataHandler.loadPropertyMap(XBeanDataHandler.java:778)
        at com.bea.cie.common.dao.xbean.XBeanDataHandler.<init>(XBeanDataHandler.java:99)
        at com.bea.cie.common.dao.xbean.XBeanDataHandler.createDataHandler(XBeanDataHandler.java:559)
        at com.bea.cie.common.dao.xbean.XBeanDataHandler.getComplexValue(XBeanDataHandler.java:455)
        at com.bea.plateng.patch.dao.cat.PatchCatalogHelper.getPatchDependencies(PatchCatalogHelper.java:442)
        at com.bea.plateng.patch.dao.cat.PatchCatalogHelper.getPatchDependencies(PatchCatalogHelper.java:464)
        at com.bea.plateng.patch.dao.cat.PatchCatalog.getPatchDependencies(PatchCatalog.java:56)
        at com.bea.plateng.patch.dao.cat.PatchCatalogHelper.getInvalidatedPatchMap(PatchCatalogHelper.java:1621)
        at com.bea.plateng.patch.PatchSystem.updatePatchCatalog(PatchSystem.java:436)
        at com.bea.plateng.patch.PatchSystem.refresh(PatchSystem.java:130)
        at com.bea.plateng.patch.PatchSystem.<init>(PatchSystem.java:114)
        at com.bea.plateng.patch.PatchSystem.<clinit>(PatchSystem.java:41)
        at com.bea.plateng.patch.Patch.main(Patch.java:279)
java.lang.NoClassDefFoundError: Could not initialize class com.bea.plateng.patch.PatchSystem
        at com.bea.plateng.patch.PatchClientHelper.getAllPatchDetails(PatchClientHelper.java:74)
        at com.bea.plateng.patch.PatchInstallationHelper.cleanupPatchSets(PatchInstallationHelper.java:130)
        at com.bea.plateng.patch.PatchTarget.<init>(PatchTarget.java:272)
        at com.bea.plateng.patch.PatchTargetFactory.create(PatchTargetFactory.java:30)
        at com.bea.plateng.patch.ProductAliasTarget.constructPatchTargetList(ProductAliasTarget.java:88)
        at com.bea.plateng.patch.ProductAliasTarget.<init>(ProductAliasTarget.java:46)
        at com.bea.plateng.patch.ProductAliasTargetHelper.getProdAliasTargetList(ProductAliasTargetHelper.java:55)
        at com.bea.plateng.patch.ProductAliasTargetHelper.getAllHomeToProdAliasesTargetMap(ProductAliasTargetHelper.java:32)
        at com.bea.plateng.patch.ProductAliasTargetHelper.checkProfilesInProductAliases(ProductAliasTargetHelper.java:133)
        at com.bea.plateng.patch.Patch$1.run(Patch.java:376)
        at java.lang.Thread.run(Thread.java:745)





Solution


1. open the bsu.sh (MIDDLEWARE_HOME/utils/bsu/bsu.sh) file edit mode
2. change the memory args value as below


From


MEM_ARGS="-Xms256m -Xmx512m"


To


MEM_ARGS="-Xms512m -Xmx1024m"


3. Save the file and run bsu again.

Tuesday 23 May 2017

Calling Unix command from Java

Here is the code sample for calling Unix command from java. The below sample can only run the Unix command in the same system.


public class LinuxInJava {
    public static void main(String args[]) {
        String s;
        Process p;
        try {
            p = Runtime.getRuntime().exec("ls -aF");
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            while ((s = br.readLine()) != null){
                System.out.println("line: " + s);
   
    }
            p.waitFor();
            System.out.println ("exit: " + p.exitValue());
            p.destroy();
        } catch (Exception e) {}
    }
}




Friday 19 May 2017

OIM 11gR2 PS3 Workflow policy page showing blank

In OIM 11gR2 PS3, one should not update the default applications (Self-Service and Sysadmin) from Weblogic deployments.



Sometime during implementation of OIM UI Customizations, peoples are updating the oracle.iam.ui.custom. In PS3 you can find that while updating oracle.iam.ui.custom, automatically below depended applications got updated.



If by mistake oracle.iam.console.identity.self-service.ear and oracle.iam.console.identity.sysadmin.ear got updated then you may find the workflow policy in sysadmin console showing blank. See the below image where opening the Workflows -> Approvals showing a white page.






Reason:
In OIM PS3, if some how oracle.iam.console.identity.self-service.ear and oracle.iam.console.identity.sysadmin.ear got updated then the OPSS policy gets overwritten.


Solution:
To resolve this issue, we need to Re-Seed the policy again from self service and sysadmin.
There are 3 policy files you need to re-seed.


1. Copy 'jazn-data.xml' (from OIM.ear) to a different directory.
2. Copy 'jazn-data.xml' (found in oracle.iam.console.identity.self-service.ear) to a different directory.
3. Copy 'jazn-data-sysadmin.xml' (found in oracle.iam.console.identity.self-service.ear) to a different directory.


4. Go to [DOMAIN_HOME]/config/fmwconfig/ take a backup of the file 'jps-config-jse.xml' in the same folder


cp jps-config-jse.xml jps-config-jse_backup.xml


5. Open the backup file 'jps-config-jse_backup.xml' and add the below 2 jps contexts just before the "</jpsContexts>" tag.


<jpsContext name="mydst">
<serviceInstanceRef ref="policystore.db"/>
</jpsContext>

<jpsContext name="mysrc">
<serviceInstanceRef ref="mysource.policystore.xml"/>
</jpsContext>



6. Open the 'jps-config-jse_backup.xml' file and add the below 'serviceInstance' just before the "</serviceInstances>" tag.


<serviceInstance name="mysource.policystore.xml"
provider="policystore.xml.provider" location="<FILE PATH>">
<description>My source</description>
</serviceInstance>



Give an absolute path of jazn-dataXXXX.xml in <FILE PATH> as per the step 1. You need to change the <FILE PATH> 3 times to seed 3 different policies.


7. Goto the location "[MWHOME]/oracle_common/common/bin/" and execute "sh wlst.sh" script


8. Execute the below command to import policies from Jazn-dataxxx.xml to the OPSS store.


Syntax
migrateSecurityStore(type='appPolicies', configFile='/opt/app/oracle/Middleware/user_projects/domains/<oim_domain>/config/fmwconfig/jps-config-jse_backup.xml',
src='mysrc', dst='mydst', srcApp='<Follow point B mentioned above>', overWrite='false')



Example
migrateSecurityStore(type='appPolicies', configFile='[DOMAIN_HOME]/config/fmwconfig/jps-config-jse_backup.xml',src='mysrc', dst='mydst', srcApp='OIM', overWrite='false')


Note: srcApp value will be changed according to the policy data as below:
'jazn-data.xml' (from OIM.ear)  - srcApp is OIM
'jazn-data.xml' (found in oracle.iam.console.identity.self-service.ear) - srcApp is OracleIdentityManager
'jazn-data-sysadmin.xml' (found in oracle.iam.console.identity.self-service.ear) - srcApp is OracleIdentityManager




9. Exit the WLST session using exit() command.
10. Repeat from the Step 6 for the other 2 policies.
11. Once done take a restart of OIM servers.


Example for the WLS command for other 2 policies:


migrateSecurityStore(type='appPolicies', configFile='[DOMAIN_HOME]/config/fmwconfig/jps-config-jse_backup.xml',src='mysrc', dst='mydst', srcApp='OracleIdentityManager', overWrite='false')

Thursday 18 May 2017

Changing SOA Admin user for OIM

SOA Admin user is an user which is required for OIM to communicate with SOA. By default OIM use weblogic as SOA Admin user, but you can change this user as per your requirement. Changes need to be done in several location. Below is a python script cn be used to change SOA Admin user.


Run this python script for $OIM_HOME/common/bin/wlst.sh


wlst> ./tmp/changeSOAAdmin.py $WL_USER $WL_PASSWORD $OIM1_URL $ADMIN_URL_T3 $WEBLOGIC_DOMAIN_NAME


------------------------------------changeSOAAdmin.py--------------------------------------
#!/usr/bin/python
import sys
wl_user=sys.argv[1]
wl_password=sys.argv[2]
oim1_url=sys.argv[3]
admin_url=sys.argv[4]
domain_name=sys.argv[5]


connect(wl_user,wl_password, oim1_url)
custom()
cd('/oracle.iam/oracle.iam:name=SOAConfig,type=XMLConfig.SOAConfig,XMLConfig=Config,Application=oim,ApplicationVersion=11.1.2.0.0')
set('Username', wl_user)
shutdown(force='true')
disconnect()

connect(wl_user,wl_password,admin_url)
deleteCred(map="oim", key="SOAAdminPassword");
createCred(map="oim", key="SOAAdminPassword", user=wl_user,password=wl_password);

edit()
startEdit()

cd('/ForeignJNDIProviders/ForeignJNDIProvider-SOA')
set('User',wl_user)
set('Password',wl_password)

save()
activate()
exit()

-------------------------------------------------------------------------------------------------------------------
The above script is doing 3 changes


1. Changing the SOA Admin Username in XMLConfig.SOAConfig
2. Recreating the SOAAdminPassword CSF
3. Updating the new user details in ForeignJNDIProvider-SOA

WLST to grant Jps Permission to OIM domain directories

You can grant Jps Permission to directories using following WLST command.


Syntax


grantPermission(codeBaseURL=[]DIRECTORY_URL', permClass=[PERMISSION_CLASS]', permTarget='[PERMISSION_TARGET]')


Example


[OIM_HOME]/common/bin/wlst.sh
connect(wl_user,wl_password, admin_url)


grantPermission(codeBaseURL='file:${XL.HomeDir}/apps/-', permClass='oracle.security.jps.JpsPermission', permTarget='IdentityAssertion')


grantPermission(codeBaseURL='file:${domain.home}/servers/${weblogic.Name}/tmp/_WL_user/-', permClass='oracle.security.jps.JpsPermission', permTarget='IdentityAssertion')

WLST command to deploy SOA composites for OIM

You can deploy SOA composites for OIM using WLST command, without login into EM console


Syntax


sca_deployComposite(serverURL, sarLocation, [overwrite], [user], [password],
[forceDefault], [configplan], [partition])



Example


$SOA_HOME/common/bin/wlst.sh
sca_deployComposite('http://localhost:8001','/workflows/sca_ManagerApproval_rev1.2.jar',true,'weblogic','abcd1234',true,'/workflows/ManagerApproval_cfgplan.xml');

DuplicateRefException in Disconnected Application Instance after upgrading OIM to PS3

After upgrading OIM to PS3 from previous version (like PS1 or R2 base version), we observed that the disconnected application instance's form doesn't work properly. Issue may happen with create form  and modify form.


If the issue is in create form, then you will not be able to raise request of it. Submit of request will throw exceptions.
If issue is with modify form then request can be created but approvers/fulfillment users will not be able to see the form data from request.


we noticed that the issue occurred on those disconnected applications where there are some hidden field in request dataset.


The error looks like below.


oracle.mds.exception.MDSRuntimeException: MDS-00010: DuplicateRefException. In document /oracle/iam/ui/runtime/form/view/pages/[APP_NAME]CreateForm.jsff there are multiple elements with the same ID _xg_0


oracle.mds.exception.MDSRuntimeException: MDS-00010: DuplicateRefException. In document /oracle/iam/ui/runtime/form/view/pages/[APP_NAME]ModifyForm.jsff there are multiple elements with the same ID _xg_0


Solution


1. Export the whole MDS of identity self service.


$OIM_HOME/common/bin/wlst.sh
connect('${WL_USER}','${WL_PASSWORD}','${ADMIN_URL_T3}');
exportMetadata(application='oracle.iam.console.identity.self-service.ear', server='${OIM_INSTANCE_NAME}', toLocation='/tmp/mds');


2. Go to the location where the MDS is exported /tmp/mds.
3. Now move to /oracle/iam/ui/runtime/form/view/pages/mdssys/cust/site/site/
4. Here you can see the create form and modify form's jsff files for all the application instances.
5. Open the create or modify jsff file in editor mode. You can see there are 2 <af: panelFormLayout> tags, which are under same <mds: insert> tag




6. Edit this form and put each <af: panelFormLayout>  under a separate <mds: insert> tag, like below.




7. Save the form do the same for all other application forms.


You can also use the below Unix command to perform the bulk update on all the forms.


Create Forms


find /tmp/mds/oracle/iam/ui/runtime/form/view/pages/mdssys/cust/site/site/ -name *CreateForm.jsff.xml -exec \
 sed  --in-place -e '/<\/af:panelFormLayout>/,/<panelFormLayout id="_xg_0"/s/<\/af:panelFormLayout>/<\/af:panelFormLayout>\n<\/mds:insert>\n<mds:insert parent="sdh1" position="last">/' {} \;



Modify Forms


find /tmp/mds/oracle/iam/ui/runtime/form/view/pages/mdssys/cust/site/site/ -name *ModifyForm.jsff.xml -exec \
 sed  --in-place -e '/<\/af:panelFormLayout>/,/<panelFormLayout id="_xg_0"/s/<\/af:panelFormLayout>/<\/af:panelFormLayout>\n<\/mds:insert>\n<mds:insert parent="sdh1" position="last">/' {} \;



Note: Change the id="_xg_0" or "_xg_1" according to your error message.


8. Zip the entire MDS.


cd /tmp/mds
zip -r ../mds.zip . >/dev/null



9. Upload the mds zip to OIM MDS repository


$OIM_HOME/common/bin/wlst.sh
connect('${WL_USER}','${WL_PASSWORD}','${ADMIN_URL_T3}');
importMetadata(application='oracle.iam.console.identity.self-service.ear', server='$OIM_INSTANCE_NAME', fromLocation='/tmp/mds.zip');



10. Restart the OIM servers.
11. Check all the Disconnected Application Instance form from OIM identity console.


Tuesday 16 May 2017

Apply weblogic patches in bulk using unix script.

If you apply more than one weblogic patches, then you have to either run the bsu.sh (located at $ORACLE_HOME/utils/bsu) in GUI mode or 1 by 1 in console mode. You can use the below script to install all the patches in one run.


follow the below steps:


1. Create a directory named /tmp/WLS_Patch
2. Put all the patches zip in the above directory
3. Create a sh file name run.sh and copy the below text into the file and save it.


echo "*********************"
echo Upgrade WLS
echo "*********************"
mkdir $ORACLE_HOME/utils/bsu/cache_dir
cd $ORACLE_HOME/utils/bsu/cache_dir
yes | find /tmp/WLS_Patch -name \*.zip -exec unzip  {} \;

cd ..
for i in 56MM CM69 FSG4 IMWL VRGR XA6W YVDZ ZARV
do

 ./bsu.sh -prod_dir=$WL_HOME -patchlist=$i -verbose -install | tee $i.out
 grep "Result: Success" $i.out
 if [ $? -ne 0 ]
 then
  echo "Unexpected issue applying patch $i. Check file $i.out"
  exit 1
 fi
done

echo "*********************"
echo WLS Upgraded
echo "*********************"



4. Replace the ORACLE_HOME and WL_HOME with the appropriate value as per your environment.
5. Add the patch alias name in the for loop list (highlighted in bold)
6. Save the file and run the script.
7. if any error occurred check the i.out file generated where the script is located.







Upload jar for ScduleTask or JavaTask in OIM 11gR2 PS3 using API

You can upload the ScheduleTask and JavaTask jar in OIM from your custom java applications. Here is the example of the same. similarly you also download, update and delete jar files from OIM database.




public void uploadJar() throws PlatformServiceException{
      
  PlatformUtilsService platformUtilsService = (PlatformUtilsService) oimClient.getService(PlatformUtilsService.class);
        JarElement jarElement = new JarElement();
        jarElement.setName("abcd.jar");
        jarElement.setPath("/tmp/abcd.jar");
        jarElement.setType("ScheduleTask");
       
        Set jarElementSet = new HashSet();
        jarElementSet.add(jarElement);
       
        platformUtilsService.uploadJars(jarElementSet );
        System.out.println("Finish uploading jar" );
    }

Thursday 11 May 2017

Update OIM 11gR2 PS3 Schedule job parameter programatically using API.

We can update OIM schedule job parameter programmatically using available APIs. Here is the code sample.




 public void updateSchedulerParam(String jobName, String paramName, String newValue){
 
  SchedulerService schdulerService = (SchedulerService)oimClientObj.getService(SchedulerService.class);
 
  try {
  
   JobDetails jobDetails = schdulerService.getJobDetail(jobName);
   HashMap<String, JobParameter> schParam = jobDetails.getParams();
  
   for (Entry<String, JobParameter> entry : schParam.entrySet()) {
      
    String key = entry.getKey();
       JobParameter jobParam = entry.getValue();
       Serializable value = jobParam.getValue();
             
       System.out.println("Old key value pair: "+key+" = "+ value);
      
       if (key.equalsIgnoreCase(paramName)){
        value = newValue;
        System.out.println(value.toString());
        jobParam.setValue(value);
      
        System.out.println(jobParam.getValue());
        schParam.put(key, jobParam);
        break;
       }
   }
   jobDetails.setParams(schParam);
   schdulerService.updateJob(jobDetails);
   System.out.println("Updated successfully");
  
 } catch (Exception e) {
    e.printStackTrace();
 }
 }

Update OIM 11gR2 PS3 catalog attributes using API

In OIM, catalog default attributes can be easily updated by Catalog Sync schedule job. But if you add any custom attributes in the catalog, those field are very difficult to update using the Catalog Sync job.


You can use the below code snippet to update catalog default and custom attributes. While using this code in real implementation, use a CSV file with all the data and attaché the code in a schedule task.


 /**
  * This method update catalog form of specified entity
  * @param DBColumnName Catalog form field name
  * @param DBColumnValue Catalog form field value
  * @throws SchedulerException
  */

 private void updateCatalogDetailsValue(String DBColumnName, Object DBColumnValue) throws SchedulerException{
 
  oracle.iam.platform.utils.vo.OIMType oimtype = null;
 
  CatalogService catalogAPI = (CatalogService)oimClientObj.getService(CatalogService.class);
 
  System.out.println("ItemName::"+ItemName);
  System.out.println("ItemType::"+ItemType);

  try {
 
   //Set catalog entity type
   if(ItemType.equals("Entitlement")){
    oimtype = oracle.iam.platform.utils.vo.OIMType.Entitlement;
   }
   if(ItemType.equals("Role")){
    oimtype = oracle.iam.platform.utils.vo.OIMType.Role;
   }
   if(ItemType.equals("ApplicationInstance")){
    oimtype = oracle.iam.platform.utils.vo.OIMType.ApplicationInstance;
   }
  
   //Get catalog form of a specified entity
   Catalog catalog = catalogAPI.getCatalogItemDetails(null, ItemName, oimtype, null);
  
   System.out.println("Found Catalog item Display Name: "+catalog.getEntityDisplayName());
  
   //Set default catalog fields
   if(DBColumnName.equalsIgnoreCase("Catagory")){
   
    catalog.setCategoryName(String.valueOf(DBColumnValue));
   }else if(DBColumnName.equalsIgnoreCase("Audit Objective")){
   
    catalog.setAuditObjectives(String.valueOf(DBColumnValue));
   }else if(DBColumnName.equalsIgnoreCase("User Defined Tags")){
   
    catalog.setUserDefinedTags(String.valueOf(DBColumnValue));
   }else if(DBColumnName.equalsIgnoreCase("Certifiable")){
   
    catalog.setCertifiable(Boolean.valueOf(DBColumnValue.toString()));
   }else if(DBColumnName.equalsIgnoreCase("Approver User")){
   
    catalog.setApproverUserLogin(String.valueOf(DBColumnValue));
    catalog.setApproverUser(getUserKey(String.valueOf(DBColumnValue)));
   }else if(DBColumnName.equalsIgnoreCase("Approver Role")){
   
    catalog.setApproverRoleDisplayName(String.valueOf(DBColumnValue));
    catalog.setApproverRole(getRoleKey(String.valueOf(DBColumnValue)));
   }else if(DBColumnName.equalsIgnoreCase("Certifier User")){
   
    catalog.setCertifierUser(getUserKey(String.valueOf(DBColumnValue)));
    catalog.setCertifierUserLogin(String.valueOf(DBColumnValue));
   
   }else if(DBColumnName.equalsIgnoreCase("Certifier Role")){
   
    catalog.setCertifierRoleDisplayName(String.valueOf(DBColumnValue));
    catalog.setCertfierRole(getRoleKey(String.valueOf(DBColumnValue)));
   }else if(DBColumnName.equalsIgnoreCase("Fulfilment User")){
   
    catalog.setFulFillMentUser(getUserKey(String.valueOf(DBColumnValue)));
    catalog.setFulFillMentUserLogin(String.valueOf(DBColumnValue));
   }else if(DBColumnName.equalsIgnoreCase("Fulfilment Role")){
   
    catalog.setFulFillmentRoleDisplayName(String.valueOf(DBColumnValue));
    catalog.setFulFillMentRole(getRoleKey(String.valueOf(DBColumnValue)));
   }else if(DBColumnName.equalsIgnoreCase("Risk Level")){
   
    if(String.valueOf(DBColumnValue)== "High Risk")
     catalog.setItemRisk(7);
    else if(String.valueOf(DBColumnValue)== "Medium Risk")
     catalog.setItemRisk(5);
    else if(String.valueOf(DBColumnValue)== "Low Risk")
     catalog.setItemRisk(3);
    else
     System.out.println("Wrong Risk Value");
   }else{
   
    //Updating custom field
    List<MetaData> catalogMetaDataList = catalog.getMetadata();
    MetaData catalogMetaData = null;
    for(int j=0; j< catalogMetaDataList.size(); j++){
    
     catalogMetaData = catalogMetaDataList.get(j);
     MetaDataDefinition catalogMetaDataDef = catalogMetaData.getMetaDataDefinition();
    
     System.out.println(j+":::catalogMetaDataDef.getDisplayName():::::"+catalogMetaDataDef.getDisplayName());
    
     if(catalogMetaDataDef.getDisplayName().equalsIgnoreCase(DBColumnName)){
     
      catalogMetaData.setValue(String.valueOf(DBColumnValue));
      catalogMetaDataList.set(j, catalogMetaData);
      break;
     }
    }
   
    //Set catalog metadata
    catalog.setMetadata(catalogMetaDataList);
   
   }
   //Update catalog
   catalogAPI.updateCatalogItems(catalog);
  
  } catch (CatalogException e) {
  
   e.printStackTrace();
  
   if ((e.toString().indexOf("No Detail found for specified catalog item") > 0)){
    System.out.println("Ignore msg");
   
   }else{
   
    throw new Exception("ERROR: Catalog Exception, see server log and server log for more details ");
   }
  
  }
 }

Close OIM 11gR2 PS3 Identity Certification in bulk using API

closing identity certification from OIM identity console is possible by an administrator, but feasible for large number. Here is a code example of doing the same for bulk.

You can get the list of certification which are not completed yet from the OIM database, using below query

select CERT_ID, USER_ID from CERTD_USER where CERT_ID in (select ID from CERT_SERTS where CERT_STATE in ('17','2','1','11','12',13','14','15','16'))

the CERT_SATE numbers are defined as below inside OIM

STATE_EXPIRED : 4
STATE_COMPLETE : 3
STATE_FINAL_REVIEW : 17
STATE_IN_PROGRESS : 2
STATE_NEW : 1
STATE_PHASE_1 : 11
STATE_PHASE_1_D : 12
STATE_PHASE_1_V : 13
STATE_PHASE_2 : 14
STATE_PHASE_2_D : 15
STATE_PHASE_2_V : 16

You can use the below code snippets to close all the open certification tasks.

/**
  *
  * @param cert_id: certification id. available in CERTD_USER table
  * @param userEntityId: User id for the certification which are pending. available in CERTD_USER.
  * @throws Exception
  */

 public void closeCertification(long cert_id,String userEntityId) throws Exception{
  
   CertificationService certificationService = (CertificationService)oimClient.getService(CertificationService.class);
    char[] oimAdminPassword = "Welcome1".toCharArray(); //Xelsysadm password
    
   List<Long> userEntityIds = new ArrayList<Long>();
   userEntityIds.add(Long.valueOf(userEntityId));
  
   
//get the certification instance from cert id
   CertificationInstance certInstance = certificationService.loadCertification(cert_id,null);
   System.out.println("Status : "+certInstance.getStatus());
   System.out.println("STATE_EXPIRED : "+CertificationConstants.STATE_EXPIRED);
   System.out.println("STATE_COMPLETE : "+CertificationConstants.STATE_COMPLETE);
  
 
  //get the different status level
   int status = certInstance.getStatus();
   int complete = CertificationConstants.STATE_COMPLETE;
   int expired = CertificationConstants.STATE_EXPIRED;
  
  
 //Checking the current status of the certification instance.
   if (status==complete) {
   
    System.out.println("certification already completed : "+cert_id);
   }else if(status==expired){
    System.out.println("certification already completed : "+cert_id);
   }  
   else{
   
    
//Certifying user of the cert instance with cancel comment
    certificationService.certifyUsers(cert_id, null, userEntityIds, CertificationConstants.STATUS_ABSTAIN, "Canceled due migration");
    certificationService.certifyRemainingUserContent(cert_id, null, userEntityIds, "Canceled due migration");
   
    if ( certificationService.canBeCompleted(cert_id, null) ) {
    
   
  //completing the certification.
     certificationService.completeCertification(cert_id, null, oimAdminPassword);
     System.out.println("Certification Completed successfully : "+cert_id);
    }else{
     System.out.println("Certification not Completed yet : "+cert_id+" , "+certInstance.getPercentComplete()+"% completed");
    }
   }
   

Assign and Revoke OIM Admin roles using API

OIM has several admin roles, which are under the scope of some organizations. in PS3 there is a separate application for managing admin roles, but in the older version this operation was incorporated under organization's life cycle.

Here are the API examples of managing Admin role life cycle like assigning or revoke. This API will work in all the OIM 11gR2 versions including PS3.

 /**
  * Assigning OIM Admin role to a user.
  * @param Userid
  * @param adminRoleName
  */

 public void assignAdminRole(String Userid, String adminRoleName){
 
  try {
  
  
 /**
    * initialize API and get the details of a specified admin role
    */

   AdminRoleService admRoleAPI = (AdminRoleService)oimClient.getService(AdminRoleService.class);
   AdminRole admRole = admRoleAPI.getAdminRole(adminRoleName);
  
   
//Print some details.
   System.out.println("Scope ::"+admRole.isScoped());
   System.out.println("Role Description ::"+admRole.getRoleDescription());
   System.out.println("Role Description ::"+admRole.getRoleId());
  
   //Create a new membership object.
   AdminRoleMembership admMembership = new  AdminRoleMembership();
   admMembership.setAdminRole(admRole);
   admMembership.setUserId(getUserKey(Userid));
  
   
/**
    * Every Admin role scoped under some organization (or organizations).
    * Assigning any admin role you need to set the scope id.
    */

   AdminRoleVO adminRoleVo = admRoleAPI.getAdminRoleVO(String.valueOf(admRole.getRoleId()));
   List<AdminRoleRuleScope> scopes = adminRoleVo.getAdminRoleRuleScopes();
   AdminRoleRuleScope scope = scopes.get(0);
   System.out.println("Admin Role In Scope Organization: "+scope.getInScopeOfOrganizationName()); //printing the organization name
   
     
   
/**
    * If the admin role is not scoped then set the scope id for SYSTEM ADMINISTRATOR organization
    * which is generally 3.  
    */
 
  if (admRole.isScoped()){
    
    admMembership.setScopeId(getOrgKey(scope.getInScopeOfOrganizationName()));
    
   }else{
    
    admMembership.setScopeId("3");
   }
   
    System.out.println("new set Scope ::"+admMembership.getScopeId());
    AdminRoleMembership newMemberShip = admRoleAPI.addAdminRoleMembership(admMembership);
    System.out.println("Admin Role Successfully Assigned to the User: "+Userid+" Key: "+newMemberShip.getUserId());
   
  
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.getMessage();
  }
 
 
 }

 
/**
  * Revok an Admin Role from user.
  * @param Userid
  * @param adminRoleName
  */

 public void revokeAdminRole(String Userid, String adminRoleName){
 
  AdminRoleService admRoleAPI = (AdminRoleService)oimClient.getService(AdminRoleService.class);
  List<String> adminRoles = new ArrayList();
  adminRoles.add(adminRoleName);
 
 
 /**
   * Get the user and admin role membership object.
   */

  List<AdminRoleMembership> adminMemberShipList = admRoleAPI.listMembershipsForUserByRoleName(getUserKey(Userid), adminRoles);
  AdminRoleMembership adminMemberShip = adminMemberShipList.get(0);
 
  
//revoke admin role.
  boolean status = admRoleAPI.removeAdminRoleMembership(adminMemberShip);
  System.out.println("Admin Role Successfully revoke from User: "+Userid+" Status: "+status);
 }


 
 /**
  * get user key from given username
  * @param userid
  * @return Userkey
  */

 private String getUserKey(String userid){
 
  String key = "";
  UserManager userAPI = (UserManager)oimClient.getService(UserManager.class);
  java.util.Set retAttrs = new HashSet();
  retAttrs.add(UserManagerConstants.AttributeName.USER_KEY.getId());
 
  User user;
  try {
   user = userAPI.getDetails(UserManagerConstants.AttributeName.USER_LOGIN.getId(), userid, retAttrs);
   key = user.getId();
  } catch (NoSuchUserException e) {
    e.printStackTrace();
  } catch (UserLookupException e) {
   e.printStackTrace();
  } catch (SearchKeyNotUniqueException e) {
   e.printStackTrace();
  } catch (AccessDeniedException e) {
     e.printStackTrace();
  }
  return key;
 }

 
 /**
  * get organization Key from a given Org name
  * @param orgName
  * @return OrgKey
  */

 private String getOrgKey(String orgName){
 
  String key = "";
  OrganizationManager orgAPI = (OrganizationManager)oimClient.getService(OrganizationManager.class);
  java.util.Set retAttrs = new HashSet();
  retAttrs.add(OrganizationManagerConstants.AttributeName.ID_FIELD.getId());
 
  try {
   Organization org = orgAPI.getDetails(OrganizationManagerConstants.AttributeName.ORG_NAME.getId(), orgName, retAttrs);
   key = String.valueOf(org.getAttribute("act_key"));
  
  } catch (SearchKeyNotUniqueException e) {
      e.printStackTrace();
  } catch (OrganizationManagerException e) {
    e.printStackTrace();
  } catch (AccessDeniedException e) {
    e.printStackTrace();
  }
 
  return key;
 }

Monday 8 May 2017

Add a new page in OIM 11gR2 PS3 (With ADF Task Flow)

Implementing OIM in an organization doesn't fulfill all the requirements. Some time we need to do lot of customization to meet customer's expectations. The good thing about OIM is, you can customize the functionalities and User Interface as per your own requirements. Even you can add a complete new page to define your own functionalities.. In this post I am going to describe the basic steps to add a new page in OIM 11gR2 PS3.

Adding a new page in OIM is not like adding a new html or jsp page. OIM only support ADF task flow to show its contents, and the functionalities of this page will be executing inside OIM engine. if you observe the pages in OIM while opening, you can find the pages are opening in a new internal tab where browser url is fixed.


All this pages are nothing but ADF task flow. We can create our own task flow in ADF and merge it to OIM identity console home page.

1. first open the JDeveloper (I am using 11.1.1.6).
2. Create a new Fusion Web Application project.

3. click Next
4. The model project details appeared. Click Next

5. Click Next.
6. View controller project details appeared. Click Next.
7. Click Finish to create the project
8. once the project is created it will looks like the above image.
9. Now we have to create a new task flow in this project. Right click on the ViewController project and click on New
10. select the JSF from the left and select ADF Task Flow from the right.


11. click ok
12. Provide the name of the task flow and append "\oracle\iam\ui\custom" at the directory link after WEB-INF. Otherwise OIM will be unable to recognize the task flow. once done click on Ok to create the task flow.

13. Now open the task flow test-flow.xml,  drag the view components from the components pallet into the task flow page. Give a name like TestPage
14. Every view components you drag into this task flow page will be created as a fragment page. To create the fragment of this view component, double click on it.
15. It will ask you to create jsff page for that view components. provide a name (recommended to keep the default: TestPage.jsff) and click on Ok. It will create a .jsff page under Web Component.

16. Now open the TestPage.jsff. Drag the "Output text" component from the Source Elements (from right side panel) into the jsff page. Change the content of the text "This is the test task flow page in OIM PS3".


17. Drag a spacer component and another Output Text element into this jsff page.


18. Now click on the source table of the TestPage.jsff. Change the value of the last output text added as below.

value="#{oimcontext.currentUser['User Login']}"


Note: "#{oimcontext.currentUser['User Login']}"  is the EL (Expression Language) to display the currently logged in user's username. As we are embedding this task flow inside OIM identity console page, so we can use all the OIM's default ELs in this project.

19. Click on Save button to save the project.
20. The basic task flow project is ready. Now we have to create a new deployment profile for this project to build ADF library jar. OIM will read this task flow project as an added UI customization, and all UI customization in OIM required ADF Library Jar. other format will not work.

21. Right click on the ViewController project and click on New. Select Deployment Profile from left and ADF Library Jar from right and click Ok.


22. Click Ok.


23. Provide the jar name (recommendation is to keep the default). it should always start with adflib. Once done, click Ok.


24. When it will ask for the model project dependencies, click on Ok.


 25. In the Deployment page you can find the default WAR is also present with the newly added adf lib. Remove the WAR profile and keep only the ADF Lib Jar.


26. After removal click on Ok. Save the project and deploy the project by Right click on ViewController -> Deploy -> adflibOIMTF1


27. click Next

28. Click Next


29. Click on Finish to create the jar.


30. The message window will display the successful compilation of the project. It also display the path where the jar file is created.


31. Now we have to implement this jar file into OIM and link this task flow into OIM home page.
32. Login to OIM server using FTP, and copy the oracle.iam.ui.custom-dev-starter-pack.war  from [OIM_HOME]/servers/apps to your desktop.

33. Copy the adflibOIMTF1.jar to oracle.iam.ui.custom-dev-starter-pack.war /WEB-INF/lib



34. replace the old oracle.iam.ui.custom-dev-starter-pack.war file with the new one, back to the same location.

35. Restart the OIM server.

36. Open the OIM PS3 identity console. and create a new sandbox.
37. From the home page click on Customize.
38. All the OIM PS3 tiles are arranged in table manner. The entire page is a table. 1 tile box is a Colum of a row of the table. Each row can hold 4 columns (means 4 tiles). So if we need to add a new tile, then we have to select the row where new column can be added and add a new column on it.
if any row is not have space to hold columns the create a new row.

37. In this case I selected the 2nd row and added a new cell. click on the row and click on Add (+) button.


38. Now select Web Components.


39. Now add a new grid cell.



40. Now select the Grid cell and click on Add (+) button


41. From the same location select and Add Dashboard Tile.


42. Close the web composer of OIM. You can see the new tile is added with default name. Do not change any details of the tile from the OIM Web Composer.


43. Export the sandbox.

44. Open the sandbox zip and edit the oracle\iam\ui\homepage\home\pages\mdssys\cust\site\site\self-service-home.jsff as below. Just add the highlighted details into the page.


45. Save the page and copy it on to the sandbox.
46. Import the sandbox into OIM and make it active.
47. Go to the Home page of identity console and you can see the modifies tile.


48. Click on the tile and you can see a new page opened.


49. This way you can add new page in OIM.

In my next blog I will discuss, how to embed functionalities onto the newly added page, where task flow page will be integrated with managed bean, and managed bean will contains OIM APIs. 

Followers

OIM API for adding process task and retry failed task

 In this blog you can find how to add new process task and retry any failed/rejected tasks using API. Adding new process task: /************...