Wednesday, February 11, 2009

Panels in User Manager's Employees tab

The "Employees" tab of user manager can have multiple panels in it:
  • The defaultPanel
  • The Header Panel
  • The Search Results panel
  • Any other user defined panels
The header panel, the defaultPanel and any user defined panels appear under "obpanelid=Employees, obapp=userservcenter, o=Oblix,<Config Base>" in the LDAP as "obpanelid=<some timestamp as ID>".

The header panel has its obpaneltype value as "headerPanel".

The value of "defaultPanel" for obpaneltype is for the default user profile panel. The user can change its name from "defaultPanel" to any other value, but the obpaneltype remains "defaultPanel".
Ever wondered what the third panel type, obpaneltype of jCardPanel? Its the panel for the search results!

Just because it does not show up as a "panel" on Identity System console can sometimes create confusion. For example when once because of some buggy horizontal migration, we eneded up with two objects with obpaneltype=jCardPanel and any change we attepted on the user manager tab profile, resulted in the error "This panel is already configured". From the Identity System console we could not see any duplicate panel information, it was only when we looked closely in LDAP, we saw two objects with obpaneltype=jCardPanel. Once we deleted the un-needed object and restarted ois server, things started working.

Wednesday, November 19, 2008

OAM Identity Server Deletes User When RDN Modified (on OID)

This is known problem but i had trouble finding the solution so here it is re-posted from the OAS release notes for HP-UX... the resolution worked perfectly BTW.
This problem occurs when you use Oracle Internet Directory as the back-end repository. To fix this problem:
  1. Edit the file ldapreferentialintegrityparams.xml in the following directory:
    Identity_Server_installation_directory\identity\oblix\data\common
  2. Change the value of the parameter referential_integrity_using from oblix to ds, as follows:
  3. Save the file.
  4. Restart the Identity Server for the changes to take effect.
    You should be able to modify the RDN attribute value without any problem.
  5. If you have multiple instances of the Identity Server installed, make this change to every instance of the Identity Server.

Wednesday, August 20, 2008

SDK-Access Server Time Difference Reminder

When using a older Access Server SDK (7.0.4) with a newer Access Server (10.1.4) running in backward compatibility mode recently, the Access Server SDK always returned cookies that were logged out. The reason turned out to be because the time was never set on the machine the SDK was installed on.

However, the Access Server SDK installed correctly when it was installed. In previous incarnations the Access Server SDK would have never been able to be configured properly if a significant time difference existed.

This definitely falls squarely in the realm of user error, as the documentation clearly stipulates that when cert or simple mode are used the times have to be synchronized between client and server. In previous releases though you would never have been able to complete the SDK configuration. I can only imagine this has something to do with "backward compatibility" mode.

Thursday, August 7, 2008

Reactivate OAM User

In order to be able to search for deactivated users, the logged in user need to be a participant in a reactivate user workflow definition.

If the user is not a participant in a reactivate user workflow then the following message will be received when the "Deactivated User Identity" button is clicked:

You do not have sufficient access rights.

Wednesday, August 6, 2008

OID Indexes

Here are a few simple notes for handling OID indexes. If you want to search on an attribute in OAM where the data is stored in OID it must be indexed. Sometimes you might want to remove and then possible re-add an index. Index adding and removal can be handles with LDIF, however, if you need to recreate an index on existing data then you need to use a command line tool called catalog.

Index an attribute

dn: cn=catalogs
changetype: modify
add: orclindexedattribute
orclindexedattribute: attributename
-

Remove an index

dn: cn=catalogs
changetype: modify
delete: orclindexedattribute
orclindexedattribute: attributename
-

Re-index an attribute
that was previously removed. If you remove an index form an attribute and the data remains and you need to re-index the data in place then you need to use the catalog command line tool.

$ORACLE_HOME/ldap/bin/catalog connect=oiddev add=&quotTRUE" attribute="attributename"

Unwilling to perform
If after the attribute has been re-indexed the directory server will still not allow it to be searched and returns an unwilling to perform error, try restarting the OID gateway.

$ORACLE_HOME/opmn/bin/opmnctl restartproc ias-component=OID

Current Indexed AttirbutesUse ldapsearch to get the current indexed attributes

ldapsearch -h localhost -p 389 -x -s base -b "cn=catalogs" "objectclass=*"

Saturday, July 26, 2008

Deleting a User with IDXML

Certain actions (such as creating or removing an LDAP entry) are only available via OAM's 'workflow' engine. A freshly installed OAM system has no workflows configured, thus, no immediate mechanism to affect such actions.

To the newly initiated, discovering the create workflow mechanisms are relatively straightforward. But the delete, however, tends to throw people for a loop at first.

The trick is to create a 'Deactivate User Workflow'. Exactly what this workflow does is up the user building the workflow. You'll find, following the definition of the initial step, three similar action choices:
  • deactivate
  • disable
  • delete

If your goal is truly to whack the account, choose delete. Otherwise, a choice of disable will set the user account ObUserAccountControl flag to DEACTIVATED (with no human interaction required). By default, the Identity System ignores DEACTIVATED accounts in the user searchbase. The deactivate action accomplishes the same thing but it requires a human participant to actually push the button to confirm the action.

Lastly, if you want to access this 'Delete User Workflow' from IDXML you just need to keep in mind that it is a workflow you are calling. Pay close attention to:
  • function="workflowDeactivateUserSave"
  • and the fact that you do provide the workflow DN in the call
Here is a complete request for calling a Deactivate User Workflow:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas-xmlsoap.org/soap/envelope/" xmlns:oblix="http://www.oblix.com">
<SOAP-ENV:Body>
<oblix:authentication type="basic">
<oblix:login>admin</oblix:login>
<oblix:password>test1234</oblix:password>
</oblix:authentication>
<oblix:request application="userservcenter" function="workflowDeactivateUserSave" version="NPWSDL1.0">
<oblix:params>
<oblix:ObWorkflowName>obworkflowid=c60491a5ca0a45668fff08da2f1072d2,obcontainerId=workflowDefinitions,OU=Oblix,OU=apps,DC=company,DC=com</oblix:ObWorkflowName>
<oblix:uid>UID=372af3c1-0c7e-428d-a80a-fae632211489,OU=people,DC=company,DC=com</oblix:uid>
<oblix:noOfFields>2</oblix:noOfFields>
<AttributeParams xmlns="http://www.oblix.com/">
<GenericAttribute>
<AttrName>cn</AttrName>
<AttrNewValue>test</AttrNewValue>
<AttrOperation>REPLACE_ALL</AttrOperation>
</GenericAttribute>
<GenericAttribute>
<AttrName>userStatus</AttrName>
<AttrNewValue>delete</AttrNewValue>
<AttrOperation>REPLACE_ALL</AttrOperation>
</GenericAttribute>
</AttributeParams>
</oblix:params>
</oblix:request>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Tuesday, July 22, 2008

OAM Identity XML (IDXML) via XMLHttpRequest

It makes sense that the ideal HTTP Client for IDXML processing is the authenticated user's browser. After all, it already has the ObSSOCookie.

JQuery is the Javascript library of choice for all my client work lately. You can see why in the following example of processing an IDXML request via Javascript straight from the client. The use cases for this capability are endless.

This is the proverbial 'tip of the iceberg' in utilizing OAM Identity in a modern web development context. The end result: Perfectable user experiences based on data and services made available and secured through OAM's web based configuration tools. It's a powerful combination.

Lets take a simple create user workflow request and turn out a simple Javascript templating function to build the string for us:
getSoap = function(data){
  var dat = [];
  dat[dat.length] = '<?xml version="1.0" encoding="UTF-8"?>';
  dat[dat.length] = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas-xmlsoap.org/soap/envelope/" xmlns:oblix="http://www.oblix.com">';
  dat[dat.length] = '<SOAP-ENV:Body>';
  dat[dat.length] = '<oblix:request function="workflowSaveCreateProfile" version="NPWSDL1.0">';
  dat[dat.length] = '<oblix:params>';
  dat[dat.length] = '<oblix:ObWorkflowName>obworkflowid=672fcf2e9c5946a8b5b225b349acd46b,obcontainerId=workflowDefinitions,OU=Oblix,OU=apps,DC=company,DC=com</oblix:ObWorkflowName>';
  dat[dat.length] = '<oblix:ObDomainName>OU=people,DC=company,DC=com</oblix:ObDomainName>';
  dat[dat.length] = '<oblix:noOfFields>5</oblix:noOfFields>';
  dat[dat.length] = '<AttributeParams xmlns="http://www.oblix.com/">';
  dat[dat.length] = '<GenericAttribute>';
  dat[dat.length] = '<AttrName>uid</AttrName>';
  dat[dat.length] = '<AttrNewValue>'+data.uid+'</AttrNewValue>';
  dat[dat.length] = '<AttrOperation>ADD</AttrOperation>';
  dat[dat.length] = '</GenericAttribute>';
  dat[dat.length] = '<GenericAttribute>';
  dat[dat.length] = '<AttrName>cn</AttrName>';
  dat[dat.length] = '<AttrNewValue>'+data.cn+'</AttrNewValue>';
  dat[dat.length] = '<AttrOperation>ADD</AttrOperation>';
  dat[dat.length] = '</GenericAttribute>';
  dat[dat.length] = '<GenericAttribute>';
  dat[dat.length] = '<AttrName>mail</AttrName>';
  dat[dat.length] = '<AttrNewValue>'+data.mail+'</AttrNewValue>';
  dat[dat.length] = '<AttrOperation>ADD</AttrOperation>';
  dat[dat.length] = '</GenericAttribute>';
  dat[dat.length] = '<GenericAttribute>';
  dat[dat.length] = '<AttrName>givenName</AttrName>';
  dat[dat.length] = '<AttrNewValue>'+data.givenName+'</AttrNewValue>';
  dat[dat.length] = '<AttrOperation>ADD</AttrOperation>';
  dat[dat.length] = '</GenericAttribute>';
  dat[dat.length] = '<GenericAttribute>';
  dat[dat.length] = '<AttrName>sn</AttrName>';
  dat[dat.length] = '<AttrNewValue>'+data.sn+'</AttrNewValue>';
  dat[dat.length] = '<AttrOperation>ADD</AttrOperation>';
  dat[dat.length] = '</GenericAttribute>';
  dat[dat.length] = '</AttributeParams>';
  dat[dat.length] = '<oblix:obactorcomment>IDXML from browser via Javascrip</oblix:obactorcomment>';
  dat[dat.length] = '</oblix:params>';
  dat[dat.length] = '</oblix:request>';
  dat[dat.length] = '</SOAP-ENV:Body>';
  dat[dat.length] = '</SOAP-ENV:Envelope>';

  return dat.join("");
};


Then, if we prep a little data object with values (presumably pulled from the user interface):

var userdata = {
  uid:"marmil",
  cn:"Mark Miller",
  mail:"mark[at]nulli.com",
  givenName:"Mark",
  sn:"Miller"
};


I can call my template and consider my soap envelope ready to go:

var createUserSoapRequest = getSoap(userdata);


All over but the sending (and response handling):

// process the request
$.ajax({
  type: "POST",
  dataType:'xml',
  url: "/identity/oblix/apps/userservcenter/bin/userservcenter.cgi",
  data: createUserSoapRequest,
  contentType:"text/xml",
  processData:false,
  success: function(idxmlResponse){
    // crude
    alert(idxmlResponse);

    // better
    $("ObConfirmation",idxmlResponse).find("ObValue").each(function(i,o){
      alert($(o).text());
    });

    // in the real world, employ dom trickery to keep the user oriented...
  }
});


Cool, no?