Grouper custom template via GSH

Grouper custom template via GSH

The Grouper custom template via GSH is in Grouper 2.5.43+

 

Intro

image-20260712-054004.png

 

Custom templates via GSH are a function of Grouper that evolves the idea of an Access Management Platform.  You can make a UI screen or a web service call that is completely custom.  The inputs are dynamic, flexible, and have built-in validations.  The GSH script to process those inputs has full control of Grouper or Java.  There is security around who can run the template, and the user they run-as.  There are easy-to-use APIs to perform a list of actions.

Custom templates via GSH are good for:

  1. Performing actions that are not available in the UI

    • check LDAP to see if provisioning happened, for example

    • make an ad hoc report and send it to the user

    • add/remove a service principal to a subject source table

  2. Automating multiple tasks into one

  3. Creating a custom access management interface for a user to simplify actions

    • e.g. to add a user to a VPN instance, you need to remove an exclude if there, and if not in the automatic population and an employee, add them to the VPN employee group, otherwise guest group.  All can be automated

  4. Create a Web Service call that does not exist in Grouper

  5. Reduce time to perform tasks

  6. Reduce Help Desk Tickets  

  7. The sky is the limit

 

Reminder:  "Custom UI" and "Custom Template via GSH" are two different features in Grouper.

Use a Custom UI when you want an end-user facing UI where the end user can:

  • See their status and why (e.g. they might need a training or a different affiliation)

  • Can (optionally) enroll or unenroll easily into a service

  • Redirect based on certain conditions to other services

  • You don't want the end user to see the full Grouper UI


Use Grouper Custom Templates via GSH (the info on this page):

  • For people who use the Grouper UI

  • Can have custom inputs

  • Logic can use the input values and performance queries or tasks

  • Automate multiple tasks in one operation

  • Can expose via web service

Best practices

  • If you get errors with dollar signs in strings use this

Script2.groovy: 603: illegal string body character after dollar sign; solution: either escape a literal dollar sign "\$5" or bracket the value expression "${5}" FROM: "$whatever" TO: '$' + "whatever"
  • You cannot line wrap unless you put an operator at end of line

No signature of method: java.lang.String.positive() is applicable for argument types: () values: [] FROM: String something = "" + "hey"; TO: String something = "" + "hey";

 

Configuring

There is a wizard in the UI.  These are the configs that the wizard controls

grouper.properties

grouperGshTemplate.<configId>.suffix

config id suffix

value example

description

notes

config id suffix

value example

description

notes

enabled

true | false

if this template is enabled

if false, do not show it in menu on folders or allow it to run

templateVersion

V1 | V2

V1 is the legacy version, the script is in the gshTemplate

V2 is the newer way where you extend a class and can include tests

 

showOnGroups

true | false

if this template option is available on groups

default false (TODO as of 2.5.36)

groupShowType

certainGroup, groupsInFolder, allGroups

is this supposed to show for one group, groups in a certain folder, or allGroups

required, show if showOnGroups=true (TODO as of 2.5.36)

groupUuidToShow

xyz321

which group to show the template on.  could be uuid or name.

required, show if groupShowType=certainGroup

groupShowOnDescendants

oneChildLevel, descendants

oneChildLevel: only show on groups directly in folder
descendants: show in all groups under the folder

required, show if groupShowType = groupsInfolder

showOnFolders

true | false

if this template option is available on folders

default false

folderShowType

certainFolder, allFolders

where should this template be available

drop down, required, show if showOnFolders = true

folderUuidToShow

abc123

uuid or name of folder to show this template

eventually we can have a folder combobox, currently textfield.  show if folderShowType = 'specifiedFolder' or groupShowType = 'groupsInFolder'.  Required

folderShowOnDescendants

certainFolder, oneChildLevel, certainFolderAndOneChildLevel, descendants, certainFolderAndDescendants

certainFolder: just show on one folder
oneChildLevel, only show on child level under folder
certainFolderAndOneChildLevel, show the folder and one level of children
descendants: show all folders under the folder
certainFolderAndDescendants: show folder and all descendants

if folderShowType = 'specifiedFolder'.  Required

runButtonGroupOrFolder

group | folder

If you want a run button on the GSH template page, this will allow configuration of a default group or folder

 

defaultRunButtonGroupUuidOrName

a:b:c

Default group name or uuid for the run now button

 

defaultRunButtonFolderUuidOrName

a:b:c

Default folder name or uuid for the run now button

 

securityRunType

wheel | specifiedGroup | privilegeOnObject | everyone

who can run this template.  Only GrouperSystem / wheel group, or specify a group.  If privilegeOnObject, then check to see if user has certain privileges on the object where the template was invoked from.

drop down, Required

groupUuidCanRun

def456

uuid or name of group that can run this template.  

eventually we can have a group combobox, currently textfield.  Show if securityRunType = 'specifiedGroup'.  Required

requireFolderPrivilege

admin, create, stemAttrRead, stemAttrUpdate

If running this template requires any of these privs on the folder it is run on

show if showOnFolders = true.  required if securityRunType = 'privilegeOnObject'

requireGroupPrivilege

admin, read, update, read_and_update, optin, optout, view, groupAttrRead, groupAttrUpdate

the option to run the template will only show if the user has this privilege on the group at least (e.g. if the user has ADMIN they can READ)

show if showOnGroups = true.
required if securityRunType = 'privilegeOnObject'

runAsType

currentUser | GrouperSystem| specifiedSubject

select the type of user to run as.  "currentUser" means
run as the user using the UI.  "GrouperSystem" means
run as root user, "specifiedSubject" means you can pick
a subject to run as (not common).

drop down.  Required

runAsSpecifiedSubjectSourceId

pennperson

select the source ID of the specified subject to run as

drop down (subject source picker).  Required

runAsSpecifiedSubjectId

12345678

subject id of the specified subject to run as

eventually we can have a subject combobox, currently textfield.  Required

templateNameExternalizedTextKey

grouperGshTemplate_<configId>_templateNameExternalizedTextKey

this is hardcoded for each template

this is readonly, not editable, eventually we can have
an externalized text editor to edit that from this screen

templateDescriptionExternalizedTextKey

grouperGshTemplate_<configId>_templateDescriptionExternalizedTextKey

this is hardcoded for each template

this is readonly

simplifiedUi

true | false

If the UI should not show the normal Grouper menus, to not confuse users who are not familiar with Grouper

 

allowWsFromNoOwner

true | false

if WS can call the template without identifying a stem or group owner

 

gshTemplate

//

this is the GSH template to run

if we can get a textarea that would be good.  Should convert from windows or mac newlines to unix newlines on submit.  Required

numberOfInputs

5

number of inputs (form elements on ui or in ws)

drop down from 0-50 repeat group.  Default value: 0

input.i.name

gsh_input_folderName

name of the ui form element, ws param, template variable,

validation: must start with gsh_input_, must be alphanumeric/underscore.  Required

input.i.labelExternalizedTextKey

grouperGshTemplate_<configId>_input_<inputName>_labelExternalizedTextKey

externalized text key of the label on the UI for this input

readonly

input.i.descriptionExternalizedTextKey

grouperGshTemplate_<configId>_input_<inputName>_descriptionExternalizedTextKey

externalized text key of the label on the UI for this input

readonly

input.i.type

int | boolean | string

type of the data

drop down with supported types.  suggested starting point: int, boolean, string.  Default value: string

input.i.formElementType

textfield, dropdown, checkbox

form element type on UI

show if type is not equal to "boolean" (if boolean its a radio).  Default value: textfield.

input.i.index

10

form elements will show on the form in order of "index".  DefaultValue is 0.  If two elements have the same index then they will show in order of configuration.

textfield

input.i.validationType

regex | jexl | none

type of validation on the input

required (none is not blank, it is an option)

input.i.validationRegex

^[a-zA-Z0-9_]{1,50}$

regex to check the input and if it doesnt match then fail.  For example, this is alphanumeric or underscore length between 1 and 50

show if validationType = 'regex', required

input.i.validationJexl

${gsh_input_myField.startsWith('whatever')}

run a validation (and include all variables for cross-validations), return true for valid, and false for invalid

show if validationType = 'jexl', required

input.i.validationMessageExternalizedTextKey

grouperGshTemplate_<configId>_input_<inputName>_validationMessageExternalizedTextKey

readonly key in externalized text for validation message (e.g. for jexl or regex)

readonly

input.i.required

true | false

if this input is required for template to run

default value: false

input.i.defaultValue

abc

default value for the input if none is provided

show if required is false

input.i.showEl

${gsh_input_someField = 'something'} for boolean, ${gsh_input_type == "Bulk"} for string value matching.

jexl for if this field should show, note all inputs are available to use as variables

 

numberOfTests

3

number of tests to make sure this template functions

drop down from 0-20 repeat group.  Default value: 0

test.i.deleteSideEffectsIfExistGsh

gsh script

will be run before and after test (first and last) to clean up what the test and setup and verification do.   Will not run after test if test fails

textarea

test.i.setupGsh

gsh script

will be run before test

textarea

test.i.testGsh

gsh script

call the Java API for the template exec with inputs

textarea, required

test.i.verifyGsh

gsh script

verify that the test succeeded

textarea

A grouper admin would configure this in the UI under miscellaneous

Text on screen similar to custom UI

This template could be called via ws REST JSON and pass in the input name/value form elements just like the UI would

 

Developing GSH templates with java

See this wiki as an example of developing GSH templates with java

Built in variables, inputs, and methods

Before the configured GSH script is executed, it will be prefixed with some built in variables, and the inputs from the user (supplied in the UI or less commonly the WS).

Type

V1 variable

V2 location

Value

Type

V1 variable

V2 location

Value

GshTemplateV2input

n/a

gshTemplateV2input

gshRunLogic method parameter for inputs.  This depends on how you name the param

@Override public void gshRunLogic(GshTemplateV2input gshTemplateV2input, GshTemplateV2output gshTemplateV2output) {

 

GshTemplateV2output

n/a

gshTemplateV2output

gshRunLogic method parameter for outputs. This depends on how you name the param

@Override public void gshRunLogic(GshTemplateV2input gshTemplateV2input, GshTemplateV2output gshTemplateV2output) {

 GshTemplateRuntime

n/a

gshTemplateV2input.getGsh_builtin_gshTemplateRuntime()

 

 

 

 

 

 

 

 

 

GshTemplateOutput

gsh_builtin_gshTemplateOutput 

GshTemplateOutput gsh_builtin_gshTemplateOutput = gshTemplateV2output.getGsh_builtin_gshTemplateOutput();

Object that helps print output, notify about validation errors, or identify that an error occurred

GshTemplateRuntime

gsh_builtin_gshTemplateRuntime

gshTemplateV2input.getGsh_builtin_gshTemplateRuntime()

Internal object that is used to help with other variables

GrouperSession

gsh_builtin_grouperSession

gshTemplateV2input.getGsh_builtin_grouperSession()

Session based on who the template is running is (this is configured, recommended to be the user who is running the template)

Subject

gsh_builtin_subject

gshTemplateV2input.getGsh_builtin_gshTemplateRuntime().getCurrentSubject()

Subject who is running the template

String

gsh_builtin_subjectId

gshTemplateV2input.getGsh_builtin_gshTemplateRuntime().getCurrentSubject().getId()

Subject ID of gsh_builtin_subject

String

gsh_builtin_ownerStemName

gshTemplateV2input.getGsh_builtin_gshTemplateRuntime().getOwnerStemName()

Folder name of the folder where the script is run (if stem script, otherwise null)

String

gsh_builtin_ownerGroupName

gshTemplateV2input.getGsh_builtin_gshTemplateRuntime().getOwnerGroupName()

Group name for the group where the script was run (if group script, otherwise null)

String

gsh_input_XXXXXX 

gshTemplateV2input.getGsh_builtin_inputString("gsh_input_org")

String inputs

Integer

gsh_input_YYYYYYY

gshTemplateV2input.getGsh_builtin_inputInteger("gsh_input_numberOfRows")

Integer inputs

Boolean

gsh_input_ZZZZZZZ

gshTemplateV2input.getGsh_builtin_inputBoolean("gsh_input_isEmployee")

Boolean inputs

String

<none>

gshTemplateV2input.getGsh_builtin_gshTemplateRuntime().getRemoteAddr()

Source IP address

String

<none>

gshTemplateV2input.getGsh_builtin_gshTemplateRuntime().getTemplateConfigId()

Config ID of template.  This is useful if the same GSH source is used
for multiple templates.

void

gsh_builtin_gshTemplateOutput.assignRedirectToGrouperOperation("NONE");

Do not navigate after running template (or put another link in there)

void

gsh_builtin_gshTemplateOutput.assignRedirectToGrouperOperation("operation=UiV2Group.viewGroup&groupName=" + groupName);