The info on this page applies to Grouper 2.6 and above. |
The comparisons and logic happen on "target objects" which are translated from grouper
${edu.internet2.middleware.grouper.util.GrouperUtil.stringFormatNameReverseReplaceTruncate(grouperProvisioningGroup.name, ".", 64)} |
If you need a group membership or privilege on a user in a translation you can use this (4.11.0+, 5.9.0+). These return a boolean
${provisioningEntityWrapper.isInGroup('test2:testGroup3')} ${provisioningEntityWrapper.isHasPrivilege('test2:testGroup3', 'admins')} |
If you need list of users from a group based on membership or privilege, can get a set of strings based on: subjectId, subjectIdentifier0, subjectIdentifier1, subjectIdentifier2, email
${provisioningGroupWrapper.groupMembers('test2:testGroup3', 'subjectId')} ${provisioningGroupWrapper.groupPrivilegeHolders('test2:testGroup3', 'updaters', 'subjectIdentifier0')} |
"Subject link" is when the subject source needs to be consulted since data to provision is not just the subject id (need attributes cached in grouper or need more up to date data)
Here is the design for subject link from grouper
For entities, this could have some data cached for a subject
provisioner.sqlProvTest.syncMemberFromId3AttributeValueFormat = ${subject.attributes['myLdapId']} |
The provisioning framework will see if the "memberFromId3" is null when getting data from sync cache, those subjects will be resolved and that data will be populated and used
This will translate that to the entity id
#translate from group auto translated to the target format provisioner.sqlProvTest.grouperToTargetTranslation.0.script = ${grouperTargetEntity.setId(grouperSyncMember.getMemberFromId3())} # could be group, membership, or entity provisioner.sqlProvTest.grouperToTargetTranslation.0.for = entity |
"Target user link" is when the target needs to be consulted since data to provision is not just the subject id or subject api data (need cached in grouper or need more up to date data)
Here is the design for target user link from grouper
For entities, this could have some data cached for a subject
# main identifier of the user on the target side provisioner.sqlProvTest.syncMemberToId2AttributeValueFormat = ${targetEntity.attributes['dn']} # identifier of the user as referred to by the group provisioner.sqlProvTest.syncMemberToId3AttributeValueFormat = ${targetEntity.attributes['uid']} |
The provisioning framework will see if the "memberToId2" or "memberToId3" is null when getting data from sync cache, those entities will be resolved and that data will be populated and used
This will translate that to the entity id
#translate from group auto translated to the target format provisioner.sqlProvTest.grouperToTargetTranslation.0.script = ${grouperTargetEntity.setId(grouperSyncMember.getMemberToId3())} # could be group, membership, or entity provisioner.sqlProvTest.grouperToTargetTranslation.0.for = entity |
"Target group link" is when the target needs to be consulted since data to provision is not just the group uuid, name, id index, etc data (need cached in grouper or need more up to date data)
Here is the design for target group link from grouper
For groups, this could have some data cached from the target
# main identifier of the user on the target side provisioner.sqlProvTest.syncGroupToId2AttributeValueFormat = ${targetGroup.attributes['dn']} |
The provisioning framework will see if the "groupToId2" or "groupToId3" is null when getting data from sync cache, those entities will be resolved and that data will be populated and used
This will translate that to the group id
#translate from group auto translated to the target format provisioner.sqlProvTest.grouperToTargetTranslation.0.script = ${grouperTargetGroup.setId(grouperSyncGroup.getGroupToId2())} # could be group, membership, or entity provisioner.sqlProvTest.grouperToTargetTranslation.0.for = group |
Field | Type | Description |
---|---|---|
id | String | every group must have an id, what it is known by in the target. if there is an opaque id, then that is best. Otherwise, whatever it is (uuid, name, extension, idIndex, etc). not: this can be manipulated to turn a name into a DN for example |
name | String | This is the group name which can be different than the id. If there is no name different from id, this can be blank. this is used for renames |
idIndex | Long (integer) | int assigned from grouper to enable renames of target groups |
displayName | String | display name for group |
attributes | Map<String, TargetAttribute> | list of attributes where there is a string name and a value (object) value can be a scalar or a collection |
Field | Type | Description |
---|---|---|
id | String | every entity must have an id, what it is known by in the target |
loginId | String | This is the entity loginid which can be different than the id. If there is no loginid different from id, this can be blank. this is used for changing the netId in the target for an existing user. e.g. netId, eppn, email, etc. optional |
name | String | name field can be "first last" or whatever the name should be in the target. optional |
String | email address used for contact to the user. optional | |
attributes | Map<String, TargetAttribute> | list of attributes where there is a string name and a value (object) value can be a scalar or a collection |
Field | Type | Description |
---|---|---|
id | String | membership can have id or else the id will be tuple of group id and subject id (optional) |
groupId | String | provisioning group id for membership |
group | ProvisioningGroup | reference to the group from this membership |
entityId | String | provisioning entity id for memberships |
entity | ProvisioningEntity | reference to the entity from this membership |
attributes | Map<String, TargetAttribute> | list of attributes where there is a string name and a value (object) value can be a scalar or a collection |
Field | Type | Description |
---|---|---|
name | String | name of attribute |
value | Object (any type, could be multivalued) | value of attribute |
Grouper native comes from SQL queries. This is fairly standard and minorly customizable
Variable (e.g. in EL) | Type | Description |
---|---|---|
grouperProvisionGroup | ProvisioningGroup |
|
grouperProvisionMembership | ProvisioningMembership |
|
grouperProvisionEntity | ProvisioningEntity |
|
The Grouper provisioning format is processed and the "target object" format needs to be reached.
Variable | Type |
---|---|
grouperTargetGroup | ProvisioningGroup |
grouperTargetMembership | ProvisioningMembership |
grouperTargetEntity | ProvisioningEntity |
First the grouper provisioning groups are cycled through, and for each group, a grouper target group will be created, and a translation will assign fields of the target object from the grouper objects
If a grouperToTargetTranslation "for" is "group" then that translation will be evaluated while looping through groups.
In this example, use the group "name" as the matching ID of the group
#translate from group auto translated to the target format provisioner.sqlProvTest.grouperToTargetTranslation.0.script = ${grouperTargetGroup.setId(grouperProvisionGroup.getName())} # could be group, membership, or entity provisioner.sqlProvTest.grouperToTargetTranslation.0.for = group #translate from group auto translated to the target format provisioner.sqlProvTest.grouperToTargetTranslation.1.script = ${grouperTargetGroup.setAttribute("desc", grouperProvisionGroup.getAttribute("description"))} # could be group, membership, or entity provisioner.sqlProvTest.grouperToTargetTranslation.1.for = group |
If a grouperToTargetTranslation "for" is "entity" then that translation will be evaluated while looping through entities
In this example use the subject id as the matching ID
#translate from group auto translated to the target format provisioner.sqlProvTest.grouperToTargetTranslation.1.script = ${grouperTargetEntity.setId(grouperProvisionEntity.getAttribute("subjectId"))} # could be group, membership, or entity provisioner.sqlProvTest.grouperToTargetTranslation.1.for = entity |
If a grouperToTargetTranslation "for" is "membership" then that translation will be evaluated while looping through memberships
Depending on the target, fields will be populated and documented for that provisioner. Note: any state needed to make changes in the target need to be stored in these beans
Variable | Type |
---|---|
targetProvisionGroup | ProvisioningGroup |
targetProvisionMembership | ProvisioningMembership |
targetProvisionEntity | ProvisioningEntity |
Variable | Type | Notes |
---|---|---|
targetNativeGroup | ? | native target group |
targetNativeMembership | ? | |
targetNativeEntity | ? |
Use the targetGroup, targetEntity, and targetMembership variable to refer to the grouperTargetGroups, grouperTargetEntity's, grouperTargetMemberships, targetProvisioningGroups, targetProvisioningEntity's, and targetProvisioningMemberships
If you are supporting renames, then the id of the targets need to something opaque and unchanging (e.g. grouper group idIndex or uuid).
Note: you only need to specify the id's for objects that are in the target (e.g. you might not need all three unless there are groups, entities, and memberships in the target).
If something is specified then the group id and entity id will be used for targetGroups and targetEntities. For targetMemberships, it will by default use MultiKey of provisioningGroupId and provisioningEntityId.
The ID cant be null unless its an insert and the target expects a null for insert
The type of the id should be a string, numeric, or a multikey of a few strings / numerics. The ${ } is optional
provisioner.sqlProvTest.targetGroupIdExpression = ${targetGroup.retrieveAttributeValueString("groupName")} provisioner.sqlProvTest.targetMembershipIdExpression = new('edu.internet2.middleware.grouperClient.collections.MultiKey', targetMembership.retrieveAttributeValueString('group_name'), targetMembership.retrieveAttributeValueString('subject_id')) provisioner.sqlProvTest.targetEntityIdExpression = ${targetEntity.retrieveAttributeValueString("subjectId")} |