Skip Headers
Oracle® Access Manager Developer Guide
10g (10.1.4.2.0)

Part Number E10355-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

3 Identity Event Plug-in API

The Identity Event Plug-in API enables you to extend the base Identity System functionality. This API provides a channel for Identity System data to flow between Identity System applications and external software components. Applications for this API can be as simple as basic logging of Identity System usage, or as sophisticated as data-filtering pipelines or seamless bridges to Enterprise Resource Planning systems.

The Identity Event Plug-in API is a standard installed component of the Identity System product.

This chapter discusses the following:

This chapter contains the following sections:

3.1 About the Identity Event Plug-in API

Just as a Web server can be configured to execute CGI programs and server-side scripts during the life cycle of an HTTP request, the Identity Event Plug-in API gives developers the ability to extend the Identity System by providing their own small applications, called actions or event handlers, to perform custom business logic and integrate with external systems. You connect event handlers to the events using a special configuration file named oblixpppcatalog.lst. The Identity System makes certain data available to the actions, which are then allowed to modify the data and influence the outcome of the event.

To support multibyte characters for globalization and localization in 10g Release 3 (10.1.3), UTF-8 encoding is used for XML pages, for SOAP/IdentityXML requests, and for Identity Event Plug-in data sent to executables. Earlier releases used ISO-8859-1 encoding (also known as Latin-1).

To provide backward compatibility with earlier releases that used Latin-1 encoding, 10g (10.1.4.0.1) supports IdentityXML requests in both ISO-8859-1 encoding (Latin-1) and UTF-8. For XML documents written to disk, both ISO-8859-1 and UTF-8 encoding are supported. IdentityXML responses are emitted in the same encoding format as the request. Therefore, when a request uses Latin-1 encoding (encoding="ISO-8859-1" the response uses Latin-1 encoding; when a request uses UTF-8 encoding, the corresponding response uses UTF-8 encoding.

Note:

Oracle recommends that you use encoding="UTF-8" in new 10g (10.1.4.0.1) installations. In upgraded environments, Oracle recommends that you use encoding="ISO-8859-1" for backward compatibility.

If an IdentityXML request uses encoding="ISO-8859-1" and the response to it contains any characters outside the Latin-1 character set, the response containing such characters is garbled. For example, when encoding="ISO-8859-1" is used for the request and the response includes Japanese or Arabic characters, those characters in the response will be garbled. For more information, see the Oracle Access Manager Upgrade Guide.

3.1.1 Examples of Uses of the Identity Event Plug-in API

Common uses of this API are for password validation, integration, and provisioning.

For example, in a password validation application, suppose a security architect recommends the use of 8-character passwords with 2-4 digits and 1-3 special characters. You can develop an event handler for Password Management events that use the Identity Event API and add this event handler to an Identity System password policy.

As another example, suppose that new hires need to be recorded in a RDBMS to ensure that they receive a "Welcome to the company" packet. You could develop an event handler for the Enable step of each registration workflow instance to update the remote database using the RDBMS vendor's API.

Finally, suppose that new users require a randomly generated unique ID to act as their login ID. You could develop an event handler for the Enable step of each registration workflow instance to generate a unique string in the required format and pass it back to the Identity System to use as the uid attribute value.

3.2 Connecting Events to Actions

This section describes actions and events in more detail, and explains how to connect them to each other using the Configuration File.

3.2.1 Types of Events

An event is a state change within the Identity system. Examples of events:

  • A request was received and is about to be passed to the User Manager view program.

  • Results have been generated by the Group Manager search program.

  • A user has entered a challenge response while attempting a password reset.

  • An attribute on a profile page for an Organization Manager tab has been modified.

  • A workflow ticket awaiting approval by the corporate IT group has been approved.

  • A user has entered a new password, and the password policy in force requires external validation.

The Identity System provides functionality specific to five different types of events, summarized here. More detail for each type of event appears in the section on "How the API Works".

3.2.1.1 Identity System Program Events: Pre and Post

These are the most frequently used type of event. Each Identity System application (User Manager, Group Manager, Organization Manager) contains a number of programs (view, search, and so on) that generate the displayed HTML for each page within the application. When any program runs, a pair of events is generated. Each of the programs recognizes this pair of events.

One event (Pre) is generated before the program begins to create the page. The Pre event enables an event handler to work with a request before it reaches a program. The other event (Post) is generated after the program has created the page, but before responding to the user with an HTML page. The Post event enables an event handler to work with the results of processing a request.

These two events are referred to as the pre-processing event and the post-processing event for that program, as shown in the following diagram.

Pre and post-processing events.

3.2.1.2 OnChange

OnChange event interaction is provided as part of the set of Identity System applications (User Manager, Group Manager, and Organization Manager). Specifically, the OnChange event applies to the Profile page within each of these applications. When a change is made to any of the data in these pages, an OnChange event is generated. These events are triggered only after the changes are successfully committed to the directory.

3.2.1.3 Workflow Events

Workflows are definitions for a repeatable set of steps used to create or modify data. Workflow definitions are created and stored within the Identity System. The user can then reference the workflow by name, and instruct the workflow engine to process it when needed. Workflow steps each generate a pair of events (pre and post). The pre event enables an event handler to inspect and modify workflow data before the step is executed. The post event enables an event handler to inspect and modify workflow data after the step is executed. Workflow steps also generate an external action event.

The Pre, Post, and external action events in a workflow can process both LDAP data and template object data. This is a departure from the Identity System applications, which only process LDAP data. The Identity System stores template attributes in fully qualified form on a workflow step, as follows:

attribute.class.domain

See the chapter on configuring template objects in the Oracle Access Manager Administration Guide for details.

3.2.1.4 Password Management Events

Password Management events are generated when an attempt is made to set the password of a user in a branch of the directory tree that is covered by a password policy whose external validation flag is enabled. Actions associated with Password Management events are used to check password quality against custom business rules.

As part of creating a password policy, you may enable the option ÒExternally specified validation rules.Ó Oracle Access Manager applies the password policy for the requester. If the requester is covered by the policy, then Oracle Access Manager checks to see if this flag is set. If it is, then Oracle Access Manager executes the password validation event which in turn carries out the action defined by the user. Oracle Access Manager also supports the Identity Event plug-in for the Identity System Lost Password Management application. When you configure the oblixpppcatalog.lst file, the application name is lost_pwd_mgmt.

3.2.1.5 Lost Password Management

The event related to lost password management functionality is setChangedPassword, and the application name for this is lost_pwd_mgmt. The sample application name, event name, and action is lost_pwd_mgmt_setChangedPassword_pre.

3.2.1.6 Encryption Events

The Identity System applies a proprietary encryption method to several pieces of information. One is cookie information, such as the login cookie for a authenticated session. An encrypted version of this cookie is kept by the user's browser while a session is in effect. A second is the response half of the challenge/response pair used for Lost Password Management. The response phrase, to be given by the user in response to the challenge phrase, is stored encrypted in the directory. Password information is encrypted when included in a workflow. Encryption events are used to invoke user-defined encryption algorithms (implemented by actions) when the Identity System needs to encrypt a piece of data.

You can replace Oracle Access Manager's encryption technique with one of your own by adding actions to the Catalog to replace either or both of these default encryption methods. For example, you can replace the default encryption scheme for cookies, challenge responses, and password fields in workflows using this method.

3.2.2 Types of Actions

An action is an event handler. More specifically it is a unit of external logic written by a developer and then configured by a Master Administrator to execute in response to a particular event.

Actions have three formats: LIB, MANAGEDLIB, and EXEC.

Actions may perform their tasks without accessing external components, or they may use any available mechanism to access third-party applications and resources such as web services, RDBMS services, and ERP applications.

At startup time, the Identity Server reads its configuration catalog, which tells it what events have actions. When an event occurs, the server executes the associated action.

3.2.2.1 LIB Actions

A LIB action is a function within a shared library that the Identity Server calls. LIB actions reside in shared libraries on Unix or DLLs on Windows. Once dynamically loaded, the action function executes in the same process space as the Identity Server and has direct access through API functions to data objects held by the server.

For a LIB action, the Identity Server dynamically opens the shared library or DLL, locates the function that implements the action, and calls the function.

LIB actions have advantages. These are:

Fast loading—LIB actions are compiled binary objects that reside in shared libraries. They have relatively low startup overhead.

Reusable at runtime—LIB actions need only be loaded once. They then remain in virtual memory, ready for subsequent calls.

High performance—LIB actions execute quickly because they are binary code modules compiled from C or C++ source code. Of course, whether they are received as fast depends on the function they perform.

Identity data on demand—LIB actions have access to a great deal of data about the current request, the authenticated user, and other services from the Identity System using simple GET/SET API calls.

Scalable—LIB actions provide good scalability, even in high traffic applications, because they are simply functions that can be called repeatedly as requests are processed, with low overhead.

Disadvantages of LIB actions:

Limited support from third-party components—LIB actions, because they are written in C or C++ have relatively few freely available third-party APIs to call upon for external services such as RDBMS access, XML parsing and formatting, network services, cryptography services, LDAP services, and so on. These services are more widely available to the Java and PERL developer community.

Specialist expertise required—LIB actions require more specialized skills to implement. This can increase the cost. For instance, even to deploy the same action on a Windows and Solaris environment simultaneously would require C/C++ development expertise in both platforms and development environments.

Platform-dependent source code—The steps necessary to author and build a shared library on Solaris are different from building a DLL for Windows on NT. Either defensive coding practices are required to ensure cross-platform source code, or multiple source trees must be maintained for a multi-platform deployment.

Potential to cause Identity Server failure—Any uncaught exceptions caused by errors in LIB actions will cause the Identity Server to fail. This is because the action is running in the Identity System Identity address space, and if it accidentally causes a memory leak or memory trash, the server cannot detect and recover from this. These problems to not exist in EXEC actions because each EXEC action runs in its own address space and can only damage itself. The server can detect this because the child process exits without returning a success status.

3.2.2.2 MANAGEDLIB Actions

A MANAGEDLIB actions only run on Windows. A MANAGEDLIB action can be written in any .NET language. A .NET language is any source language for which a Microsoft Intermediate Language (MIL) compiler exists. MIL instructions are executed by the Microsoft .NET Common Language Runtime (CLR), which uses a just-in-time (JIT) compiler. The JIT compiler compiles the MIL instructions into native machine instructions. MIL instructions are compiled once and stored in dynamic memory. There is a modest performance hit the first time that managed code is executed.

ManagedLib actions.

MANAGEDLIB actions are similar to LIB actions. As with LIB actions, a MANAGEDLIB action is loaded into memory. MANAGEDLIB actions also share most of the benefits of LIB actions.

In addition, MANAGEDLIB actions offer the benefits of managed code, including:

  • Language Choice—You can write your plug-ins in VisualBasic, C#, Managed C++ (MC++), Java, or PERL.

  • Language Integration—You can combine MIL modules compiled from different source languages into one assembly or plug-in. This provides the plug-in writer with a wider range of language choices for plug-in development.

  • Support for Memory Management—The CLR provides garbage collection, freeing the plug-in writer from most memory management. The garbage collector will return memory to the heap when that memory is no longer referenced. However, the plug-in writer should ensure that there are no dangling references to objects. If there are dangling references, garbage collection will not occur for the unused memory.

  • .NET framework support—The .NET framework SDK contains a wide range of functionality. This may reduce the need for third-party support in plug-in code.

3.2.2.3 EXEC Actions

An EXEC action is a standalone executable program that the Identity Server executes. EXEC actions reside in separate executables and run in their own process space. To process an EXEC action, the Identity Server starts a new child process and loads the executable passing its parameters. Input is streamed to the action on STDIN and output is received on STDOUT and the process's exit status.

Characteristics of EXEC actions:

  • Communication with the Identity Server is limited to startup parameters and an XML stream for input, and an XML stream plus an exit status code for output. Any further access to the Identity System data must be done like any other Identity System client, using IdentityXML.

  • Actions can also use any other APIs, such as an LDAP Identity Event Plug-in API to access directory information directly.

  • For scripted EXEC actions, the action would be the interpreter, such as /usr/local/bin/perl, and the script itself would be passed as a command-line parameter.

Advantages of EXEC actions:

Choice of Development Languages—EXEC action developers can write the code in C, C++, Java, PERL, or any language that supports C-style command line processing and stdio.h compatible standard I/O processing.

Rapid prototyping—EXEC actions can be rapidly prototyped or developed using scripting languages such as PERL.

Platform-Independent Code—EXEC action source code can be platform independent because of the language neutrality. The same code written in PERL and Java will execute on Windows and Unix.

Java-Compatible—EXEC actions can be implemented in Java, giving them access to third-party services that only provide Java APIs.

Extensive Third-Party Support—EXEC actions cannot bring down the Identity Server. If they fail, the end user will see an error report and the Identity Server will continue to serve other requests.

Disadvantages include:

Poor Scalability—EXEC actions do not scale as well for high-traffic applications because a new child process is required for each request.

Limited Access to Identity System Data—EXEC actions get their input from command line parameters and from the (static) XML stream available on STDIN when they execute. There is no API to provide direct access to further Identity System information. To do this, the action would have to implement an IdentityXML client and communicate with Identity Server over a separate connection.

XML Parser Required—EXEC actions need to parse XML for all but the simplest tasks in order to access their input. This means that they must have an embedded parser that understands the XML schema of any input they may receive. This adds to the startup time, the memory footprint, and the complexity of the action, and may be too heavyweight for many tasks.

3.2.3 Configuration File (Catalog)

The Identity System uses a configuration file, oblixpppcatalog.lst, to provide the link between Identity events to be responded to and custom actions to be taken. This file is called the Catalog. For LIB, MANAGEDLIB, and EXEC actions, this file is installed and must stay in the following directory:

Identity_install_dir/identity/oblix/apps/common/bin

Note:

When you installed the Identity System, an installation directory was specified and created, for example: /usr/coreid/identity. As a convenient shorthand, this directory is called Identity_install_Dir.

Each entry in oblixpppcatalog.lst is a single line linking an Identity System event to an action. Each line in the Catalog must contain at least five fields (six if you need to use the apiVersion field), delimited by semicolons. Each line must end with a semicolon. Lists of data items within each field are delimited by commas. Fields may be empty, indicated by the semicolons being next to each other. The precise content of each field varies with the action type and the kind of event to which it is responding.

The general form for a LIB or MANAGEDLIB entry is:

actionName;actiontype;;path;funcname;apiVersion;

With LIB and MANAGEDLIB actions, the path can be relative or a full path.

The general form for an EXEC entry is:

actionName;actiontype;identityparam1,...;path;execparam1,...;apiVersion;

Fields within the entries are delimited by semicolons (;). Each entry must have at least five fields, and end with a semicolon, followed by a new line (carriage return and line feed).

Note:

The special character # is used in this file to indicate lines that are comments. Do not use this character as part of a LIB or EXEC entry. It would be a mistake, for example, to call a LIB funcname getbuilding# since, for that entry, everything past the # would be ignored.

Explanation of each field is given in the following table. Read down each column to understand the content for each of the action types.

Field Name LIB and MANAGEDLIB Actions EXEC Actions
actionName

(required)

Field 1. The action name. The name contains information that tells the Identity System which event type the action responds to and in some cases whether it should be performed before, as part of, or after the event. Field 1. Same description as for LIB and MANAGEDLIB Actions.
actiontype

(required)

Field 2. managedlib (This exact text) or lib (this exact text), depending on what type of action you are using. Field 2. exec (This exact text).
identityparam1,

. . .

(optional)

Field 3. This field is always empty. Field 3. Used by EXEC actions only. The names of global parameters, delimited by commas. A table of these parameters is provided on "Global Parameters".
path

(required)

Field 4. The location and name of the LIB or MANAGEDLIB file that implements the action. Field 4. The location and name of the EXEC file that implements the action.
funcname

(required)

Field 5. The name of one function to call from within the shared library, for the LIB or MANAGEDLIB action. N/A
execparam

(optional)

N/A Field 5. One or more input parameters to the EXEC action, delimited by commas.
apiVersion

(optional)

Field 6. Leave this field empty. Reserved for earlier versions of the product. Field 6. Same description as for MANAGEDLIB Actions.

3.2.4 Guidelines for Writing an Action

The procedure for creating an action is as follows.

3.2.4.1 Task overview: Writing an action

  1. Identify Requirements—Investigate whether you need to validate or modify the inputs, results, or side effects of an Identity System request or workflow in order to achieve results that the Identity System cannot deliver.

  2. Select the Event—This depends on the following:

3.2.4.2 Availability—The availability of the data

  1. Timing—whether the system is in the desired state for the action when the event occurs

  2. Performance—To maximize performance, identify the least frequently used event that will yield the desired result.

  3. Execution—Determine if this action should run before (pre-event) or after (post-event) the request is processed by the Identity System application.

  4. Write—Write the action.

  5. Configure the Action—A Master Administrator must edit the Identity Event plug-in API configuration catalog in

Identity_install_dir//identity/oblix/apps/common/bin/oblixpppcatalog.lst

The administrator enters an entry in the catalog to register the action and its parameters against a particular request. The administrator then restarts the Identity Server(s) or uses a portal insert to refresh the catalog of a running Identity Server.

3.3 How the API Works

The next section describes how actions are found and executed, from the Identity System application's point of view. The following section, "Identity System Applications, as Seen by Actions" describes what happens and what data can be accessed, from an action's perspective.

3.3.1 Actions, as Seen by Identity System Applications

The Catalog is loaded once, when the Identity System starts up. File content can be changed while the Identity System is running, but the changes take effect only if the file is reloaded. You can force changes to take effect by restarting the Identity System or by linking from any browser to the following URL:

http://hostname:port/identity/oblix/apps/admin/bin/genconfig.cgi?program=flushCache&cacheType=ppp

For LIB and EXEC Actions—If you flush the Identity Event Plug-in (PPP) information from the Identity System, it forgets all it knew about DSOs and executables that contain actions. The Identity System reads the Catalog again when it next generates an event, and starts loading DSOs on demand, depending on what actions are configured and what events occur.

For MANAGEDLIB Actions—The DSO (in managed code terminology, this is the assembly or DLL) is loaded once into the default application domain. If a plug-in writer rebuilds the assembly, they will need to restart the Identity Server to ensure that the new assembly is loaded the first time an action from that assembly is invoked.

Multiple actions can be defined for a single event. If multiple actions are defined, all of the actions are performed, in the order that they appear in the Catalog. This approach enables you to build action pipelines, where the output of one action can become the input of the next.

Keep in mind, however, that for a typical event, the event that invoked the action was caused by user activity. While your code is processing the data, and passing its output down the chain, the end user may be waiting for a result. You should include the impact of user-perceived responsiveness in the design and testing of all actions, especially if multiple actions are expected for a single event. Note also that if any of the multiple actions returns an error, additional actions in the pipeline for that event instance will not be performed.

The following diagram shows how three possible events can be configured with actions for the User Manager application.

Assume that the workflowActivate event is associated in the Catalog with three custom actions to be performed during post-processing:

  • Invoke an action to extract information about the newly activated user, and add the user to default company email distribution lists.

  • Send a pre-written email message template to relevant lists and individuals (possibly based on Identity System data) welcoming the new user to the organization.

  • Trigger an external business process that updates each of various external company databases with appropriate information about the user. This can be as simple as an application that pushes the new user's information to a table where external programs can pick it up.

How events are triggered.

In this example, when a user request generates the workflowActivate event, User Manager consults the Catalog, determines that this event has no configured pre-processing actions, and proceeds to generate the page in XML. It then checks for post-processing actions and finds three: updateDistLists, sendWelcomeMsg and updateRDBMS. User Manager checks the Catalog to see whether the first action, updateDistLists, is a LIB or EXEC action. How processing proceeds depends on the result of this test:

  • For a LIB Action—User Manager dynamically loads the DSO containing the function (if it is not already loaded) and obtains a pointer to the function within the action. It then calls the function, passing the name of the event for which it is being invoked and a pointer to an ObPPPData object through which the action can interact with User Manager. The action performs its tasks, querying User Manager as needed through calls to ObPPPData methods. When its task is complete, the action function returns status information that the event uses to decide its next behavior.

  • For a MANAGEDLIB Action—User Manager dynamically loads the DSO containing the function if it is not already loaded and obtains a pointer to an object that implements the IPPPData interface. The Identity System will reference an EventAPI object and invoke the "action" method on that object, passing a reference to IPPPData as a parameter of the "action" method. The EventAPI object is a singleton, meaning that the first request will instantiate the object and subsequent requests will use this object. The action performs its tasks, querying User Manager as needed through calls to IPPPData methods. When its task is complete, the action function returns status information that the event uses to decide its next behavior.

    Note:

    In managed code terminology, DSO is referred to as an assembly or a dll.
  • For an EXEC Action—User Manager starts up the executable in a new process, making connections to its STDIN and STDOUT streams. The argv[] array of command line arguments is built as well. The first argument is the total count of arguments. The last is always the data for the set of Identity System parameters specified in the catalog (if any), provided in a specific XML format, called EventXML. The arguments in between match the values given for EXEC parameters in the catalog file (if any). User Manager always sends the XML data representing the current state of the request, in EventXML format, to the action on its STDIN. The action interprets its arguments, if any, reads its STDIN and performs its task, which may or may not involve XML parsing to extract and replace (or extract and replace) information received from User Manager. When complete, the action optionally writes the XML data out on its STDOUT. The action is not required to return the XML data, because the Identity System keeps the original version as the default, in parsed form. (If the data is large, avoiding an extra parsing operation can be worthwhile).

    Note:

    If any action modifies the XML data, it is the action's responsibility to make sure the output XML conforms to the appropriate XML Schema. How to find the correct schema file for the event you are handling is described in "Connecting Events to Actions".

When User Manager receives the result status code, either from the return value of a LIB action function or from the exit status of a terminating child process that was running an EXEC action, it proceeds as follows:

  • STATUS_PPP_OK—User Manager looks for the next post-processing action in the Catalog that is configured for workflowActivate. If there is one, User Manager goes through the preceding procedure again for that action, passing in the possibly modified XML data received from the earlier actions.

  • STATUS_PPP_ABORT—The action has signalled an error. In this case, User Manager does not even check for subsequent actions for the event. It translates any information transmitted by the action through the API into an error, and handles the error. This result generally results in an error message being displayed to the user, who can then report the problem.

  • STATUS_PPP_WF_ASYNC—For use with workflows, this result tells the event to wait for an asynchronous, probably manual, action to be completed. For example, this might ensure that a currently unavailable database is updated before the workflow continues. See "Workflow Events" for more details.

  • STATUS_PPP_WF_RETRY—For use with workflows, this response tells the event that the workflow step did not complete, probably because of invalid data, that therefore needs to be reentered. The event increments its retrycount, and starts again.

In the example, workflowActivate has three post-processing actions. You can view this as a pipeline, because the data flows from one action to the next. In practice, each action returns to User Manager before the next is called. If all of the actions return STATUS_PPP_OK, User Manager completes its processing for the request, applying the XSL stylesheet for the page and returning the resulting HTML page to the browser.

No actions are configured for the workflowDeactivate pre- or post-processing events, so User Manager builds the result page without calling any actions.

The workflowReactivate post-processing event is configured to call the sendWelcomeBackMsg action. User Manager calls this single action and applies XSL processing to its output before returning the result page to the user.

Note:

The action has direct access only to data known to the current event. For example, in order to access full user information from the directory, the action might have to communicate with the Identity System using a different method, such as the IdentityXML interface, before it has sufficient information to accomplish a given task.

The preceding illustration uses User Manager as an example; the other Identity System applications that generate events behave in exactly the same way with respect to the Identity Event Plug-in API.

For detailed examples of LIB, MANAGEDLIB, and EXEC actions, including sample code and Catalog entries for configuration, see "Examples".

3.3.2 Identity System Applications, as Seen by Actions

The following topics provide details about Identity System applications and actions:

3.3.2.1 LIB Actions

LIB actions are only available in C or C++. However, if you want to write these actions in Java, you can write a JNI to wrap C++ functions with the Java API.

3.3.2.2 LIB Interface

The LIB action interface to the Identity System is defined by the ObPPPData class provided in the obpppdata.h. file. See "Development Environment" for the location of this file. ObPPPData defines five methods that a LIB action may use to access Identity System data. These methods are:

  • Get —Use this method to get the value or values (attributes may be multi-valued) for a specified parameter from the Identity System application that triggered the event. The method returns a pointer to an array of values matching a key. The key is any attribute that is known to the application handling the event. The key may also be one of the Global parameters; see "Global Parameters". The last member of the array is a NULL.

    virtual const char * const *Get( const char *key) const;
    
    

    Responsibility for allocating and freeing memory for the return value lies with the Identity System. If you request a value for a parameter that is not valid for the event triggering the action, only the NULL value is returned.

  • Set—Use this method to set the value(s) for a given parameter to be sent to the Identity System application. You should set values only for those parameters that are valid for the event.

    virtual int Set(const char *key,

    const char * const *value) = 0;

    Key represents the parameter to be set; value is an array of values to be used. The last member of the array must contain a NULL.

    Responsibility for allocating and freeing memory for the input parameter content lies with the API developer.

    The Identity System returns 1 if the set is successful, 0 if not.

  • Receive —Use this method to request and receive event data from the Identity System application as an XML string. You will need to understand the structure of this XML string in order to locate data within it. See "Working with XML" and the chapter on PresentationXML in the Oracle Access Manager Customization Guide.

    virtual const char *Receive() const = 0;
    
    
  • Send—Use this method to send replacement content for the event page to the Identity System application as an XML string. Generally, this will be EventXML, from which the Identity System application extracts the information it needs. In the case of post actions, however, this is expected to be PresentationXML. This PresentationXML string completely replaces the output that the Identity System application would otherwise have used to generate an HTML page for the user or would have passed to the next action if this action is part of a pipeline. Your new content may differ in a minor way, such as the addition of a copyright or other text message, or it may contain significantly different data.

    virtual void Send(const char *data) = 0;
    
    

    The XML data string being sent must match the schema expected by the application receiving it. Best practice is to verify the XML data against the schema with an XML editor, before using the action in a live environment.

  • SetResultString—Use this method to set the content of a result string to be displayed to the user by the Identity System application. The exact manner in which the text is then shown varies with the event to which the action is responding.

    virtual void SetResultString(const char *str) = 0;
    
    

    str contains the text to be displayed.

    Note:

    This method cannot be used for post events, because the data returned by them is in PresentationXML format. If an error is to be displayed, the developer is responsible for building it into the PresentationXML.

3.3.2.3 Load Behavior

The Dynamically Shared Object (DSO) for a LIB action is loaded into the Identity System's address space when it is first needed and remains there. A new version of the DSO can be generated and installed while the Identity System is running, but any revised actions contained in the DSO will not be loaded unless the Identity System is stopped or started, or the loaded Catalog is flushed using the URL described in "Configuration File (Catalog)". If the file is flushed, then the action is reloaded the next time its corresponding event occurs.

Functions for LIB actions are loaded as needed into Identity System applications, and executed directly by them. For this reason, you will need to link with the Oracle-provided interface library on Windows platforms or with the runtime shared library itself for UNIX. See "Development Environment" for the location of the Windows library.

3.3.2.4 LIB Examples

LIB Code examples can be found installed under the following directory:

Identity_install_dir/oblix/usupported/ppp/ppp_dll

They are provided under "Examples".

3.3.2.5 MANAGEDLIB Actions

MANAGEDLIB actions can be written in any language supported by the Microsoft .NET framework for managed code, including Visual Basic, C# and C++.

3.3.2.6 MANAGEDLIB Interface

The MANAGEDLIB action interface to the Identity System is defined by the IPPPData interface. See "Development Environment" for the location of the header file. The header was written in MC++. The IPPPData interface will be syntactically different in other .NET languages, but will work the same way, that is, the semantics will be identical.

IPPPData defines five methods that a MANAGEDLIB action may use to access Identity System data. The definitions for these methods are similar to those for LIB actions:

  • Get —Gets value or values for a specified parameter (argument key) from the Identity System application that triggered the event.

    String * Get( String * key ) __gc[];
    
    
  • Set—Set the value(s) for a given parameter (argument key) to be sent to the Identity System application. You should set values only for those parameters that are valid for the event.

    int Set( String * key , String * value __gc[] );
    
    
  • Receive —Use this method to request and receive event data from the Identity System application as an XML string. You will need to understand the structure of this XML string in order to locate data within it. See "Working with XML". See also the chapter on PresentationXML in the Oracle Access Manager Customization Guide.

    String * Receive( );
    
    
  • Send—Use this method to send replacement content for the event page to the Identity System application as an XML string.

    void Send( String * data );
    
    

    The XML data string being sent must match the schema expected by the application receiving it. Best practice is to verify the XML data against the schema with an XML editor, before using the action in a live environment.

  • SetResultString—Use this method to set the content of a result string to be displayed to the user by the Identity System application. The exact manner in which the text is then shown varies with the event to which the action is responding.

    void SetResultString( String * str );
    
    

    str contains the text to be displayed.

    Note:

    This method cannot be used for post events, because the data returned by them is in PresentationXML format. If an error is to be displayed, the developer is responsible for building it into the PresentationXML.

3.3.2.7 Load Behavior for MANAGEDLIB

The DSO (managed assembly or dll) is loaded once into the default application domain, which is part of the Identity System process. If a plug-in writer rebuilds the assembly, they will need to restart the Identity Server to ensure that the new assembly is loaded the first time an action from that assembly is invoked.

3.3.2.8 MANAGEDLIB Examples

MANAGEDLIB code examples can be found installed under

Identity_install_dir\oblix\unsupported\ppp\dotnet\managedcplusplus

and are provided under "Examples".

3.3.2.9 MANAGEDLIB Actions

Using Windows-based Managed Code, you can write MANAGEDLIB actions in Visual Basic, C#, C++, and any other language that uses Managed Code. Managed Code is only appropriate for MANAGEDLIB actions, not for EXECs. This is because MANAGEDLIB actions are loaded into memory.

3.3.2.10 EXEC Actions

Exec Interface—Executables run as distinct processes and do not share an address space with the Identity System.

The Identity System determines the data to be sent and received between itself and the executable, based on the Identity System and Executable parameters specified in the Catalog entry. The action then receives a set of command line arguments and XML data representing the event on STDIN. The EXEC action returns a status and, optionally, XML data on STDOUT. The possibilities are shown in the following diagram:

Exec actions.

The set of command line arguments has a fixed logical structure. Consider, for example, the argv[] array of command line parameters. The first member of this array is the total count of arguments. The last array member is always the data for the set of Identity System parameters (if any) specified in the catalog entry for the event, always provided in EventXML format. (These are the same set of parameters available to LIB actions; see the full list at "Global Parameters".) The arguments in between are the values given for EXEC parameters (if any) in the catalog entry for the event. The exec parameters are user-defined instructions to the EXEC action that control its operation.

The format of the XML data sent to the action and returned by it varies with the type of event. In most cases, both the STDIN and STDOUT data will be in EventXML format. Post processing events are an exception; they always return PresentationXML, as discussed in greater detail in "Pre and Post Events".

EXEC actions are able to get and return the same data as LIBs, but do it in a more complex way, generally requiring parsing of the XML data. Here are the equivalences:

  • Equivalence to Get —The desired value must be obtained by first locating the attribute name in the EventXML or PresentationXML string, then extracting the value.

Values for global parameters are provided, in EventXML format, as the last command line argument.

  • Equivalence to Set —The user must start with the full EventXML or PresentationXML string, then locate the attribute name in the XML and insert the value.

  • Equivalence to Receive —This is the EventXML or PresentationXML string for the event, which is always provided to the EXEC using its STDIN.

  • Equivalence to Send —This is the EventXML or PresentationML which the action optionally returns on its STDOUT.

  • Equivalence to SetResultString —Use ObResultString to name the ObParam and provide the message string as its value.

3.3.2.11 Load Behavior

Unlike LIB actions (which are cached) EXEC actions are executed afresh from the file system each time they are used. This means that they can be replaced at any time with a new version. The new version is executed the next time the corresponding event is triggered.

3.3.2.12 EXEC Examples

EXEC Code examples can be found installed under

Identity_install_dir/oblix/unsupported/ppp/ppp_exec

3.3.2.13 Global Parameters

A special set of global parameters can be retrieved. Lib actions get values for these parameters interactively, using the Get method. Exec actions get values by providing one or more of the parameter names in the parameter list. Either way the developer specifies a predefined fixed value parameter name, also called a key, as listed in the following table. Use the full uppercase parameter name shown in the table, preceded by either ObRequest or ObEnv, as shown.

User Identity Key Name Description of Data
ObRequest.

REMOTE_ADDR

Client IP address, for example, 666.777.888.999. This is the IP address of the user making the request.
ObRequest.

REMOTE_HOST

Client's DNS address (for example, www.foo.com).
ObRequest.

REMOTE_PORT

The port number at which the client host is listening.
ObRequest.

REMOTE_USER

Name of the HTTP authenticated user.
ObRequest.

HTTP_USER_AGENT

Name of the client's browser (for example, Mozilla/4.07).
ObRequest.

OBLIX_AUTH_USER

The Oracle Access Manager authenticated user.
ObRequest.

TARGET_UID

UID for the target entry.
ObRequest.

<any requestInfo parameter>

A requestInfo parameter is any of the values that appear in the URL for a displayed page, following the delimiters $ or &.
ObEnv.

INSTALL_DIR

Installation Directory for the Identity Server.

For example, to get the name of the user making the request from within a LIB or MANAGEDLIB Faction, the content could be:

currentuser = Get("ObRequest.OBLIX_AUTH_USER")

The catalog entry for the equivalent EXEC request might look like this:

userservcenter_view_pre;exec; ObRequest.OBLIX_AUTH_USER; ../../../unsupported/ppp/ppp_exec/pppexectest; someinstruction;

3.3.3 Working with XML

The following topics are discussed in this section:

3.3.3.1 Event XML Format

EventXML provides a standard, predictable format for use by LIB, MANAGEDLIB, and EXEC actions. The schema for EventXML looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.oblix.com/"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.oblix.com/" elementFormDefault="qualified">
           <xs:element name="ObEventParams">
             <xs:complexType>
             <xs:choice minOccurs="0"
                  maxOccurs="unbounded">
                  <xs:element name="ObParamList"
                  minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                       <xs:sequence>
                         <xs:element ref="ObParam"
                           maxOccurs="unbounded"/>
                         </xs:sequence>
                         <xs:attribute name="name"
                         type="xs:string" use="required"/>
                       </xs:complexType>
                     </xs:element>
                     <xs:element ref="ObParam" minOccurs="0"
                         maxOccurs="unbounded"/>
             </xs:choice>
             </xs:complexType>
           </xs:element>

<xs:element name="ObParam">
             <xs:complexType>
               <xs:sequence>
                   <xs:element name="ObValue" type="xs:string"
                     minOccurs="0" maxOccurs="unbounded"/>
                   </xs:sequence>
                   <xs:attribute name="name" type="xs:string"
                   use="required"/>
                 </xs:complexType>
</xs:element>
</xs:schema>

Consider an example. Suppose the Catalog entry for an EXEC action is as follows:

userservcenter_view_pre;exec;
ObRequest.cn,ObRequest.sn; ../../../unsupported/ppp/ppp_exec/pppexectest; execparam;

This example specifies that the EXEC action pppexectest is to be invoked before (pre) the Identity System begins to build the person profile page (view) in User Manager (userservcenter). Information is requested for the cn parameter and sn parameters. The executable parameter execparam is to be included as the first command line argument to the executable.

The last argument of the command-line information passed to the EXEC action, containing the EventXML, will be as shown in the following listing. Note there are as many instances of ObParam as there are requested parameters.

<?xml version="1.0" encoding="UTF-8"?>
<ObEventParams
xmlns="http://www.oblix.com/">
<ObParamList name="ObRequest">
<ObParam name="cn">
<ObValue>John Smith</ObValue>
</ObParam>
<ObParam name="sn">
<ObValue>Smith</ObValue>
</ObParam>
</ObParamList>
</ObEventParams>

3.3.3.2 PresentationXML Format

The content of PresentationXML is highly variable, because the Identity System enables the user to modify the appearance and content of screens to satisfy site-dependent requirements. An explanation of the XML content and structure is provided in the chapter on PresentationXML in the Oracle Access Manager Customization Guide.

3.3.3.3 Parsing XML

In order to work with either EventXML or PresentationXML, the developer will need to be able to parse the XML data stream, to locate the points in the stream where data is provided (to in effect Get data) or must be inserted (to in effect Set data).

We do not attempt here to tell developers how to program such a parser. However, a set of examples is provided at:

Identity_install_dir/oblix/unsupported/ppp/parser_test

See "Parser Example Files" for a list of these files.

The files assume the developer is using the free Apache XML parser, XERCES, source code for which can be obtained from:

http://xml.apache.org/

The content of the EventXML and PresentationXML strings technically is predictable, but depends in very complex ways upon which event is occurring and in which application. The recommended approach is to set up an action that returns the XML stream for the desired application and event combination, and capture the stream in a file. Then, code the action to work with that information. This approach is particularly appropriate for actions to be written for post-processing events, when the stream consists of highly variable PresentationXML information.

3.4 Event Handling in the API

For each of the five event types, this section describes:

The following topics are discussed in this section:

Note:

Events are described in greater detail at "Types of Events". All event types support LIB, MANAGEDLIB, and EXEC actions.

3.4.1 Event Handler Initialization and Shutdown Functions

For LIB and MANAGEDLIB actions, Pre and Post Processing (PPP) provides functions for initialization and shutdown for the event handler. These initialization and termination functions are called each time when the PPP library is loaded or unloaded.

For MANAGEDLIB actions, you must define a singleton object of class EventAPI. The constructor will be invoked upon loading the DSO, while the destructor will be called when the default application domain is unloaded from the Identity System process during shutdown. The initialization code must be placed in the constructor for this class, and the shutdown code must be placed in the destructor. These replace the Init and Term functions provided for LIB and MANAGEDLIB actions.

Global initialization and cleanup should be done only within the following functions.

3.4.1.1 ObInitEventAPI ( )

For LIB, actions, the ObInitEventAPI () function is called when the DSO is loaded. This function, shown as follows, provides all global initialization such as reading of configuration files and creation of log files.

unsigned int OBLIX_DLLEXPORT ObInitEventAPI (void)

This function is guaranteed to be called in a thread-safe manner.

If this function is present in the plug-in, the Identity System calls it after the plug-in has been loaded.

3.4.1.2 Return Values

The function can return either of the following two response values, which are defined in the obppp.h. file:

  • STATUS_PPP_OK—This is the result the function should return if it succeeds. This function result tells the application that the function has completed execution without error.

  • STATUS_PPP_ABORT— This is the result the function should return if it fails. This function result tells the application that the function failed to complete execution because of an error. Subsequent calls to the plug-in will not be made.

3.4.1.3 ObTermEventAPI ( )

For LIB actions, the function ObTermEventAPI () is called when the DSO is unloaded. This function, shown as follows, performs clean-up activity such as releasing any allocated memory and closing any opened files.

unsigned int OBLIX_DLLEXPORT ObTermEventAPI (void)

This function is guaranteed to be called in a thread-safe manner.

If this function is present in the plug-in, the Identity System calls it when the server is being shut down.

3.4.1.4 Return Values

The action returns the following value which are defined in the pppdlltest.cpp file:

STATUS_PPP_OK—The function returns this result to tell the application that it has completed the action without error.

STATUS_PPP_ABORT—The function returns this result to tell the application that it has encountered an error.

3.4.2 Pre and Post Events

The following topics are discussed in this section:

3.4.2.1 Catalog Entry

For this event type the format for the entry in the Catalog for a LIB action or a MANAGEDLIB action is:

actionName;lib;;libname;libfuncname;apiVersion;

For EXEC actions the format for the entry is:

actionName;exec;NPparam1,...;execname;execparam1,...;apiVersion;

Note the punctuation within each entry. Fields are separated by semicolons; lists of items within fields are separated by commas. The entry is terminated with a semicolon. Fields may be empty. The following table describes each field in detail.

Field Name Description
actionName (for events in Group Manager, Organization Manager, and User Manager) Required. Provide this information in the form APPNAME_EVENTNAME_PPPTYPE. Note the underscores used to separate the three parts.

APPNAME is the Identity System application name. Valid application names are:

groupservcenter—or Group Manager

objservcenter—for Organization Manager

userservcenter—for User Manager

EVENTNAME is one of the possible events for the APPNAME application, as described in Chapter C, "Identity Events".

PPPTYPE is one of two values:

pre—means the action is a preprocessing action, to take place before the event

post—means a post-processing action, to occur after the event.

(other fields) See the descriptions in "Configuration File (Catalog)".

The following are some LIB action Catalog entry examples. For the examples shown here and in following sections, file entries are shown with line breaks at the semicolon delimiters, to allow printing in this Guide. In the actual file, the content must be entered all on one line. Also, source for many of the example actions is provided as part of the Identity System installation. See "Development Environment".

userservcenter_view_pre;lib;;
../../../unsupported/ppp/ppp_dll/libppp_dll.dll;
PreProcessingTest;;

For a MANAGEDLIB action Catalog, the entry would be as follows:

userservcenter_view_pre;managedlib;;
c:\unsupported\ppp\ppp_dll\libppp_dll.dll; PreProcessingTest;;

This example calls for the PreProcessingTest action function in the ppp_dll.dll library to be performed before (pre) the person profile page (event = view) is built by the User Manager (application = userservcenter). Because the file type is lib, this is a LIB action implemented by a function, meaning that the DSO must be loaded and the function located within the DSO before the action can be performed.

This example action that is provided in the unsupported directory changes the requested uid value to the following DN:

cn=Pick Carli,ou=Customer10K1,ou=Customers,o=Company,c=US

Mr. Smith's profile is always displayed when the user requests a profile page in the User Manager, regardless of the uid for which the request was made.

userservcenter_view_post;lib;; ../../../unsupported/ppp/ppp_dll/ppp_dll.dll;
PostProcessingTest;;

This example configures the PostProcessingTest action function in ppp_dll.dll to be invoked after (post) the building of User Manager's person profile (view) page. This example action, which is provided in the unsupported directory, forces a message to be displayed instead of the profile page.

Further examples of Catalog entries can be found in the default Catalog file located at:

Identity_install_dir/oblix/apps/common/bin/oblixpppcatalog.lst

3.4.2.2 Interaction Methods

Get

Operation User Identity Key Name Description of Data
GET <attribute name> For a LIB action, returns a NULL-terminated array holding each of the values provided for the named attribute within the XML data used to create the display. For managed code, returns an object of base type System.Array whose contents can be enumerated.

Set

Operation User Identity Key Name Description of Data
SET <attribute name> Sets values for the named attribute within the XML data used to create the display.
SET ObRequest.

<any requestInfo parameter>

Sets the single value for any of the RequestInfo parameters that appear in the URL for a displayed page, following $ or &.

Receive

XML data received in response to this request can be of two different formats, depending upon whether the action is pre or post. Pre actions receive data in the EventXML format, as described at "Working with XML". Post-processing actions receive data in the PresentationXML format, as described in the chapter on PresentationXML in the Oracle Access Manager Customization Guide.

Note:

In the case of pre actions, the EventXML will contain values only if the event being monitored is one that enables a change of attributes.

Send

XML data sent back to the application must be the same type as was received. The data sent to the application must conform to the formal schema for each type of data or else it will be rejected. The section "Parser Example Files" lists some files provided with the Identity System installation, which can be used to verify the data using an XML editor.

SetResultString

A string returned with this method will be displayed by the Identity System application.

Return Values

The action should return one two response values, which are defined in the Obppp.h file:

  • STATUS_PPP_OK—This is the success response. The action sends this value to tell the application that the action has completed without an error. Value = 0x00h.

  • STATUS_PPP_ABORT—This value returned means an error has occurred. Value = 0x01h.

Failure to formally return a response value will cause unpredictable behavior in the application, depending upon the default return value that the operating system will supply instead.

3.4.3 OnChange Events

The following topics are discussed in this section:

3.4.3.1 Catalog Entry

Entries to the Catalog for this action type are the same as for pre- and post-processing events, except for the action name.

Field Name Description
actionName (for OnChange) Required. Provide this information in the form APPNAME_STRUCTURALCLASSNAME_onchange.

APPNAME is the Identity System application name.

STRUCTURALCLASSNAME is the name of the structural class that contains the attribute whose change in value is to be monitored. If the attribute belongs to an auxiliary class then the name of the structural class it is attached to.

onchange precisely identifies the type of action.

(other fields) See the descriptions in "Configuration File (Catalog)".

This event gets triggered only after the changes are successfully committed to the directory.

Here is an example:

userservcenter_inetOrgPerson_onchange;lib;;
..\..\..\unsupported\ppp\ppp_dll\ppp_dll.dll;
uscOnChange;;

This example calls for the action uscOnChange to monitor any changes that the event makes to attributes belonging to the inetOrgPerson class, or to any of its attached auxiliary classes.

3.4.3.2 Interaction Methods

Get

Operation User Identity Key Name Description of Data
GET <attribute name>.ObOldValue The old value for the attribute.
GET <attribute name>.ObNewValue The new value for the attribute.
GET <attribute name>.ObChangeType The type of change that was made.

Possible values:

OB_ADD—A new value was added.

OB_MODIFY—An existing value was changed.

OB_DELETE—An existing value was deleted.

OB_NOCHANGE—The value was not changed.


Set

This method is not supported for the OnChange event.

Receive

Receive() is used to get data from the Identity System. XML can be received just as for pre- and post-processing events, but only in EventXML format.

Send

The Send() method is used to send data to the Identity System. The onChange event handler is called in response to completion of an operation that changed data in the Profile page of an Identity System application. For the onChange event handler, you use the Send() method to set a message to be displayed on the screen after the modification operation completes execution. A call to the Send() method must be sent in EVENTXML format.

Send() method is for sending data back to the Identity System. For the onChange event, Send() can only be used to set a message to be shown after the operation is completed. The same result can be implemented using the SetResultString() call

SetResultString

A string returned with this method will be displayed by the Identity System application.

3.4.3.3 Return Values

The action must return one of two response values, which are defined in the Obppp.h file:

  • STATUS_PPP_OK—This is the success response. The action sends this value to tell the application that the action has completed without an error. Value = 0x00h.

  • STATUS_PPP_ABORT—This value returned means an error has occurred. Value = 0x01h.

Failure to formally return a response value will cause unpredictable behavior in the application, depending upon the default return value that the operating system will supply instead.

3.4.4 Workflow Events

The following topics are discussed in this section:

3.4.4.1 Catalog Entry

Workflow entries to the Catalog use the same format as for pre- and post-processing events. Also, except for the actionName field, the table describing the fields within entries is identical. For a description of the format and requirements for the fields of the workflow entry that are common to all entries, see "Configuration File (Catalog)".

Field Name Description
actionName (for workflows) For events triggered by workflows, use the form

WORKFLOW-DEFINITION-ID_STEP-DEFINITION-NUMBER_PPPTYPE. Note the underscores used to separate the three parts.

WORKFLOW-DEFINITION-ID is the unique identifier used to label the workflow. The DN for the workflow is shown in the workflow definition view. See the Oracle Access Manager Administration Guide for details.

STEP-DEFINITION-NUMBER is the number of the step within the workflow.

PPPTYPE is one of three values:

preaction—The action is a preprocessing action, to take place before the workflow step.

externalaction—Means the action occurs as part of the workflow step. The workflow waits for this action to complete before continuing.

postaction—Means a post-processing action, to occur after the workflow step.

(other fields) See the descriptions in "Configuration File (Catalog)".

Here is an example of a workflow event entry in the oblixpppcatalog.lst Catalog file:

63f004504f83455b924133acd0ef2e87_3_externalaction;
lib;;../../../unsupported/ppp/ppp_dll/libppp_dll.so;
WorkflowExtActionTest;;

This example calls WorkflowExtActionTest as an externalaction during step three of the workflow whose ID is 63f004504f83455b924133acd0ef2e87.

Example: Calling Logger as a Post-Processing Action After a Workflow Step

Here is another example of an entry in the Catalog. This example calls the Logger action after Step 1 of the workflow completes execution. The workflow ID number—2e22c064723e4030a05b437e059fe4d6—is used to identify the workflow that contains the step. The full entry for both MS Windows and Unix platforms is shown in the following paragraphs.

For Windows

Here is the oblixpppcatalog.lst entry for MS Windows:

2e22c064723e4030a05b437e059fe4d6_1_postaction; exec;uid;c:\j2sdk1.4.1_01\bin\java.exe; —classpath C:\ana\samples\bin Logger;;

  • actionName—2e22c064723e4030a05b437e059fe4d6_1_postaction

    Here are the parts of the actionName for this example:

    • WORKFLOW-DEFINITION_ID

    • 2e22c064723e4030a05b437e059fe4d6

    • STEP-DEFINITION_NUMBER

      1

    • PPPTYPE

      postaction

  • actionType—exec

  • identityparam1—uid

  • path—/usr/local/bin/java

functionname— -classpath C:\ana\samples\bin Logger

Note:

The same syntax applies for an entry pertaining to a pre-processing action. The single difference is that the PPPTYPE is preaction.

For Unix

Here is the oblixpppcatalog.lst entry for Unix

2e22c064723e4030a05b437e3059fe4d6_1_postaction;exec;uid;/usr/local/bin/java; -LD_LIBRARY_PATH/opt/ana/sample/bin Logger;;

actionName—2e22c064723e4030a05b437e3059fe4d6_1_postaction

actionType—exec

identityparam1—uid

path—/usr/local/bin/java

functionname— -LD_LIBRARY_PATH/opt/ana/sample/bin Logger

3.4.4.2 Interaction Methods

Get

Operation User Identity Key Name Description of Data
GET WfHandler This is the callback URL expected by the asynchResumeWorkflowProcess function in IdentityXML. This URL will be of the form:

http://www.domain.com/identity/oblix/ apps/asynch/bin/asynch.cgi

GET WfSubflow A list of one or more of the subflows belonging to the current workflow.
GET WfInstance.

<attribute name>

A list of one or more values for the named attribute belonging to the current workflow.

For example WfInstance.obtargetdn refers to the value for the target DN, as stored in the obtargetdn attribute. See the full list of WfInstance attributes in the following table.

GET WfStepInstance. <attribute name> A list of one or more values for the named attribute belonging to the current step of the current workflow.

For example WfStepInstance.obactordn refers to the value for the uid of the person processing the current step, as stored in the obactordn attribute.

GET WfAttribute.

<attribute name>

A list of one or more values for the named Workflow attribute. Refers to the configured workflow attribute for the step.
GET WfSubflow.

<subflowid>.

<attribute name>

A list of one or more values for the named attribute under the named subflow ID for the current Workflow, where attribute name is any of the WfInstance attributes pertaining to the subflowid. For example, WfSubflow.63f004504f83455b924133acd0ef87.

obtargetdn refers to the target DN of the subflow whose ID is 63f004504f83455b924133acd0ef87 and which is triggered from the current workflow instance.


Set

Operation User Identity Key Name Description of Data
SET WfAttribute.

<attribute name>

Any of the configured workflow attributes for the step.
SET WfInstance. Obwf

supplementalval

Set the approval status for all subflows. Applies only to steps that have multiple workflows. Possible values to be set are:

rejected

approved


Receive

XML can be received just as for pre- and post-processing events, but only in the EventXML format.

Send

XML can be sent just as for pre- and post-processing events, but only in the EventXML format.

SetResultString

A string returned with this method will be displayed by the Identity System application.

3.4.4.3 Tables of Workflow Attributes

The following table summarizes WfInstance attributes:

Attribute Name Meaning
obactionindicator For internal use.
obactorcomment Comments entered during workflow processing.
obapp Application to which the workflow belongs (for example userservcenter for User Manager).
obattr For internal use.
obcertid Certificate id (used by certificate workflows).
obclass Object classes of the target entry.
obcurrentdn The dn of the user who initiated the workflow.
obcurrentstep The dn of the current step being processed.
obdatecreated Integer date when the workflow instance was created.
obdateprocessed Integer date when the workflow instance was last processed.
obhostname Hostname of the machine from where the workflow was initiated.
obkey For internal use.
oblockedby The dn of the user who locked the workflow ticket.
obparentstep Applicable to subflows. dn of the parent workflow step instance that triggered the subflow.
obparentworkflow Applicable to subflows. The dn of the parent workflow instance.
obport Port number of the machine from which the workflow was initiated.
obtargetdn The dn of the target user entry.
obtriggeredworkflow For internal use. Maintains number of unfinished triggered subflows.
obver Identity System version.
obwfinstanceid Instance identifier.
obwfstatus Status of workflow.
obwfsupplementalval This indicates a single approval status of all triggered subflows. Valid values:
  • approved

  • rejected

Example:

data->Get("WfInstance.obwfsupplementalval");

obwftypename Display name of type of workflow.
obworkflowdn The dn of the workflow definition.
obworkflowname Name of workflow definition.
obworkflowtype Type of workflow, such as create user, change attribute, and so on.

The following table summarizes WfStepInstance attributes:

Attribute Name Meaning
obactionname Step action (for example initiate, request, and so on.)
obactionreturncode For internal use.
obactorcomment Status message of step processing.
obactordn The dn of the user processing the current step.
obapp Application to which the workflow belongs (for example userservcenter for User Manager).
obdatecreated Integer date when the workflow step instance was created.
obdateprocessed Integer date when the workflow step instance was last processed.
obentrycondition Not used.
obexitcondition Not used.
oblockedby The dn of the user who locked the workflow ticket.
oboptionalattribute List of optional attributes configured for the step. The attribute list is comma delimited.
obparticipant Not used.
obprovisionedattribute List of attributes for which subflows are configured in the step. The attribute list is comma delimited.
obrequiredattribute List of required attributes configured for the step. The attribute list is delimited with comma.
obretrycount Number of times the step has been retried. Applicable only if retry status is returned from workflow event handler.
obretrydone Boolean value that indicates if the retry is completed or not.
obtriggeredworkflow Not used.
obver Identity System version.
obwfstatus Status of step instance processing.
obwfstepinstid Step instance identifier.
obworkflowstepdn The dn of the workflow step definition.
obattr Attribute name.
obattrtype Attribute type.
obattrvals Attribute values.
obver Identity System version.
obwfattrdefval Not used.
obwfattrflags Not used.

3.4.4.4 Return Values

The action must return one of four response values to the workflow engine:

  • STATUS_PPP_OK—This value tells the workflow engine that the action has completed, and it may continue to the next step.

  • STATUS_PPP_ABORT—This value tells the workflow engine an error has occurred. The workflow engine tells workflow participants for the current step in the workflow that it has failed, and uses its internal logic to handle the error.

  • STATUS_PPP_WF_ASYNC—This value tells the workflow engine to put itself into a pending state, waiting for some external action to complete. Recover from this state by sending an asynchResumeWorkflowProcess command. The URL to which the command should be sent is requested using the parameter name wfhandler. This command and the process for using it, are described in the Chapter 2, "IdentityXML Functions and Parameters".

  • STATUS_PPP_WF_RETRY—This value tells the workflow engine that the step did not complete, most likely due to entry of invalid data. The user will need to try the step again, providing correct data. The current retry count is maintained in the directory entry for the workflow step instance. You can request the current retry count using the attribute name obretrycount.

Failure to formally return a response value may cause unpredictable behavior in the application, depending upon the default return value that the server operating system will supply instead.

3.4.5 Password Management Events

As part of creating a password policy, you may set a flag allowing "Externally specified validation rules." If this flag is set on, then the Identity System checks the Catalog for actions to be used in place of its standard Password Management.

The event related to lost password management functionality is setChangedPassword and the application name is lost_pwd_mgmt. The sample application name, event name, and action is lost_pwd_mgmt_setChangedPassword_pre. Note that this is not the standard UserServCenter application naming convention.

The following topics are discussed in this section:

3.4.5.1 Catalog Entry

Under Password Management, only one event is possible, Password Validation. The action name therefore has the fixed value PWMGMT_PasswordValidation. Also, because no pre- or post-processing is supported, the name does not include the pre or post indicator that other actions use.

Field Name Description
actionName (for Password Management) Required. Provide this information in the form PWMGMT_PasswordValidation.
(other fields) See the descriptions in "Configuration File (Catalog)".

Here is an example of a password validation event entry in the Catalog:

PWMGMT_PasswordValidation;exec;;..\..\..\unsupported\ppp\ppp_exec\ppp_exec.exe;;

This example calls ppp_exec.exe as an EXEC function to do password validation. This registers the standalone program ppp_exec.exe to perform password validation when a user attempts to change their password. The following must be true for the action to be invoked:

  • The action must be configured in the catalog and deployed on the Identity System.

  • A Master Identity Administrator must configure a password policy whose External Validation flag is turned on.

  • The password policy must be enabled.

The domain of the password policy must contain the user's identity.

3.4.5.2 Interaction Methods

Get

Operation User Identity Key Name Description of Data
GET Password This is the password value entered by the user, to be validated. It is a two-member array, NULL terminated.
GET PasswordPolicy

Domain

The domain defined for the Oracle Access Manager password policy that applies to the user.
GET PasswordPolicy

Filter

The filter defined for the Oracle Access Manager password policy that applies to the user.

Set

This method is not supported for the Password Management event.

Receive

XML can be received just as for pre- and post-processing events, but only in the EventXML format.

Send

XML can be sent just as for pre- and post-processing events, but only in the EventXML format.

SetResultString

A string returned with this method will be displayed by the Identity System application.

3.4.5.3 Return Values

The action must return one of two values:

  • STATUS_PPP_OK—Indicates that the password conforms to the rules and can be changed to the indicated value.

  • STATUS_PPP_ABORT—Indicates that it does not. The change can not be made.

Failure to formally return a response value will cause unpredictable behavior in the application, depending upon the default return value that the server operating system will supply instead.

3.4.6 Encryption Events

Whenever an encryption event occurs, the Identity System checks the Catalog for an encryption action. If one is present, then the process defined within it is used instead of the Identity System's default method.

If you make this change, the Identity System assigns all responsibility for the encryption to your action. Be sure that the encrypt and decrypt methods you use are the inverse of each other.

The following topics are discussed in this section:

3.4.6.1 Catalog Entry

Catalog entries for encryption use the same format as pre- and post-processing events, with one difference, the actionName. Under Encryption, only two events are possible. Also, because no pre- or post-processing is supported, the name does not include the pre or post indicator that other actions use.

In table format:

Field Name Description
actionName (for Encryption) Required. Provide this information in the form APPNAME_EVENTNAME. Note this has only two parts, separated by underscores.

APPNAME is the Identity System application name, in this case Encryption, entered as ENCRYPTION.

Under encryption, there are only two valid events, actually the type of information to be encrypted. These are the Cookie Encryption Key or the Challenge Response Encryption Key. Acceptable values for EVENTNAME are therefore cookieEncryptionKey or CPResponseEncryptionKey respectively.

(other fields) See the descriptions in "Configuration File (Catalog)".

Here is an example of an Encryption event entry in the Catalog.

ENCRYPTION_CPResponseEncryptionKey;lib;;
../../../unsupported/ppp/ppp_dll/ppp_dll.dll;
ProcessCPResponseEncryption;;

This example calls the ProcessCPResponseEncryption function in ppp_dll.dll to encrypt the challenge response key.

3.4.6.2 Interaction Methods

Get

Operation User Identity Key Name Description of Data
GET OPERATION This operation returns one of two values.

ENCRYPT—Encrypt the data.

DECRYPT—Decrypt the data.

GET INPUTSTR Returns user entered information in a two-member array, NULL terminated.

Set

Operation User Identity Key Name Description of Data
SET OUTPUTSTR The information to be returned to the Identity System. You must provide a NULL termination.

Receive

XML can be received just as for pre- and post-processing events, but only in the EventXML format.

Send

XML can be sent just as for pre- and post-processing events, but only in the EventXML format.

SetResultString

A string returned with this method will be displayed by the Identity System application.

3.4.6.3 Response Values

The event must return one of two values:

  • STATUS_PPP_OK—The event sends this value to indicate that encryption has completed satisfactorily.

  • STATUS_PPP_ABORT—The event sends this value to indicate that encryption did not complete satisfactorily.

  • Because encryption is essential to the Identity System's operation, any response other than STATUS_PPP_OK will cause the Identity System instance to stop, and generate a bug report.

3.5 The API

This section provides additional information for the developer on how to use the API. The following topics are discussed:

Note:

Do not use blank spaces in the names of any file in an Identity Event API project.

3.5.1 More on LIB Actions

You implement a LIB action as a callable function (with C language calling conventions), that resides within a dynamic shared object (DSO) library. The DSO must be native to the platform on which the Identity System is running. For example on NT, it must be a .dll; on Solaris UNIX it is must be an .so.

Note:

When developing a LIB plug-in, global data must be implemented in a thread-safe manner.

LIB actions are executed in the address space of the Identity System server process. It is critical that LIB actions be thoroughly tested before being deployed, as there is a class of programming errors (such as divide-by-zero errors) that cannot be caught by the Identity System and can cause the server to fail, or to exhibit other unstable behavior.

LIB actions communicate with the Identity System application by calling API functions directly, passing the appropriate parameters, as described in "Connecting Events to Actions".

3.5.2 More on MANAGEDLIB Actions

MANAGEDLIB actions are methods on a class. You implement a MANAGEDLIB action as a method on the EventAPI class, which is defined in the plug-in. The DSO is an assembly or a dll.

Note:

When developing a MANAGEDLIB plug-in, member variables of class EventAPI must be accessed in a thread-safe manner.

MANAGEDLIB actions are executed in the address space of the Identity server process. It is critical that MANAGEDLIB actions be thoroughly tested before being deployed. However, any exception generated by the managed plug-in will be caught by the Identity Server, logged, and a bug report page will be generated.

MANAGEDLIB actions communicate with the Identity System application by calling API functions directly, passing the appropriate parameters, as described in "Connecting Events to Actions".

When compiling an EventAPI PPP Plug-In in VB.NET, ensure that:

  • Your VB Class is named "EventAPI".

  • You are not using namespaces in your code.

  • You blank out the "Root Namespace" in the properties settings of your project in Visual Studio.NET with your VB project open:

    Go to the Project, then to Properties, then to the Common Properties / General page, then to the Root Namespace, remove the value, and click OK.

The Identity Server will not load your dll if you fail to perform any of the items in the previous list.

Note:

Any managed library to be used for PPP events must have the EventAPI class declared at the global namespace level. That is, it must be declared within no namespace. For a C# library, this means simply removing the `namespace' directive from the source code. For a VB.Net library, remove the `Default Namespace' option from the project.

3.5.3 More on EXEC Actions

You implement an EXEC action as a standalone executable. The action receives two kinds of input: command-line parameters that you specify in the catalog and XML data from the Identity program whose event is causing the action to run. The parameters are received in the ARGV[] array passed into the main() function (assuming a C/C++ programming environment). The XML data is available as a stream on the executable's standard input stream, STDIN.

Content of the XML data depends on whether the event is a pre-processing or post-processing event. For a pre-processing event, the data describes the request and is given in EventXML format. For a post-processing event, the data represents the result of processing the request and is given in PresentationXML format. (PresentationXML is the XML that would normally be combined with an XSL stylesheet and transformed into the HTML ultimately seen by the user's browser.) The action is expected to perform its task and optionally write modified XML, in the same format as was received, back to the executable's standard output STDOUT. If information is returned on STDOUT, the Identity System receives it and generates the HTML based on the new data.

Note:

A complete discussion of the process that the Identity System follows to logically combine XML data and XSL style sheets to create its HTML presentation is outside the scope of this manual. See the chapter on PresentationXML in the Oracle Access Manager Customization Guide.

Use of STDIN and STDOUT gives developers the ability to code their EXEC actions in any language that supports these data streams. This includes Java, C, C++, PERL, Python, UNIX shells, and .NET languages such as C#, MC++, and VisualBasic. If it needs to access the data to perform its task, an EXEC action may invoke any XML parser to interpret the XML. The Identity System does not provide a built-in parser. The EXEC action must maintain the validity of the XML. Otherwise the Oracle-provided or custom XSL stylesheets that may be applied further downstream before presentation to the user may not produce the expected results. Within this constraint, the EXEC action may perform any processing needed:

  • It might parse the Identity System data and take action based on the result.

  • It might filter the Identity System data by replacing some or all of it in the output stream with different data, taking care to maintain compliance with the Identity System data's XML schema.

  • It might allow the Identity System data to pass through untouched, but kick off another business process somewhere else on the network. For example, an action handling the workflowActivateSave event in User Manager can maintain a count of users that have been activated. When the count reaches a certain threshold, the action can trigger a backup or replication procedure to limit the risk of data loss. Or it can send email to an IT manager, who might want to investigate why so many users have suddenly been activated.

3.5.4 Returning Error Messages From an EXEC Call

There are three interfaces you can use to return error messages from an EXEC call. The three common interfaces are:

  • EXEC - WF

  • EXEC - PRE

  • EXEC - POST

3.5.4.1 Returning Error Messages Using EXEC - WF

To send error message back to the Identity System, specify the 'ObResultString' in the XML along with the message to be displayed. The message is displayed in the confirmation page after the user processes a ticket.

The XML MUST be constructed as follows:

<ObEventParams>
<ObParam name="ObResultString">
<ObValue>The value of the result string goes here...</ObValue>
</ObParam>
<ObParamList name="WfAttribute">
<ObParam name="cn">
<ObValue>New value(s) go here...</ObValue>
</ObParam>
<ObParam name="sn">
<ObValue>New value(s) go here...</ObValue>
<ObValue>New value(s) go here...</ObValue>
</ObParam>
</ObParamList>
<ObParamList name="WfInstance">
<!--
NOTE: This is the only parameter that can be changed. The parameter is used to set the outcome of a sub-flow. It will be displayed as the 'Outcome' value in the 'Subflow Approval' step. By default, the Identity System sets this parameter to 'approved' or 'rejected' in an 'Approval' step.
-->
<ObParam name="obwfsupplementalval">
<ObValue> New value(s) go here...</ObValue>
</ObParam>
</ObParamList>
</ObEventParams>

3.5.4.2 EReturning Error Messages Using EXEC - PRE

For a PRE event, the XML is constructed in much the same way as in a WF event. The DOM is the same. The difference is in the parameter names. The parameters usually begin with ObRequest, followed by the parameter you wish to change. To set the result string for a PRE event, the executable must return 'STATUS_PPP_ABORT'.

<ObEventParams>
<ObParam name="ObRequest.uid">
<ObValue>cn=Thomas Remahl,o=Company,c=US</ObValue>
</ObParam>
<ObParam name="ObResultString">
<ObValue>Always viewing: cn=Thomas Remahl,o=Company,c=US</ObValue>
</ObParam>
</ObEventParams

3.5.4.3 Returning Error Messages Using EXEC - POST

In the case of a POST event, the XML must conform to the event that is associated with the plug-in. To set the result string for a POST event, you usually embed an <ObTextMessage> element in the XML returned to the Identity System. Whether the returned string is shown or not depends on the associated stylesheet.

For example, the output of the view event in the following example shows the returned string "Hello, World!". As already noted, the stylesheet determines if the element is applied. In the following example, the element is 'usc_profile.xsl'.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="../../../lang/en-us/style0/usc_profile.xsl" type="text/xsl"?>
<Oblix xmlns:oblix="http://www.oblix.com/" xmlns="http://www.oblix.com/" oblang="en-us">
<ObProfile>
<ObTextMessage>
Hello, World!
</ObTextMessage>
<ObPanel obname="defaultPanel" obpanelId="20040401T22135679142" obpanelClass="gensiteorgperson">
<ObAttribute obattrName="genUserID">
<ObDisplay obdisplayName="UID" obdisplayType="textS" obsemanticType="ObSLogin" obname="genUserID" obmode="view" obcanRequest="false" obrequired="false">
<ObTextS>
<ObValue>Admin</ObValue>
</ObTextS>
</ObDisplay>
</ObAttribute>
<ObAttribute obattrName="sn">
<ObDisplay obdisplayName="Last Name:" obdisplayType="textS" obname="sn" obmode="view" obcanRequest="false" obrequired="false">
<ObTextS>
<ObValue>dmÔn</ObValue>
</ObTextS>
</ObDisplay>
</ObAttribute>
<ObAttribute obattrName="cn">
<ObDisplay obdisplayName="Name" obdisplayType="textS" obname="cn" obmode="view" obcanRequest="false" obrequired="false">
<ObTextS>
<ObValue>Master dmÔn</ObValue>
</ObTextS>
</ObDisplay>
</ObAttribute>
</ObPanel>
<ObPanel obname="miisPanel" obpanelId="20040406T10492776123" obpanelClass="gensiteorgperson">
<ObAttribute obattrName="cn.person.miis">
<ObDisplay obdisplayName="MIIS Name" obdisplayType="textS" obname="cn.person.miis" obmode="view" obcanRequest="false" obrequired="false">
<ObTextS></ObTextS>
</ObDisplay>
</ObAttribute>
<ObAttribute obattrName="userSMIMECertificate.person.miis">
<ObDisplay obdisplayName="MIIS Password" obdisplayType="password" obsemanticType="ObSPassword" obname="userSMIMECertificate.person.miis" obmode="view" obcanRequest="false" obrequired="false">
<ObPassword oboldpsw="false"></ObPassword>
</ObDisplay>
</ObAttribute>
</ObPanel>
<ObHeaderPanel>
<ObAttribute obattrName="cn">
<ObDisplay obdisplayName="Name" obdisplayType="textS" obname="cn" obmode="view" obcanRequest="false" obrequired="false">
<ObTextS>
<ObValue>Master dmÔn</ObValue>
</ObTextS>
</ObDisplay>
</ObAttribute>
</ObHeaderPanel>
<ObRequestInfo>210498888</ObRequestInfo>
<ObScripts>
<ObScript obname="../../../lang/en-us/msgctlg.js"></ObScript>
<ObScript obname="../../../lang/shared/i18n.js"></ObScript>
<ObScript obname="../../../lang/shared/nsiesetup.js"></ObScript>
<ObScript obname="../../../lang/shared/misc.js"></ObScript>
<ObScript obname="../../../lang/shared/miscsc.js"></ObScript>
<ObScript obname="../../../lang/shared/horizontalprofile.js"></ObScript>
<ObScript obname="../../../lang/shared/userservcenter.js"></ObScript>
</ObScripts>
<ObForm obname="profileForm" obmethod="post" obaction="userservcenter.cgi?tab_id=Employees&amp;uid=cn%3DMaster%20%C5dm%EFn%2Co%3DCompany%2Cc%3DUS">
<ObInput obtype="hidden" obname="program" obvalue="view"></ObInput>
<ObInput obtype="hidden" obname="visiblePanel"></ObInput>
</ObForm>
<ObDisplay obdisplayName="ObTextMessage" obdisplayType="textS" obname="ObTextMessage" obmode="view" obcanRequest="false" obrequired="false">
<ObTextS>
<ObTextMessage></ObTextMessage>
</ObTextS>
</ObDisplay>
<ObTextMessage></ObTextMessage>
<ObSelectorInfoForm>
<ObForm obname=""></ObForm>
</ObSelectorInfoForm>
<ObButton obaction="initiateDeactivateUser"></ObButton>
<ObButton obaction="userreactivate"></ObButton>
<ObButton obaction="wfTicketDelete"></ObButton>
<ObButton obaction="userModify" obimageUrl="NAVmodify" obmouseOver="Modify this profile." obhref="../../userservcenter/bin/userservcenter.cgi?program=modify&amp;tab_id=Employees&amp;uid=cn%3DMaster%20%C5dm%EFn%2Co%3DCompany%2Cc%3DUS"></ObButton>
<ObStatus>0</ObStatus>
</ObProfile>
<ObNavbar obbgcolor="#669966">
<ObMisc>
<ObButton obaction="T1help" obimageUrl="T1help" obmouseOver="View Online Help" obhref="javascript:ObHelp('../../help/bin/help.cgi?program=helpProgram&amp;helpAppContext=userservcenter&amp;helpEventContext=view&amp;helpTOCContext=application');"></ObButton>
<ObButton obaction="T1about" obimageUrl="T1about" obmouseOver="Product Information and Feedback" obhref="userservcenter.cgi?program=aboutOblix&amp;tab_id=Employees"></ObButton>
<ObButton obaction="T1logout" obimageUrl="T1logout" obmouseOver="Logout" obhref="userservcenter.cgi?program=commonLogout&amp;sessionUid=20040407T14380285745"></ObButton>
</ObMisc>
<ObApps>
<ObApplication>
<ObButton obaction="userservcenter_application_info" obimageUrl="T1TABusermanager" obmouseOver="User Manager" obhref="../../userservcenter/bin/userservcenter.cgi" obanchorText="User Manager"></ObButton>
<ObTitle>
<ObButton obaction="T1TABusermanager"></ObButton>
</ObTitle>
<ObFunctions>
<ObButton obaction="MyProfile" obimageUrl="FTABmyidentity2" obmouseOver="View my profile." obhref="userservcenter.cgi?program=view&amp;uid=cn%3DMaster%20%C5dm%EFn%2Co%3DCompany%2Cc%3DUS&amp;tab_id=Employees"></ObButton>
<ObButton obaction="Report" obimageUrl="FTABreports" obmouseOver="Report Functions" obhref="userservcenter.cgi?program=mainReports&amp;appName=userservcenter&amp;tab_id=Employees"></ObButton>
<ObReportFunctions>
<ObButton obaction="generateReport" obimageUrl="2FTABgeneratereport" obmouseOver="Generate a report" obhref="javascript:QueryBuilder('../../querybuilder/bin/querybuilder.cgi?program=modifyFilter&amp;tab_id=Employees&amp;appName=userservcenter&amp;uid=cn%'+'3DMaster%'+'20%'+'C5dm%'+'EFn%'+'2Co%'+'3DCompany%'+'2Cc%'+'3DUS&amp;advModeDisable=true&amp;slapTab=true','','..%'+'2F..%'+'2Fuserservcenter%'+'2Fbin%'+'2Fuserservcenter.cgi%'+'3Fprogram%'+'3DshowReportsResults%'+'26appName%'+'3Duserservcenter%'+'26tab_id%'+'3DEmployees%'+'26fromQB%'+'3Dtrue','')"></ObButton>
<ObButton obaction="viewPredefinedReports" obimageUrl="2FTABviewpredefinedreports" obmouseOver="View predefined reports" obhref="userservcenter.cgi?program=predefinedReports&amp;appName=userservcenter&amp;tab_id=Employees"></ObButton>
</ObReportFunctions>
<ObButton obaction="wfCreateProfile" obimageUrl="FTABcreateuseridentity" obmouseOver="Create New User" obhref="userservcenter.cgi?program=workflowCreateProfile&amp;tab_id=Employees"></ObButton>
<ObButton obaction="wfDeactivateProfile" obimageUrl="FTABdeactivateuseridentity" obmouseOver="Search on Deactivated Persons." obhref="userservcenter.cgi?program=workflowDeactivatedUserSearchResults&amp;tab_id=Employees"></ObButton>
<ObButton obaction="adminProxy" obimageUrl="FTABsubstituterights" obmouseOver="Configure Proxy Administration" obhref="userservcenter.cgi?program=proxyAdmin&amp;tab_id=Employees"></ObButton>
<ObButton obaction="Workflow" obimageUrl="FTABrequests" obmouseOver="Workflow Functions" obhref="userservcenter.cgi?program=workflowMain&amp;tab_id=Employees"></ObButton>
<ObWorkflowFunctions>
<ObButton obaction="wfIncomingRequest" obimageUrl="2FTABincomingrequests" obmouseOver="Incoming Request" obhref="../../userservcenter/bin/userservcenter.cgi?program=workflowTicketSearchForm&amp;tab_id=Employees&amp;requestType=incomingRequests"></ObButton>
<ObButton obaction="wfOutgoingRequest" obimageUrl="2FTABoutgoingrequests" obmouseOver="Outgoing Request" obhref="../../userservcenter/bin/userservcenter.cgi?program=workflowTicketSearchForm&amp;tab_id=Employees&amp;requestType=outgoingRequests"></ObButton>
<ObButton obaction="wfMonitor" obimageUrl="2FTABmonitorrequests" obmouseOver="Requests Monitor" obhref="../../userservcenter/bin/userservcenter.cgi?program=workflowMonitorSearchForm&amp;tab_id=Employees"></ObButton>
</ObWorkflowFunctions>
<ObButton obaction="Admin" obimageUrl="FTABconfiguration" obmouseOver="Administrative Functions" obhref="userservcenter.cgi?program=administrationMain&amp;tab_id=Employees"></ObButton>
<ObAdminFunctions>
<ObButton obaction="adminAccessControl" obimageUrl="2FTABattraccesscontrol" obmouseOver="Configure Attribute Access Control" obhref="javascript:DetectPluginForApplets('../../userservcenter/bin/userservcenter.cgi?program=mainAccessAdmin&amp;tab_id=Employees')"></ObButton>
<ObButton obaction="adminDelegate" obimageUrl="2FTABdelegateadmin" obmouseOver="Configure Delegated Administration" obhref="javascript:DetectPluginForApplets('../../userservcenter/bin/userservcenter.cgi?program=mainDelegateAdmin&amp;tab_id=Employees')"></ObButton>
<ObButton obaction="adminWorkflowDef" obimageUrl="2FTABworkflowdefinition" obmouseOver="Configure Workflow Definition" obhref="javascript:DetectPluginForApplets('../../userservcenter/bin/userservcenter.cgi?program=mainWorkflowAdmin&amp;tab_id=Employees')"></ObButton>
<ObButton obaction="adminSetSearchbase" obimageUrl="2FTABsetsearchbase" obmouseOver="Configure Localized Access" obhref="javascript:DetectPluginForApplets('../../userservcenter/bin/userservcenter.cgi?program=mainSetSearchbase&amp;tab_id=Employees')"></ObButton>
</ObAdminFunctions>
</ObFunctions>
</ObApplication>
<ObApplication>
<ObButton obaction="groupservcenter_application_info" obimageUrl="T1TABgroupmanager" obmouseOver="Group Manager" obhref="../../groupservcenter/bin/groupservcenter.cgi" obanchorText="Group Manager"></ObButton>
<ObTitle></ObTitle>
<ObFunctions></ObFunctions>
</ObApplication>
<ObApplication>
<ObButton obaction="objservcenter_application_info" obimageUrl="T1TABorgmanager" obmouseOver="Org. Manager" obhref="../../objservcenter/bin/objservcenter.cgi" obanchorText="Org. Manager"></ObButton>
<ObTitle></ObTitle>
<ObTabs></ObTabs>
<ObFunctions></ObFunctions>
</ObApplication>
<ObApplication>
<ObButton obaction="corpdir_application_info"></ObButton>
<ObTitle></ObTitle>
<ObTabs></ObTabs>
<ObFunctions></ObFunctions>
</ObApplication>
<ObApplication>
<ObButton obaction="dashline" obmouseOver="------------------------------------" obhref="userservcenter.cgi?"></ObButton>
</ObApplication>
<ObApplication>
<ObButton obaction="front_page_admin_application_info" obimageUrl="T1TABidentityadmin" obmouseOver="Identity System Console" obhref="../../admin/bin/front_page_admin.cgi" obanchorText="Identity System Console"></ObButton>
</ObApplication>
</ObApps>
<ObScripts>
<ObScript obname="../../../lang/en-us/msgctlg.js"></ObScript>
<ObScript obname="../../../lang/shared/i18n.js"></ObScript>
<ObScript obname="../../../lang/shared/misc.js"></ObScript>
<ObScript obname="../../../lang/shared/helpcommon.js"></ObScript>
<ObScript obname="../../../lang/shared/wf_qs.js"></ObScript>
</ObScripts>
<ObStatus>0</ObStatus>
<ObUserName>Master dmÔn</ObUserName>
</ObNavbar>
<ObSearchForm>
<ObSearchRow>
<ObDisplay obdisplayName="" obdisplayType="select" obname="STy1" obmode="modify" obrequired="true" obcardinality="singleValued" obcanRequest="false">
<ObSelect obmultiple="false">
<ObChoice obdisplayName="Last Name:" obselected="false">sn</ObChoice>
<ObChoice obdisplayName="MIIS Name" obselected="false">cn.person.miis</ObChoice>
<ObChoice obdisplayName="Name" obselected="true">cn</ObChoice>
<ObChoice obdisplayName="UID" obselected="false">genUserID</ObChoice>
</ObSelect>
</ObDisplay>
<ObDisplay obdisplayName="" obdisplayType="select" obname="SLk1" obmode="modify" obrequired="false" obcardinality="singleValued" obcanRequest="false">
<ObSelect obmultiple="false">
<ObChoice obdisplayName="That Contains" obselected="false">OOS</ObChoice>
<ObChoice obdisplayName="Contains In Order" obselected="false">OSM</ObChoice>
<ObChoice obdisplayName="=" obselected="false">OEM</ObChoice>
<ObChoice obdisplayName="&lt;=" obselected="false">OLE</ObChoice>
<ObChoice obdisplayName="&gt;=" obselected="false">OGE</ObChoice>
<ObChoice obdisplayName="That Begins With" obselected="false">OBW</ObChoice>
<ObChoice obdisplayName="That Ends With" obselected="false">OEW</ObChoice>
<ObChoice obdisplayName="That Sounds Like" obselected="false">OSL</ObChoice>
<ObChoice obdisplayName="!=" obselected="false">ONE</ObChoice>
</ObSelect>
</ObDisplay>
<ObDisplay obdisplayName="" obdisplayType="textS" obname="SSt1" obmode="modify" obrequired="false" obcardinality="singleValued" obcanRequest="false">
<ObDisplayProperties>
<ObDisplayProperty obname="onKeyDown" obvalue="javascript:checkSearchKey(event,this)"></ObDisplayProperty>
</ObDisplayProperties>
<ObTextS oblength="19"></ObTextS>
</ObDisplay>
</ObSearchRow>
<ObAdvancedSearch obadvancedSearchOn="false">
<ObDisplay obdisplayName="" obdisplayType="radio" obname="showAllResults" obmode="modify" obrequired="true" obcardinality="singleValued" obcanRequest="false">
<ObRadio>
<ObChoice obdisplayName="All" obselected="false">true</ObChoice>
<ObChoice obdisplayName="" obselected="true">false</ObChoice>
</ObRadio>
</ObDisplay>
<ObDisplay obdisplayName="" obdisplayType="textS" obname="noOfRecords" obmode="modify" obrequired="true" obcardinality="singleValued" obcanRequest="false">
<ObTextS oblength="2">
<ObValue>8</ObValue>
</ObTextS>
</ObDisplay>
</ObAdvancedSearch>
<ObRequestInfo>210498888</ObRequestInfo>
<ObScripts>
<ObScript obname="../../../lang/en-us/msgctlg.js"></ObScript>
<ObScript obname="../../../lang/shared/i18n.js"></ObScript>
<ObScript obname="../../../lang/shared/misc.js"></ObScript>
</ObScripts>
<ObForm obname="searchForm" obmethod="post" obaction="userservcenter.cgi?">
<ObInput obtype="hidden" obname="program" obvalue="search"></ObInput>
<ObInput obtype="hidden" obname="tab_id" obvalue="Employees"></ObInput>
<ObInput obtype="hidden" obname="startFrom" obvalue="0"></ObInput>
<ObInput obtype="hidden" obname="getPrevRecords" obvalue="false"></ObInput>
<ObInput obtype="hidden" obname="noOfFields" obvalue="1"></ObInput>
<ObInput obtype="hidden" obname="displayFormat" obvalue="2"></ObInput>
<ObInput obtype="hidden" obname="advSearch" obvalue="false"></ObInput>
<ObInput obtype="hidden" obname="searchStringMinimumLength" obvalue="3"></ObInput>
<ObInput obtype="hidden" obname="searchSameAttrAsOr" obvalue="false"></ObInput>
</ObForm>
<ObDisplay obdisplayName="ObTextMessage" obdisplayType="textS" obname="ObTextMessage" obmode="modify" obrequired="false" obcardinality="singleValued" obcanRequest="false">
<ObTextS>
<ObTextMessage></ObTextMessage>
</ObTextS>
</ObDisplay>
<ObSelectorInfoForm>
<ObForm obname=""></ObForm>
</ObSelectorInfoForm>
<ObButton obaction="searchGo" obimageUrl="SEARCHgo" obmouseOver="Start search." obhref="javascript:validateSearchAndSubmit('search')"></ObButton>
<ObButton obaction="searchAdvance" obimageUrl="SEARCHadvanced" obmouseOver="Advanced search." obhref="javascript:validateSearchAndSubmit('moreFields')"></ObButton>
<ObButton obaction="searchLess"></ObButton>
<ObButton obaction="searchMore" obimageUrl="SEARCHmore" obmouseOver="Get more fields." obhref="javascript:validateSearchAndSubmit('moreFields')"></ObButton>
<ObButton obaction="searchAll" obimageUrl="SEARCHall" obmouseOver="All fields." obhref="javascript:validateSearchAndSubmit('allFields')"></ObButton>
<ObStatus>0</ObStatus>
</ObSearchForm>
<ObStatus>0</ObStatus>
</Oblix>

3.5.5 Development Environment

The Identity Event Plug-in API consists of a set of header files that you can use to build your LIB actions, source code examples for working with LIB, MANAGEDLIB, and EXEC actions, source code examples for creating an XML parser, and a default obpppcatalog.lst file with extensive examples of action configuration entries. On Windows platforms, an import library is also provided, which you will need to build your LIB actions. All of these files are bundled in the standard Identity System installation; there is nothing else to install in order to develop actions.

For managed code, plug-in writers need to compile and link with pppInterface.dll, which contains the IPPPData interface. This assembly is located at

install_dir/oblix/include/managed/pppinterface.dll

This path will need to be referenced as a "Resolve #using Reference" in Visual Studio, or through the /AI compiler option when compiling and linking the plug-in. At runtime, both the Identity Server and the plug-in will need to locate pppInterface.dll. For this reason, pppInterface.dll is installed in the Global Assembly Cache (GAC) during installation of the Identity Server. Alternatively, if plug-in writers wish to test their plug-in on a machine where the Identity System has not been installed, pppInterface.dll can be privately deployed. This means placing the assembly in the plug-in's bin directory. It is important to compile and link with the same version of pppInterface.dll that will be used at runtime (either through the GAC or through private deployment). Otherwise, an exception may be thrown by the Common Language Runtime (CLR).

The files you need to be familiar with in order to develop custom actions are described in the following tables:

3.5.5.1 Library Files for LIB and EXEC Actions

Directory:

$Identity_install_Dir/oblix/lib

File Name Description
ppp.lib (Windows platforms only.) An export library you need to link your LIB action DLL to in order to resolve references to Identity System-provided symbols.

Directory:

$Identity_install_Dir/oblix/include/ppp

File Name Description
obppp.h Defines the basic success/failure status return codes used by the API functions. Declares the ObActionFunc function signature that you must use to declare your LIB action functions.
obpppdata.h Defines the ObPPPData C++ class that you must use to transmit data between the Identity System and your LIB action.
obpppwf.h Defines constants used for developing actions that work with the Identity System's workflow functionality.

3.5.5.2 Library Files for MANAGEDLIB Actions

The pppInterface.dll is located as follows:

$Identity_install_dir\identity\oblix\include\managed\

This is the dll with which plug-ins compile and link.

File Name Description
pppInterface.dll (Windows platforms only.) The DSO for MANAGEDLIB actions.

3.5.5.3 LIB Action Example Files

These are examples only, not part of the product. See the \unsupported branch of the Identity System directory tree. Directory:

Identity_install_dir/oblix/unsupported/ppp/ppp_dll

File Name Description
libppp_dll.so Solaris UNIX platforms only. This is a dynamic shared object (DSO) that is pre-built from source files present in this example directory. You provide a path to this DSO as part of the entry for a lib action in the oblixpppcatalog.lst file, specifying the name of one of the action functions within the DLL, as defined in pppdlltest.cpp.

You must also include the path to the libppp_dll.so DSO in the shared library search path. The preferred method for doing this is to use the -L option of the ld command. Another way is to use the LD_LIBRARY_PATH environment variable, which can be set to give the run-time shared library loader (ld) an extra set of directories to look for when it searches for DSOs.

ppp_dll.dll Windows platforms only. This is a dynamic link library (DLL) pre-built from source files in this example directory. You provide a path to this DLL as part of the entry for a lib action in the oblixpppcatalog.lst file, specifying the name of one of the action functions within the DLL, as defined in pppdlltest.cpp.
ppp_dll.sln Windows platforms only. A Microsoft Visual C++ project file you can use to build ppp_dll.dll yourself.
pppdlltest.cpp The C++ source file for the Oracle-provided LIB action examples.
ppputil.cpp Provides:

A C++ class that illustrates how to access the Identity System data available to actions through the API. The example simply writes the data out to the file system.

A C function, MakePayload, that illustrates how to compose an XML SOAP message to request a group subscription for a user.

ppputil.h Class and function declarations for ppputil.cpp.
nis_client.cpp Provides a C++ class that implements an HTTP client capable of sending messages to the Identity System using WebPass. By combining this with the MakePayload function mentioned under ppputil.cpp, your action can use the IdentityXML or AccessXML interfaces to make requests of the Identity System. This example may be particularly useful for Cross Application Support. See "Cross-Application Support".
nis_client.h Class and function declarations for nisclient.cpp.

Tip: If you are using the ConfigurationStructure class provided in nis_client.h, it does not get called when either nis_client.h has the declaration of a class ConfigurationStructure or the same class has been used in some other functionality.

When the Identity server starts, the ConfigurationStructure class is loaded before the ConfigurationStructure class that is present in the PPP plug-in. Solaris always calls the constructor of the ConfigurationStructure class, while the constructor of the ConfigurationStructure class in the PPP plug-in's nis_client.cpp file never gets called.Suggestion: Build libppp_dll.so using -Wl,-B,symbolic option so that Solarisv will bind symbols at compile time only.

makefile Solaris, UNIX platforms only. This is the UNIX make file used to create libppp_dll.s.

3.5.5.4 MANAGEDLIB Action Example Files

Directory:

Identity_install_dir\unsupported\ppp\dotnet\managedcplusplus\Release

File Name Description
managedcplusplus.cpp (Windows platforms only.) The MC++ source file for the Oracle-provided MANAGEDLIB action examples.
managedcplusplus.h (Windows platforms only.) The header file for managedcplusplus.cpp. It defines a singleton class that contains methods specified as Identity Event API actions.
managedcplusplus.sln (Windows platforms only.) A Microsoft Visual C++ managed code project file that you can use to build managedcplusplus.dll.
managedcplusplus.vcproj (Windows platforms only.) A Microsoft Visual C++ managed code project file that contains the necessary configuration to build the project.
managedcplusplus.dll The sample plug-in.
pppfilewriter.cpp (Windows platforms only.) A utility class that receives Identity System data and writes the data to a file.
pppfilewriter.h (Windows platforms only.) The header file for pppfilewriter.cpp.

3.5.5.5 EXEC Action Example Files

Directory:

Identity_install_dir/oblix/unsupported/ppp/ppp_exec

File Name Description
ppp_exec_test. java This is the source for a JAVA version of an Oracle-provided EXEC action example for post-processing. You can refer to this program as an EXEC action in the oblixpppcatalog.lst file.
ppp_exec.exe (Windows platforms only.) This is an NT executable, pre-built from the file pppexectest.cpp to make that example available to you. You can refer to this program as an EXEC action in the oblixpppcatalog.lst file.
ppp_exec.sln (Windows platforms only.) A Microsoft Visual C++ project file you can use to build ppp_exec.exe yourself.
pppexectest.cpp The C++ source file for an Oracle-provided EXEC action example.
ppp_perl.pl This is the source for a PERL version of an Oracle-provided EXEC action example for post-processing. You can refer to this program as an EXEC action in the oblixpppcatalog.lst file.
ppp_string.cpp A C++ class representing strings used by pppexectest.cpp.
ppp_string.h Class declaration for ppp_string.cpp.
corpdir_view_pre.xml A pre-formatted XML message for the example to send to the Identity System when invoked as a preprocessing step. See the pppexectest.cpp example.

3.5.5.6 Parser Example Files

Directory:

Identity_install_dir/oblix/unsupported/ppp/parser_test

File Name Description
MyPPPActions.cpp The C++ source file that builds a function called SAXParserPostActionTest, to be loaded as part of a DSO called MYPPPActions.dll. The file also provides Windows and UNIX examples of the Catalog entry that connects the action to the view post-processing event in the Profile page of the User Manager. The function replaces the phone numbers of corporate users with the pattern XXX-XXX-XXXX.
MyPPPActions.dll This is the dynamic link library (DLL) pre-built from source files in this example directory.
MyPPPAction.sln (Windows platforms only.) A Microsoft Visual C++ project file you can use to build MyPPPActions.
MySAXhandler.cpp The C++ source file that builds the SAXhandler class of methods that does the actual interpretation of the XML. SAX stands for Simple API for XML.
MySAXhandler.hpp The header file defining the methods belonging to the SAXhandler class.

Note:

The examples are provided for illustrative purposes only. To emphasize that they are not part of the formal product, they are installed in the unsupported branch of the Oracle Access Manager directory tree.

3.6 Cross-Application Support

Standard workflows exist within specific applications, such as the User Manager and Group Manager, and their direct effects are limited to the application in which they exist. Situations may arise in which you want a workflow to make changes that affect more than one Manager application. An example is the need to create a new user and also subscribe that user to a Group.

This is accomplished by including an event in the workflow, which triggers an action that gets information from the workflow, and uses IdentityXML syntax to send a request to the other application to accomplish the task. The flow might be something like this:

The event entry in the Catalog to implement this might be the following:

63f004504f83455b924133acd0ef2e87_3_postaction;
lib;;../../../unsupported/ppp/ppp_dll/ppp_dll.dll;
NISClient;

It takes the same form as any other Workflow event. The behavior difference lies in the NISClient function, which performs all the duties described in the previous list. You will find the example code for the NISClient function in the file pppdlltest.cpp, with supporting methods in nis_client.cpp, both in the directory

Identity_install_dir/oblix/unsupported/ppp/ppp_dll

The example conf.txt file is located in:

Identity_install_dir/oblix/unsupported/ppp/ppp_dll

If you use it, you will need to change the content to match your situation, and move it to where the dll expects to find it:

Identity_install_dir/oblix/apps/common/bin

Note:

There may be timing delays involved when you use a Cross Application plug-in. For example, if you are using replicated directories it will take time for information written to a first directory to be duplicated to a second. Your plug-in should allow for this time difference before trying to use data from the second directory.

3.7 Examples

The following are examples of the Identity Event Plug-in API in use:

3.7.1 A LIB Action Example—LogActivation

In this example, we will examine a C function that implements logging for both activation and deactivation of users in the Identity System. Notice that the same action function is registered in the Catalog for two different events. The event name is passed to the action, so it can differentiate between events that are handled in similar ways.

In the example, the log is written to the file system. A more sophisticated implementation might connect directly to a relational database to collect statistics like this for later processing by external enterprise applications. You should resist the urge to do too much in an action, however. Time spent in an action is time added to the of the HTTP request latency perceived by the user, in this case a Delegated Identity Administrator.

The following code implements this feature, packaged as a LIB action:

#include <ppp/obppp.h>
#include <ppp/obpppwf.h>
#include <ppp/obpppdata.h>
 
extern "C" {
 
/**
* LogActivation
* This action logs user activation and deactivation
* events.
* @param eventName The name of the event that
* triggered this action.
* This example processes both activation and
* deactivation, and uses this parameter to
* tell the difference.
* @param data the data for this event.
* (re: include/ppp/obpppdata.h)
* @return STATUS_PPP_OK or STATUS_PPP_ABORT
**/
 
unsigned int
LogActivation(const char *eventName, ObPPPData *data)
{
// Event names (must match those used in catalog)
const char *ACTIVATE_EVENT =
"userservcenter_workflowActivateSave_pre";
const char *DEACTIVATE_EVENT =
"userservcenter_workflowDeactivateUserSave_pre";
// open our file
FILE *file = fopen("activation_log.txt", "a");
// Determine whether action is being called to log
// an activate or deactivate user event.
bool activate;
if (0 == strcmp(eventName, ACTIVATE_EVENT)) {
activate = true;
} else if (0 == strcmp(eventName, DEACTIVATE_EVENT)) {
activate = false;
} else {
// error - can't process other events
data->SetResultString("PPP action misconfigured");
fclose(file);
return STATUS_PPP_ABORT;
}
 
const char **uid = (const char **)data->Get("uid");
if (NULL == *uid) {
data->SetResultString("PPP action error");
fclose(file);
return STATUS_PPP_ABORT;
data->SetResultString("PPP action error");
fclose(file);
return STATUS_PPP_ABORT;
}
// Write the log entry
fprintf(file, "%s: %s\n",
activate ? "activated" : "deactivated",
*uid);
fclose(file);
return STATUS_PPP_OK;
}

For reference in the following description, here is how this action can be configured in oblixpppcatalog.lst on a UNIX system:

userservcenter_workflowActivateSave_pre;lib;;/var/opt/netpoint/plug-ins/liblogactions.so;LogActivation;

userservcenter_workflowDeactivateUserSave_pre;lib;;/var/opt/netpoint/plug-ins/liblogactions.so;LogActivation;

The LogActivation LIB action begins by including the Identity Event Plug-in API header files, as all LIB actions must do in order to have access to Identity System data.

Notice that the LogActivation is declared within an extern C block to tell the C++ compiler that it is code written in C with external C linkage.

Next is the function signature for the action:

unsigned int
LogActivation(const char *eventName, ObPPPData *data)

This code declares LogActivation as a function with the same return type and parameter list as an ObActionFunc, as described in obppp.h. The Identity System requires that all LIB actions conform to this type.

LogActivation then declares constants for ACTIVATE_EVENT and DEACTIVATE_EVENT. The values of these constants reflect the events that this action will respond to, and must match the stylized event names used in the Catalog, as shown in the preceding code listing.

Next, a file is opened for append using fopen(). This is the log file for the example. It resides in the current working directory of the Identity System, which is the identity/oblix/apps/common/bin directory. In this example, there are just two possible types of entry in the log file:

  • activated: <user dn>

  • deactivated: <user dn>

LogActivation next inspects the name of the event for which it is being invoked, and sets an activate/deactivate flag. Then it looks up the DN of the user using the Get method of ObPPPData, to fetch the value of the uid parameter. The value of this parameter for this event is the directory DN of the user who is being activated or deactivated.

Note:

Notice that the action demonstrates communicating an error to User Manager by setting the return status to STATUS_PPP_ABORT if it is called for an unexpected event, or if it fails to find the expected data in the ObPPPData object.

The action completes its task by writing its log message, closing the log file and returning the success status, STATUS_PPP_OK to User Manager.

3.7.2 An EXEC Action Example—AfterHours

This example implements an after-hours lockout function using a post-processing EXEC action. The intent is that a site may have a policy of disallowing certain types of activity during certain hours of the day, to allow a safe environment for backups and other system maintenance. This action might be one tool in the administrator's toolbox for enforcing such a policy.

Here is the source code for the AfterHours action:

#include <time.h>
#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <stdlib.h>
#include <ppp/obppp.h>
int main(int argc, char* argv[])
{
// XML template for text message
static const char *messageTemplate =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n \
<?xml-stylesheet href=\"../../common/ui/style0/ppp.xsl\"
type=\"text/xsl\"?>\n \
<Oblix xmlns=\"http://www.oblix.com/\">\n \
<ObTextMessage>\n \
%s\n \
</ObTextMessage>\n \
</Oblix>\n";
 
static const char *message;
 
if (argc > 1 && argv[1] != 0 && stricmp(argv[1], "pre")
== 0) {
// PRE-processing requests are not supported
return(STATUS_PPP_ABORT);
} else {
// POST-processing
// Examine command-line for any EXEC arguments
if (argc > 1 && argv[1] != 0) {
const long now = time(0);
struct tm* tmNow = localtime(&now);
int hrsNow = tmNow->tm_hour;
int minNow = tmNow->tm_min;
int hrsOff = atoi(argv[2]);
int minOff = atoi(argv[3]);
int hrsOn = atoi(argv[4]);
int minOn = atoi(argv[5]);
int timeOff = (60 * hrsOff) + minOff;
int timeOn = (60 * hrsOn) + minOn;
int timeNow = (60 * hrsNow) + minNow;
if (timeOn < timeOff) timeOn += (60*24);
if (timeOn != timeOff && timeNow >= timeOff &&
timeNow < timeOn) {
// Disallow the event; send ObTextMessage using
// text in catalog
message = argv[1];
} else {
// Allow the event. As a convenience, Identity
// applications assume actions haven't modified
// the data if they don't write to stdout. So
// all you need to do here is return status.
return STATUS_PPP_OK;
}
} else {
// No arguments. Output a default disablement message.
message = "This operation is disabled by the POST-processing action.";
}
// If we get here, we're replacing the data with
// the ObTextMessage.
fprintf(stdout, messageTemplate, message);
fflush(stdout);
return(STATUS_PPP_OK);
}
}
Here is a sample Catalog entry to configure the AfterHours action on a Windows server.
userservcenter_view_post;exec;;C:\NetPoint\Identity\Actions\AfterHours.exe;"This Operation is unavailable outside business hours. Please contact your Identity administrator for details." 21 30 06 00;

The first field associates the action with the User Manager view post-processing event. The second field is empty (no Identity System parameters). The third field indicates that this is an EXEC action. The fourth field is the path to the executable that implements the AfterHours action. The remaining fields are EXEC action parameters, and they are supplied to the action as argv[1] through argv[5]. Notice that the text message parameter must be quoted because it contains spaces. The last four parameters indicate that the OFF hours are 21:30 (9.30pm) till 06:00 (6.00am).

Note:

This illustrates the use of action parameters. Parameters are only available to EXEC actions, not LIB actions. A LIB action that implemented the after-hours lockout feature would have to look up its OFF and ON hours, and the text message to be displayed from an external source. Doing so would provide the opportunity for greater sophistication: just like a home-security time switch, an administrator may want more than one OFF period a day, or may want a different schedule on weekends. Knowing the requirements will help you to design your action interface, and help you decide whether a LIB or EXEC action is called for.

The AfterHours action begins by declaring a string containing the XML document that is used to return a text message to the browser if the event is currently disabled. Notice the %s embedded in the string. The string is used as a template to fprintf; the %s is a printf directive and is replaced by the actual message.

Next, the action rejects attempts to call it from a pre-processing event. It does not support pre-processing because it cannot usefully replace the XML result of the request until it has been generated, which is not until after pre-processing.

AfterHours then performs some time calculations. To do this, it checks the system time and extracts the current hour and minute, then converts it to minutes alone. It then examines its command-line arguments, and extracts the Catalog-supplied message, the OFF hours and minutes, and the ON hours and minutes, as argv[1] through argv[5], in that order.

Again, times are converted to minutes. If the ON time is earlier than the OFF time, the ON time falls within the next day, so 24 hours (24 * 60 minutes) are added to the ON time. If ON and OFF times are the same, AfterHours enables the request. If the time now falls between the OFF and ON times, AfterHours selects argv[1] for output in the message template. If the time now falls outside that period, AfterHours simply returns STATUS_PPP_OK to indicate that the event may proceed.

If the event is to be disallowed, this is achieved by combining the message template with the selected message in a call to fprintf, sending output to STDOUT. The action returns STATUS_PPP_OK to allow the event to proceed. User Manager applies the stylesheet ppp.xsl, which is part of the Identity System, and the resulting page containing the text message is returned to the browser.

3.7.3 A MANAGEDLIB Action Example

The following is a sample header file that declares class EventAPI.

// managed_ppp.h
 
#ifndef __managed_ppp__
#define __managed_ppp__
 
#using <mscorlib.dll>
#using <pppinterface.dll>
#using <System.dll>
#using <System.Xml.dll>
 
using namespace System;
using namespace System::Text;
using namespace System::Collections;
using namespace System::Xml;
using namespace System::Net;
using namespace System::IO;
using namespace Oblix::Identity::CoreID;
 
/* Singleton class that contains methods specified as Identity Event API actions.
The Identity System will instantiate one EventAPI object, which will be shared among threads.
Class members must be accessed in a thread-safe manner. Modification of data members must be synchronized.
 
The class must be named EventAPI and must define a constructor and destructor
*/
 
public __gc class EventAPI {
 
public:
/* ctor, initialize class members here */
EventAPI( );
/* dtor, release resources here */
virtual ~EventAPI( );
 
/* action methods */
IPPPData::STATUS_PPP_M PreProcessingTest( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M PostProcessingTest( String * eventName , IPPPData * data );
IPPPData::STATUS_PPP_M PostProcessingTest_Phone( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M SavePreProcessing( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M WorkflowPreActionTest( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M WorkflowPostActionTest( String * eventName , IPPPData * data );
IPPPData::STATUS_PPP_M WorkflowPostActionPasswordTest( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M WorkflowExtActionTest( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M WorkflowSubflowActionTest( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M PasswordTest( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M WorkflowRetryTest( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M NISClient( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M ProcessCPResponseEncryption( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M USCOnChange( String * eventName, IPPPData * data );
IPPPData::STATUS_PPP_M NavigationTest( String * eventName, IPPPData * data );
 
private:
String * MakePayload( IPPPData * data, String * login, String * password, String * group , String * user );
};
 
 
public __gc class XMLUtil {
public:
static String * XMLUtil::knewline = S"\n";
static String * XMLUtil::kSpace = S" ";
static String * XMLUtil::kCloseAngle = S">";
static String * XMLUtil::kProcessingInst = S"<?xml version=\"1.0\"?>";
static String * XMLUtil::kSoapEnvEnvelopeStart = S"<SOAP-ENV:Envelope";
static String * XMLUtil::kSoapEnvEnvelopeEnd = S"</SOAP-ENV:Envelope>";
static String * XMLUtil::kxmlns = S"xmlns:oblix=\"http://www.oblix.com\" xmlns:SOAP-ENV=\"http://schemas-xmlsoap.org/soap/envelope/\"";
static String * XMLUtil::kSoapEnvBodyStart = S"<SOAP-ENV:Body>";
static String * XMLUtil::kSoapEnvBodyEnd = S"</SOAP-ENV:Body>";
static String * XMLUtil::kOblixAuthStart = S"<oblix:authentication ";
static String * XMLUtil::kOblixAuthEnd = S"</oblix:authentication>";
static String * XMLUtil::kTypeBasic = S"type=\"basic\"";
static String * XMLUtil::kObLoginStart = S"<oblix:login>";
static String * XMLUtil::kObLoginEnd = S"</oblix:login>";
static String * XMLUtil::kObPasswordStart = S"<oblix:password>";
static String * XMLUtil::kObPasswordEnd = S"</oblix:password>";
static String * XMLUtil::kObReqStart = S"<oblix:request";
static String * XMLUtil::kObReqEnd = S"</oblix:request>";
static String * XMLUtil::kApp = S"application=\"groupservcenter\"";
static String * XMLUtil::kfuncname = S"function=\"subscribeUserToGroup\"";
static String * XMLUtil::kObParamsStart = S"<oblix:params>";
static String * XMLUtil::kObParamsEnd = S"</oblix:params>";
static String * XMLUtil::kObParamStart = S"<oblix:param";
static String * XMLUtil::kObParamEnd = S"</oblix:param>";
static String * XMLUtil::kNameEqproxysourceuid = S"name=\"proxysourceuid\"";
static String * XMLUtil::kNameEquid = S"name=\"uid\"";
 
};
 
#endif

There are several "action" methods in the class. The directive

#using <pppinterface.dll>

indicates that the plug-in will be using date types from pppInterface.dll, namely the IPPPDate interface as well as the status codes. Initialization code should be placed in the constructor, EventAPI(), and clean-up code should be placed in the destructor ~EventAPI().

The sample plug-in also uses data types from the System.Xml library, as indicated by the directive

#using<System.Xml.dll>

The method EventAPI::NISClient is an example of how to send a SOAP request using classes from System.Xml, which is part of the .NET framework SDK. The method subscribes the target user to a group. The target user is obtained through IPPPDate::Get, while other parameters, including the group to which to subscribe the user, are obtained from a configuration file, params.xml.

The method uses these parameters to construct the SOAP request with the method EventAPI::MakePayLoad (not listed here, but it is in the sample code). It then creates an http request with the URI parameter using HttpWebRequest. It then gets a stream from that request and writes the SOAP request (IdentityXML/subscribeUserToGroup) to the stream. Afterwards, the method gets a response from the request.

IPPPData::STATUS_PPP_M
EventAPI::NISClient( String * eventName, IPPPData * data )
{
IPPPData::STATUS_PPP_M retStatus = IPPPData::STATUS_PPP_M::STATUS_PPP_OK;
 
try {
String * sUidParamName = S"proxysourceuid";
String * sGroupDNParamName = S"uid";
String * uri, * login, * password, * group, * user;
String * errMsg = S"Missing Parameter";
 
String * targets[] = data->Get( S"WfInstance.obtargetdn" );
user = targets[0];
XmlDocument& doc = *new XmlDocument;
doc.Load( S"params.xml" );
XmlNode * root = doc.FirstChild;
XmlElement * elem;
elem = root->get_Item( S"uri" );
if( elem != NULL ) { uri = elem->InnerText; } else { throw new Exception( errMsg ); }
elem = root->get_Item( S"login" );
if( elem != NULL ) { login = elem->InnerText; } else { throw new Exception( errMsg ); }
elem = root->get_Item( S"password" );
if( elem != NULL ) { password = elem->InnerText; } else { throw new Exception( errMsg ); }
elem = root->get_Item( S"group" );
if( elem != NULL ) { group = elem->InnerText; } else { throw new Exception( errMsg ); }
 
String * sPayLoad = MakePayload( data, login , password , group , user);
XmlDocument& soapReq = *new XmlDocument;
soapReq.LoadXml( sPayLoad );
 
HttpWebRequest * req = static_cast<HttpWebRequest*>( WebRequest::Create( uri ) );
req->ContentType = "text/xml;charset=\"utf-8\"";
req->Accept = "text/xml";
req->Method = "POST";
 
Stream * stm = req->GetRequestStream( );
soapReq.Save( stm );
stm->Close( );
 
WebResponse * resp = req->GetResponse( );
 
}
catch( Exception * e ) {
data->SetResultString( e->ToString( ) );
retStatus = IPPPData::STATUS_PPP_M::STATUS_PPP_ABORT;
}
 
return retStatus;
}
 
Parameter File:
 
params.xml
<Root>
<uri>http://sdelaney/identity/oblix/apps/groupservcenter/bin/groupservcenter.cgi</uri>
<login>admin</login>
<password>oblix</password>
<group>cn=Group of Employees10k1 with 1000 members, ou=Corporate, o=Company,c=US</group>
</Root>