Skip to content

Form Examples

This section contains examples of XML specifications for the various types of forms.

Application and Role Provisioning Policies and Workflow Forms can all be created through the user interface, though some advanced features might require XML editing to implement. All form types are recorded as XML objects that can be edited through the debug pages as needed. This section reviews the form types in their XML format and shows how they are rendered as a form in the user interface based on that XML definition.

Application and Role Provisioning Policy

Application provisioning policies are specified as <Form> within the <Application> definition. Role provisioning polices are <Form> within the <Bundle> definition. Applications might have more than one provisioning policy form -- one for (account) creation, update, and delete provisioning activities plus additional policies for group creation and update. Roles might only have one for role assignment to an Identity.

This sample <Form> definition provides examples of fields slotted into separate sections, assigned to different owners by value or by script, with an permitted values set, and with a validation script. Application provisioning policies are specified within a <Forms> element that wraps all of the specified provisioning policy forms together.

<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE Form PUBLIC "spt.dtd" "spt.dtd">
<Form name="New Acct Policy" type="Create">
  <Field displayName="Name" name="name" required="true" reviewRequired="true" type="string">
    <OwnerDefinition value="IIQApplicationOwner"/>
  </Field>
  <Field displayName="Phone" name="phone" required="true" section="Extra Info" type="string">
    <OwnerDefinition value="IIQApplicationOwner"/>
  </Field>
  <Field displayName="Office Number" name="off_no" required="true" section="" type="integer">
    <OwnerDefinition>
      <Script>
        <Source>return identity.getManager();</Source>
      </Script>
    </OwnerDefinition>
    <ValidationScript>
      <Source>
   try {
int number=Integer.parseInt(value);
if (number &lt; 100) {
return "Office numbers are all 100 or greater.";
} else{
return null;
}
} catch (NumberFormatException e) {
return "Non-numeric value provided; must be numeric.";
}
</Source>
    </ValidationScript>
  </Field>
  <Field displayName="Region" name="region" required="true" type="string">
    <AllowedValues>
      <String>Americas</String>
      <String>EMEA</String>
      <String>APAC</String>
    </AllowedValues>
  </Field>

Application Provisioning Policies can render on multiple forms, depending on the field Owners. Multiple provisioning policy forms can be combined into one form if a request spans multiple applications or roles that each need to gather additional data from the same user.

Identity Provisioning Policy

The XML below creates an identity provisioning policy which implements many of the available form options, including:

The form includes multiple field types (: string, object, and secret -. Secret hides enteredthe text). as it is entered. Object fields are rendered as dropdown list boxes prepopulated with all available items of that type.

  • Multi-column configurations

  • Multi-column spans for some fields

  • Allowed values lists

  • Tool tip help prompts

  • Field validation (runs when user clicks Submit)

  • Filter on object lists for example, show only Manager Identities in Manager drop down list

  • Conditional display of sections based on entered field values

  • Population of fields based on values entered in other fields

The form includes multiple field types: string, object and secret. Secret hides the text as it is entered. Object fields are rendered as dropdown list boxes prepopulated with all available items of that type.

     <?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Form PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Form name="Identity Create Policy" type="CreateIdentity">
  <Description>This is the provisioning policy used when creating a new identity thru LCM.</Description>
  <Section columns="2">
    <Field displayName="First Name" name="firstname" required="true" reviewRequired="true" type="string"/>
    <Field displayName="Last Name" name="lastname" postBack="true" required="true" type="string"/>
    <Field columnSpan="2" displayName="Username" dynamic="true" helpKey="cube name" name="name" required="true" type="string">
      <Script>
        <Source>
           if ((null != firstname) &amp;&amp; (null != lastname)) {
               return (firstname + "." + lastname);
           }
           return null;
        </Source>
      </Script>
      <ValidationScript>
        <Source>
            // validation variable comes in as "value"; messages value returned 
            // is displayed on screen below field on validation; success should return
            // empty messages list
            import sailpoint.tools.Message;     
            import sailpoint.object.Identity; 

            List messages = new ArrayList();

            Identity existing = (Identity)context.getObjectByName(Identity.class,value); 
            if (existing == null) { 
               // No Identity found with that name, so return empty messages -
               // validation successful
               return messages; 
            } else { 
               Message msg = new Message();
               msg.setKey("Username: " + value + " already exists. Modify this name to make it unique.");
               messages.add(msg);
               return messages;
            }
        </Source>
      </ValidationScript>
    </Field>
    <Field displayName="Password" name="password" reviewRequired="true" type="secret"/>
    <Field displayName="Password Confirmation" name="passwordConfirm" reviewRequired="true" type="secret"/>
    <Field displayName="Employment Type" displayType="combobox" name="status" postBack="true" type="string">
      <AllowedValues>
        <String>Employee</String>
        <String>Contractor</String>
      </AllowedValues>
    </Field>
  </Section>
  <Section label="Employee Only Fields">
    <Attributes>
      <Map>
        <entry key="hidden">
          <value>
            <Script>
              <Source>
                 if ("Employee".equals(status)) {
                     return false; 
                 } else {
                     return true;
                 }
                </Source>
            </Script>
          </value>
        </entry>
      </Map>
    </Attributes>
    <Field displayName="Manager" filterString="managerStatus == true" name="manager" type="sailpoint.object.Identity"/>
    <Field displayName="att_email" dynamic="true" name="email" reviewRequired="true" section="" type="string">
      <Script>
        <Source>
                if (("Employee".equals(status)) &amp;&amp; (null != firstname) &amp;&amp; (null != lastname)) {
                    return (firstname + "." + lastname + "@demoexample.com");
                }
                return null;
            </Source>
      </Script>
    </Field>
    <Field displayName="Location" name="location" reviewRequired="true" type="string" value="Austin">
      <AllowedValues>
        <String>Austin</String>
        <String>Brazil</String>
        <String>Munich</String>
        <String>London</String>
        <String>Brussels</String>
        <String>San Jose</String>
        <String>Chicago</String>
        <String>Taipei</String>
        <String>Tokyo</String>
      </AllowedValues>
    </Field>
  </Section>
</Form>

Workflow Form

This example XML creates a custom form that displays the Identity's name and asks the user to select a region to which the Identity should be assigned. It demonstrates use of an AllowedValuesDefinition and a ValidationScript as well as Sections of all three types, text, datatable, and default. This form is embedded in the Workflow XML, as it would be if the form were created through the Business Process Editor Add Form option. The form could alternatively be created as a standalone form object and referenced as an argument to the approval, as described in Workflow Forms.

<Step name="Need Region" posX="359" posY="182">
  <Approval name="Need Region" owner="ref:launcher" return="region" 
          send="identityName">
    <Arg name="workItemDescription" 
           value="string:Fill in Region for $(identityName)"/>
    <Form>
     <Attributes>
        <Map>
          <entry key="pageTitle" value="Get Region"/>
          <entry key="title" value="Need Region for Identity"/>
        </Map>
     </Attributes>
     <Button action="back" label="Abort"/>
     <Button action="next" label="Submit"/>
     <Button action="cancel" label="Return Item to Inbox"/>

     <Section name='userInstructions' type='text'>
        <Field value="Employees must be assigned to a region.  Please provide the correct region for this employee."
/>
     </Section>

     <Section type="datatable">
       <Field displayName="Employee Name" name="identityName"/>
     </Section>

     <Section name="Edit These Fields">
        <Field displayName="Region Value" name="region" required="true"  
          type="String">
         <AllowedValuesDefinition>
           <Script>
             <Source>
                  import java.util.ArrayList;
            import sailpoint.api.*;
            import sailpoint.object.*;

            List regions = new ArrayList();
            QueryOptions qo = new QueryOptions();

            qo.setDistinct(true);
            qo.addOrdering("region", true);

            List props = new ArrayList();
            props.add("region");

            Iterator result = context.search(Identity.class, qo, props);
            while (result.hasNext()) {
              Object [] record = result.next();
            String region= (String) record[0];
            regions.add(region);
            }
            return regions;
             </Source>
           </Script>
         </AllowedValuesDefinition>
         <ValidationScript>
             <Source>
            // validation variable comes in as "value"
              import sailpoint.tools.Message;
               List messages = new ArrayList();
               if(value.length() &lt; 6) {
                  Message msg = new Message();
                  msg.setKey("New region must be at least 6 characters.");
                  messages.add(msg);
               }
               return messages;

             </Source>
         </ValidationScript>
      </Field>
    </Section>
  </Form>
 </Approval>
</Step>

Report Forms

Report forms are used to display report-specific filters to the user in the Edit Report window. The form must be created as an independent Form object and referenced from the report definition in a <ReportForm> element.

At runtime, the form is combined with the Report Form Skeleton, which defines the Standard Properties and Report Layout pages. Each section named in the form is created as its own Report Properties page, displayed between the Standard Properties and Report Layout pages. The page name, shown in the Sections list and at the top of the form, is specified as the Section's label attribute.

   <Form name="Uncorrelated Accounts Report Custom Fields">
      <Section label="Uncorrelated Accounts Parameters" name="customProperties">
<Field displayName="report_input_correlated_apps" filterString="logical==false &amp;&amp;
authoritative==false" helpKey="rept_input_uncorrelated_ident_report_correlated_apps"
name="correlatedApps" type="Application" value="ref:correlatedApps"/>
      </Section>
    </Form>

An example of a simple report form is shown below. It contains only one section, formatted in two columns with several datatypes represented (dates, objects, and Boolean). The displayName and helpKey values on this report are localizable message keys. The values are all pulled from the TaskDefinition's input arguments, if any are provided there, to set the fields' default values.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Form PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Form created="1346776069392" id="4028460239921ba40139921bf510019a" modified="1346776080142"
name="Application Owner Access Review Report Form">
  <Section columns="2" label="rept_cert_custom_section_title" name="customProperties">
    <Field displayName="rept_cert_field_create_start" helpKey="rept_cert_help_create_start"
name="createStartDate" type="date" value="ref:createStartDate"/>
    <Field displayName="rept_cert_field_create_end" helpKey="rept_cert_help_create_end"
name="createEndDate" type="date" value="ref:createEndDate"/>
    <Field displayName="rept_cert_field_signed_start" helpKey="rept_cert_help_signed_start"
name="signedStartDate" type="date" value="ref:signedStartDate"/>
    <Field displayName="rept_cert_field_signed_end" helpKey="rept_cert_help_signed_end"
name="signedEndDate" type="date" value="ref:signedEndDate"/>
    <Field displayName="rept_cert_field_due_start" helpKey="rept_cert_help_due_start" name="dueStartDate"
type="date" value="ref:dueStartDate"/>
    <Field displayName="rept_cert_field_due_end" helpKey="rept_cert_help_due_end" name="dueEndDate"
type="date" value="ref:dueEndDate"/>
    <Field displayName="rept_cert_field_apps" helpKey="rept_cert_help_apps" multi="true"
name="applications" type="Application" value="ref:applications"/>
    <Field displayName="rept_cert_field_tags" helpKey="rept_cert_help_tags" multi="true" name="tags"
type="Tag" value="ref:tags"/>
    <Field displayName="rept_cert_field_cert_group" helpKey="rept_cert_help_cert_group" multi="true"
name="certificationGroups" type="CertificationGroup" value="ref:certificationGroups"/>
    <Field displayName="rept_cert_field_show_exclusions" helpKey="rept_cert_help_show_exclusions"
name="exclusions" type="boolean" value="ref:exclusions"/>
  </Section>
</Form>

This form is rendered as shown in the Report Properties section of the Edit Report window.

In report forms, sections can be created without Field definitions, allowing the report's taskDefinition's initialization rule/script to create the form fields. Several of the standard reports, for example, use an initialization rule to generate a pages of Application and/or Identity attribute filters based on the installation's system data, the defined standard and extended attributes, so the report forms themselves are defined with empty sections. The Privileged Access Report form provides an example of a dynamically built form.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Form PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Form created="1346776069392" id="4028460239921ba40139921bf510019a" modified="1346776080142"
name="Application Owner Access Review Report Form">
  <Section columns="2" label="rept_cert_custom_section_title" name="customProperties">
    <Field displayName="rept_cert_field_create_start" helpKey="rept_cert_help_create_start"
name="createStartDate" type="date" value="ref:createStartDate"/>
    <Field displayName="rept_cert_field_create_end" helpKey="rept_cert_help_create_end"
name="createEndDate" type="date" value="ref:createEndDate"/>
    <Field displayName="rept_cert_field_signed_start" helpKey="rept_cert_help_signed_start"
name="signedStartDate" type="date" value="ref:signedStartDate"/>
    <Field displayName="rept_cert_field_signed_end" helpKey="rept_cert_help_signed_end"
name="signedEndDate" type="date" value="ref:signedEndDate"/>
    <Field displayName="rept_cert_field_due_start" helpKey="rept_cert_help_due_start" name="dueStartDate"
type="date" value="ref:dueStartDate"/>
    <Field displayName="rept_cert_field_due_end" helpKey="rept_cert_help_due_end" name="dueEndDate"
type="date" value="ref:dueEndDate"/>
    <Field displayName="rept_cert_field_apps" helpKey="rept_cert_help_apps" multi="true"
name="applications" type="Application" value="ref:applications"/>
    <Field displayName="rept_cert_field_tags" helpKey="rept_cert_help_tags" multi="true" name="tags"
type="Tag" value="ref:tags"/>
    <Field displayName="rept_cert_field_cert_group" helpKey="rept_cert_help_cert_group" multi="true"
name="certificationGroups" type="CertificationGroup" value="ref:certificationGroups"/>
    <Field displayName="rept_cert_field_show_exclusions" helpKey="rept_cert_help_show_exclusions"
name="exclusions" type="boolean" value="ref:exclusions"/>
  </Section>
</Form>