How do we add multiple values in single field via form

Which IIQ version are you inquiring about?

8.4p1

Hi,
we have requirement to develop a quicklink in which we have field called Stewards . We need this field to add multiple users by creating dynamic workgroup . For now we created this field to add single user from drop down . Any sample code/documentation to create multiple users ?
Thanks!

Hi @Preethi

This is a great requirement for SailPoint IdentityIQ! You’re looking to enhance a Quicklink to allow multiple users to be selected as “Stewards” and then to dynamically create or manage a Workgroup based on these selections.

Core Concepts Involved:

  1. Quicklink Forms: Your quicklink will likely use a form (or be a form within a workflow) to capture user input.
  2. Multi-Select Field: You’ll need a form field that allows selecting multiple Identity objects (users). This is typically a Field with type="sailpoint.object.Identity" and multiSelect="true".
  3. Workgroups: SailPoint Workgroups are collections of Identities, often used for approvals, notifications, or managing access to IIQ features. They can be static or dynamic.
  4. Dynamic Workgroups (via Membership Rule): For your “Stewards” field, a dynamic Workgroup is often ideal. Instead of adding users one by one to a static Workgroup, you define a Membership Rule that programmatically determines who belongs to the Workgroup. This rule can read the values from your Quicklink field.
  5. Workflow: Quicklinks commonly trigger workflows. The workflow will contain the logic to:
  • Present the form.
  • Process the form submission (get the selected Stewards).
  • Create or update the dynamic Workgroup based on these Stewards.
  • Perform any other necessary actions (e.g., assigning the Workgroup as an owner).
  1. Rule for Dynamic Workgroup Membership: This rule will be attached to the Workgroup definition and will return a List<Identity> of the members.

Step-by-Step Implementation Outline:

1. Define Your Quicklink and Workflow

You’ll have a QuickLink object that points to a Workflow.

Example Quicklink XML (Quicklink.xml):

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE QuickLink PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<QuickLink action="workflow" category="Custom" messageKey="Quicklink_ManageStewards" name="ManageStewardsQuicklink">
  <Attributes>
    <Map>
      <entry key="workflowName" value="ManageStewardsWorkflow"/>
    </Map>
  </Attributes>
</QuickLink>

2. Design the Workflow

The workflow will handle the user interaction and the backend logic.

Example Workflow XML (ManageStewardsWorkflow.xml):

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Workflow PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Workflow explicitTransitions="true" name="ManageStewardsWorkflow">

  <Variable name="formInput" input="true"/>
  <Variable name="selectedStewards" type="java.util.List"/>
  <Variable name="workgroupName" type="string" initializer="MyDynamicStewardsWorkgroup"/> <Variable name="workgroup" type="sailpoint.object.Workgroup"/>

  <Step name="start" icon="Start">
    <Transition to="displayForm"/>
  </Step>

  <Step name="displayForm">
    <Form name="stewardSelectionForm" hidden="false">
      <Section label="Select Stewards">
        <Field name="stewards" type="sailpoint.object.Identity" multiSelect="true" required="true"
               filterString="type eq 'Identity' and name ne 'spadmin'"> <Prompt>Select Stewards</Prompt>
        </Field>
        </Section>
      <Button action="submit" label="Submit"/>
      <Button action="cancel" label="Cancel"/>
    </Form>
    <Transition to="processForm" on="submit"/>
    <Transition to="stop" on="cancel"/>
  </Step>

  <Step name="processForm">
    <Script>
      <Source>
        <![CDATA[
          // Get the selected stewards from the form input
          List selectedIdentities = formInput.get("stewards");
          workflow.put("selectedStewards", selectedIdentities);

          // Get the workgroup object
          String workgroupName = workflow.getString("workgroupName");
          Workgroup workgroup = context.getObjectByName(Workgroup.class, workgroupName);

          // If the workgroup doesn't exist, create it (adjust properties as needed)
          if (workgroup == null) {
              workgroup = new Workgroup();
              workgroup.setName(workgroupName);
              workgroup.setDisplayName(workgroupName);
              // Set description, owner, etc.
              context.save(workgroup);
              log.debug("Created new Workgroup: " + workgroupName);
          }
          workflow.put("workgroup", workgroup);

          // Now, set the membership rule for the workgroup
          // This rule will read the 'selectedStewards' list (if it's passed dynamically)
          // or a persistent attribute on the workgroup/other object.
          // For simplicity here, we'll assume the rule reads a 'stewardList' attribute
          // that we'll set on the workgroup.
          
          List stewardNames = new ArrayList();
          if (selectedIdentities != null) {
              for (Identity id : selectedIdentities) {
                  stewardNames.add(id.getName());
              }
          }
          // Store the list of steward names on the workgroup itself
          // This allows the Membership Rule to read it later.
          // This approach makes the workgroup truly dynamic based on the last form submission.
          workgroup.put("stewardNames", stewardNames); // Custom attribute on Workgroup
          workgroup.setMembershipRule("DynamicWorkgroupStewardsRule"); // Name of your rule
          context.save(workgroup);
          context.commitTransaction(); // Commit changes

          log.debug("Workgroup '" + workgroupName + "' updated with new stewards and rule set.");

        ]]>
      </Source>
    </Script>
    <Transition to="stop"/>
  </Step>

  <Step name="stop" icon="Stop"/>

</Workflow>

3. Create the Dynamic Workgroup Membership Rule

This rule will be associated with the Workgroup. It receives the Workgroup object itself as an argument and returns a List<Identity> of its members.

Example Rule XML (DynamicWorkgroupStewardsRule.xml):

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule name="DynamicWorkgroupStewardsRule" type="WorkgroupMembership">
  <Description>Defines the members of the dynamic stewards workgroup based on a list of identity names stored on the workgroup.</Description>
  <Source>
    <![CDATA[
      import sailpoint.object.Workgroup;
      import sailpoint.object.Identity;
      import sailpoint.api.SailPointContext;
      import java.util.List;
      import java.util.ArrayList;

      // The 'workgroup' object is passed to this rule automatically
      // when it's evaluated for a WorkgroupMembership rule type.
      
      // Get the list of steward names stored on the workgroup object
      List<String> stewardNames = (List<String>) workgroup.get("stewardNames"); 
      
      List<Identity> members = new ArrayList<Identity>();

      if (stewardNames != null && !stewardNames.isEmpty()) {
          for (String stewardName : stewardNames) {
              Identity steward = context.getObjectByName(Identity.class, stewardName);
              if (steward != null) {
                  members.add(steward);
                  log.debug("Added " + steward.getName() + " to dynamic workgroup " + workgroup.getName());
              } else {
                  log.warn("Steward identity '" + stewardName + "' not found for workgroup " + workgroup.getName());
              }
          }
      } else {
          log.debug("No steward names found on workgroup " + workgroup.getName() + ". Workgroup will be empty.");
      }

      return members;
    ]]>
  </Source>
</Rule>

4. Import and Configure

  1. Import the XMLs: Import the QuickLink.xml, Workflow.xml, and Rule.xml files into your IdentityIQ instance using the import command in the IIQ console or sailpoint.sh/bat console.
  2. Configure Workgroup:
  • After the workflow runs for the first time and creates the workgroup, you can manually verify it in Setup > Groups > Workgroups.
  • Ensure the Membership Rule is set to DynamicWorkgroupStewardsRule.
  1. Quicklink Population: Ensure your Quicklink is assigned to the appropriate Quicklink Population (Global Settings > Quicklink Populations) so that the desired users can see and access it.
  2. Permissions: Make sure the users who will be using this Quicklink have the necessary capabilities to:
  • Execute the workflow.
  • (If creating new workgroups) Create Workgroup objects.
  • (If managing existing workgroups) Edit Workgroup objects.