Child pages
  • Grouper provisioning in UI
Skip to end of metadata
Go to start of metadata

In a patch grouper_v2_4_0_ui_patch_35 in 2.4 we added provisioning in the UI.  This can be for multiple provisioners including PSPNG and other things like Box provisioning.  Note the provisioner needs to be able to key off the the attributes on groups and folders, which is not yet available for PSPNG.  It is currently (grouper_v2_4_0_ui_patch_35) available for the Duo connector.  We will add more provisioners.

Getting started

Enable provisioning in the grouper.properties

#########################################
## Provisioning in UI
#########################################

# if provisioning in ui should be enabled
# {valueType: "boolean", required: true}
provisioningInUi.enable = true


Set a group in the grouper-ui.properties if you dont want all group / folder admins to control provisioning

###################################
## V2 UI provisioning settings
###################################

# put in a group here if you want to restrict the provisioning tab to certin users.  
# note, admins can always see the tab
# ${valueType: "group"}
uiV2.provisioning.must.be.in.group =


Target specific properties

For each target, the following properties can be configured. They need to be set in grouper.properties

#name and key you want to give to your target. key is used to configure the label for the UI
provisioning.target.pspngLdap1.key = pspngLdap1Key

#members of the configured group are allowed to assign this target 
provisioning.target.pspngLdap1.groupAllowedToAssign =

#if this target should only be assigned to one stem
provisioning.target.pspngLdap1.allowAssignmentsOnlyOnOneStem = false

#if this target is read only and cannot be assigned from provisioning UI.
provisioning.target.pspngLdap1.readOnly = false


To assign label for the key configured above, a corresponding entry needs to go in grouper.text.en.us.base.properties or grouper.text.en.us.properties for English. For other languages, add an entry into corresponding externalized language file.

provisioningUiLabelForKey_pspngLdap1Key = OpenLDAP production

Example of setting up provisioning in the UI with Duo

Enable provisioning in the UI in grouper.properties (per above)

Add a provisioner in the grouper.properties and optionally configure text in externalized text file : grouper.textNg.en.us.base.properties

#########################################
## Provisioning in UI
#########################################

# if provisioning in ui should be enabled
# {valueType: "boolean", required: true}
provisioningInUi.enable = true

# key for target
# {valueType: "string"}
provisioning.target.duo.key = duo

# members of this group, wheel group members and system user are allowed to assign this target
# {valueType: "stem"}
provisioning.target.duo.groupAllowedToAssign =

# should this target be assigned to only one stem
# {valueType: "boolean", required: false}
provisioning.target.duo.allowAssignmentsOnlyOnOneStem = true

# should this target be read only
# {valueType: "boolean", required: false}
provisioning.target.duo.readOnly = false


Assign this on a folder:


See that groups in the folder will be provisioned

Edit the grouper-loader.properties to use provisioning in the UI, and not a direct configuration

REMOVE:
# put groups in here which go to duo, the name in duo will be the extension here
# this ust be blank if using UI provisioning configuration
grouperDuo.folder.name.withDuoGroups = test:duo

ADD:
# use ui provisioning configuration, not config file
grouperDuo.use.ui.provisioning.configuration = true

# links the ui provisioner config to this provisioner code
grouperDuo.ui.provisioning.targetName = duo



UI actions

  • Edit LDAP configs (grouper loader properties)
  • Enable a provisioning target type (grouper loader properties)
  • Enable a provisioning target
  • Disable/Enable a provisioning target for folder or group
  • See grouper loader logs for change log consumers
  • Manage change log bookmark for change log listeners
  • Trigger a full sync (send message), look at provisioningLastFullMillisSince1970 until complete
  • Reporting can do a report of a full sync

Privileges

  • ADMIN on folder you can see configs?
  • READ on group you can see the configs?
  • By default you have to be grouper admin to do provisioning
    • Provisioning target type Java implementation could allow group/folder ADMINs to be able to edit?  Anyone need this?  Might be nice for

Screenshots

Use the "More actions" button to access Provisioning


List of assigned targets for a folder


Assigning a target to a folder

Attribute definitions

DefinitionAssigned ToPurposeValueCardinality

provisioningDef

folder, groupidentify a group typemarkerMulti assign

provisioningValueDef

folder assignment, group assignmentname/value pairsstringSingle assign, single valued


Attribute names

NameDefinitionValue

provisioningMarker

provisioningDef<none>

provisioningTarget

provisioningValueDefRelated to a config in grouper-loader.properties which links this provisioner to entend the class GrouperProvisionerBase

provisioningDirectAssign

provisioningValueDefif this is directly assigned or inherited

provisioningOwnerStemId

provisioningValueDefif this is not a direct assignment, then this is the stem id where it is inherited from

provisioningStemScope

provisioningValueDefIf folder provisioning applies to only this folder or this folder and subfolders. one|sub

provisioningDoProvision

provisioningValueDefIf you should provisioning (default to true)

provisioningLastFullMillisSince1970

provisioningValueDefMillis since 1970 that this was last full provisioned

provisioningLastIncrementalMillisSince1970

provisioningValueDefMillis since 1970 that this was last incremental provisioned. Even if the incremental did not change the target

provisioningLastFullSummary

provisioningValueDefSummary of last full run

provisioningLastIncrementalSummary

provisioningValueDefSummary of last incremental run


Developer notes

This is integrated with Duo, see GrouperDuoUtils

  /**
   * cache the folder for duo
   */
  private static ExpirableCache<Boolean, Stem> duoStemCache = new ExpirableCache<Boolean, Stem>(5);

  /**
   * get duo stem from expirable cache or from database
   * duo stem
   * @param debugMap
   * @return the stem
   */
  public static Stem duoStem(Map<String, Object> debugMap) {
    
    Stem duoStem  = duoStemCache.get(Boolean.TRUE);
    if (debugMap != null) {
      debugMap.put("duoStemInExpirableCache", duoStem != null);
    }

    if (duoStem == null) {
      duoStem = duoStemHelper(debugMap);
      duoStemCache.put(Boolean.TRUE, duoStem);
    }
    return duoStem;
  }
  
  /**
   * duo stem
   * @param debugMap
   * @return the stem
   */
  public static Stem duoStemHelper(Map<String, Object> debugMap) {

    //# put groups in here which go to duo, the name in duo will be the extension here
    //grouperDuo.folder.name.withDuoGroups = duo
    String grouperDuoFolderName = GrouperLoaderConfig.retrieveConfig().propertyValueString("grouperDuo.folder.name.withDuoGroups");
    boolean useUiProvisioningConfiguration = GrouperLoaderConfig.retrieveConfig().propertyValueBoolean("grouperDuo.use.ui.provisioning.configuration", true);
    
    if (useUiProvisioningConfiguration && !StringUtils.isBlank(grouperDuoFolderName)) {
      throw new RuntimeException("If you are using ui provisioning configuration, you cant configure a folder in the grouper-loader.properties 'grouperDuo.folder.name.withDuoGroups'!!!!");
    }
    
    Stem grouperDuoFolder = null;
    
    if (useUiProvisioningConfiguration) {
      
      String uiProvisioningTargetName = GrouperLoaderConfig.retrieveConfig().propertyValueStringRequired("grouperDuo.ui.provisioning.targetName");
      
      if (debugMap != null) {
        debugMap.put("uiProvisioningTargetName", uiProvisioningTargetName);
      }
      
      List<Stem> stems = new ArrayList<Stem>(new StemFinder().assignAttributeCheckReadOnAttributeDef(false)
          .assignNameOfAttributeDefName(GrouperProvisioningSettings.provisioningConfigStemName()+":"+GrouperProvisioningAttributeNames.PROVISIONING_TARGET)
          .addAttributeValuesOnAssignment(uiProvisioningTargetName)
          .assignNameOfAttributeDefName2(GrouperProvisioningSettings.provisioningConfigStemName()+":"+GrouperProvisioningAttributeNames.PROVISIONING_DO_PROVISION)
          .addAttributeValuesOnAssignment2("true")
          .findStems());

      GrouperUtil.stemRemoveChildStemsOfTopStem(stems);
      
      if (debugMap != null) {
        debugMap.put("folderCount", GrouperUtil.length(stems));
      }
      
      if (GrouperUtil.length(stems) > 1) {
        throw new RuntimeException("Folder count can only be 0 or 1!!! " + GrouperUtil.length(stems));
      }
      if (GrouperUtil.length(stems) == 1) {
        grouperDuoFolder = stems.iterator().next();
      }
    } else {
    
      grouperDuoFolder = StemFinder.findByName(GrouperSession.staticGrouperSession(), grouperDuoFolderName, true);
    }
    return grouperDuoFolder;
  }


Issues

  • Do not provisioning internal groups list systemOfRecord
    • Decide how that works with DoProvision


  • No labels

2 Comments

  1. It would be great if attributesNames could supply a "search" (to use a list of Grouper objects: groups, attribute names from another attribute definition, a grouper config property set of values, others?) to provide the user a fixed list of values that can be used for that attributeName.

      Which would be very specifically useful for the provisioningTarget, provisioningDirectAssign, provisioningStemScope,  attribute names above. ( And I would think for a whole host of attribute names.)


  2. "By default you have to be grouper admin to do provisioning"  What do you specifically mean by that?

     Maybe this access control? "groups.wheel.group= ..." Something else?


    Maybe it could be driven by the ability to see Grouper objects that feed provisioningTarget ? That way each provisioner could be managed by different groups ( after being established by the Grouper System owners/operators.