All Downloads are FREE. Search and download functionalities are using the official Maven repository.

.middleware.grouper.grouper.5.11.0.source-code.grouper.base.properties Maven / Gradle / Ivy

There is a newer version: 5.13.5
Show newest version
#
# Copyright 2014 Internet2
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

#
# Grouper Configuration
# $Id: grouper.example.properties,v 1.48 2009-12-16 06:02:30 mchyzer Exp $
#


########################################
## Config chaining hierarchy
## Grouper uses Grouper Configuration Overlays (documented on wiki)
## By default the configuration is read from grouper.base.properties
## (which should not be edited), and the grouper.properties overlays
## the base settings.  See the grouper.base.properties for the possible
## settings that can be applied to the grouper.properties
########################################

# comma separated config files that override each other (files on the right override the left)
# each should start with file: or classpath:
# e.g. classpath:grouper.example.properties, file:c:/something/myconfig.properties
# {valueType: "string", required: true, multiple: true}
grouper.config.hierarchy = classpath:grouper.base.properties, classpath:grouper.properties, database:grouper

# seconds between checking to see if the config files are updated
# {valueType: "integer", required: true}
grouper.config.secondsBetweenUpdateChecks = 600


########################################
## General settings
########################################

# used to identify your institution (e.g. in TIER instrumentation)
# {valueType: "string"}
grouper.institution.name =

# in cases where grouper is logging or emailing, it will use this to differentiate test vs dev vs prod
# {valueType: "string"}
grouper.env.name =

#put the URL which will be used e.g. in emails to users.  include the webappname at the end, and nothing after that.
#e.g. https://server.school.edu/grouper/
# {valueType: "string"}
grouper.ui.url =

# tmp dir to use, will set this to the env var for tmp dir during cache operations...
# note, if you are using a backslash, you need to escape it with another, e.g. c:\\temp
# see the temp dir in logs with this in log4j.properties
# {valueType: "string"}
grouper.tmp.dir =

# main stem for grouper built in objects
# Note: there are more locations to change than just this
# {valueType: "stem"}
grouper.rootStemForBuiltinObjects = etc

#######################################
## Inititalization and configuration settings
#######################################

#if grouper should auto init the registry if not initted (i.e. insert the root stem, built in fields, etc)
#defaults to true
# {valueType: "boolean", required: true}
registry.autoinit = true

#if grouper should try and detect and log configuration errors on startup
#in general this should be true, unless the output is too annoying or if it is causing a problem
# {valueType: "boolean", required: true}
configuration.detect.errors = true

#if the startup message should display
# {valueType: "boolean", required: true}
configuration.display.startup.message = true

#if groups like the wheel group should be auto-created for convenience (note: check config needs to be on)
# {valueType: "boolean", required: true}
configuration.autocreate.system.groups = true

# auto-create groups (increment the integer index), and auto-populate with users
#(note: check config needs to be on)
# {valueType: "group", regex: "^configuration\\.autocreate\\.group\\.name\\.[0-9]+$"}
#configuration.autocreate.group.name.0 = $$grouper.rootStemForBuiltinObjects$$:uiUsers

# auto-create group description (increment the integer index)
# {valueType: "string", regex: "^configuration\\.autocreate\\.group\\.description\\.[0-9]+$"}
#configuration.autocreate.group.description.0 = users allowed to log in to the UI

#auto-create group subject ids or identifiers, comma separated, to bootstrap the registry on startup
#  (increment the integer index)
# {valueType: "subject", multiple: true, regex: "^configuration\\.autocreate\\.group\\.subjects\\.[0-9]+$"}
#configuration.autocreate.group.subjects.0 = johnsmith

# if should check database and utf in new thread
# {valueType: "boolean", required: true}
configuration.checkDatabaseAndUtf.inNewThread = true

# if grouper should check to see if the database has case sensitive selects
# {valueType: "boolean", required: true}
configuration.detect.db.caseSensitive.problems = true

# if grouper should give a success message on case sensitive matching
# {valueType: "boolean", required: true}
configuration.display.db.caseSensitive.success.message = false

# (Deprecated) if grouper should check to see if utf-8 works on startup (both files and db). This
# property never worked as intended; instead of setting this, see the individual properties
# "configuration.detect.utf8.file.problems" and "configuration.detect.utf8.db.problems"
# {valueType: "boolean", required: false}
#configuration.detect.utf8.problems = false

# 2016/04/15 utf-8 checking doesnt work, we need to fix this before default to true
# if grouper should check to see if utf-8 works on startup in files
# {valueType: "boolean", required: true}
configuration.detect.utf8.file.problems = false

# if grouper should check that utf-8 works on startup in files
# {valueType: "boolean", required: true}
configuration.detect.utf8.db.problems = true

# if grouper should give a success message on utf8 inputs
# {valueType: "boolean", required: true}
configuration.display.utf8.success.message = false

# if grouper in the utf8 check will check to see if grouper supports transaction
# {valueType: "boolean", required: true}
configuration.detect.db.transaction.problems = true

# display a success message on transactions
# {valueType: "boolean", required: true}
configuration.display.transaction.success.message = false

# {valueType: "string", defaultValue: "jdbc"}
configuration.registrySubjectSource = jdbc

###################################
## Security settings
###################################

# If set to _true_, the ALL subject will be granted optin on
# each new group that is created.  Note, you can override the default
# checkboxes on screen of UI in media.properties.
# {valueType: "boolean", required: true}
groups.create.grant.all.optin         = false

# If set to _true_, the ALL subject will be granted optout on
# each new group that is created.  Note, you can override the default
# checkboxes on screen of UI in media.properties.
# {valueType: "boolean", required: true}
groups.create.grant.all.optout        = false

# If set to _true_, the ALL subject will be granted read on
# each new group that is created.  Note, you can override the default
# checkboxes on screen of UI in media.properties.
# {valueType: "boolean", required: true}
groups.create.grant.all.read          = false

# If set to _true_, the ALL subject will be granted view on
# each new group that is created.  Note, you can override the default
# checkboxes on screen of UI in media.properties.
# {valueType: "boolean", required: true}
groups.create.grant.all.view          = false

# If set to _true_, the ALL subject will be granted attrRead on
# each new group that is created.  Note, you can override the default
# checkboxes on screen of UI in media.properties.
# {valueType: "boolean", required: true}
groups.create.grant.all.groupAttrRead = false

# If set to _true_, the ALL subject will be granted attrUpdate on
# each new group that is created.  Note, you can override the default
# checkboxes on screen of UI in media.properties.
# {valueType: "boolean", required: true}
groups.create.grant.all.groupAttrUpdate = false

# If set to _true_, the ALL subject will be granted create on
# each new stem that is created.
# {valueType: "boolean", required: true}
stems.create.grant.all.create         = false

# If set to _true_, the ALL subject will be granted admin on
# each new stem that is created.
# {valueType: "boolean", required: true}
stems.create.grant.all.stemAdmin      = false

# If set to _true_, the ALL subject will be granted attrRead on
# each new stem that is created.
# {valueType: "boolean", required: true}
stems.create.grant.all.stemAttrRead   = false

# If set to _true_, the ALL subject will be granted attrUpdate on
# each new stem that is created.
# {valueType: "boolean", required: true}
stems.create.grant.all.stemAttrUpdate = false

# If set to _true_, the ALL subject will be granted attrAdmin on
# each new attributeDef that is created.
# {valueType: "boolean", required: true}
attributeDefs.create.grant.all.attrAdmin         = false

# If set to _true_, the ALL subject will be granted attrOptin on
# each new attributeDef that is created.
# {valueType: "boolean", required: true}
attributeDefs.create.grant.all.attrOptin         = false

# If set to _true_, the ALL subject will be granted attrOptout on
# each new attributeDef that is created.
# {valueType: "boolean", required: true}
attributeDefs.create.grant.all.attrOptout        = false

# If set to _true_, the ALL subject will be granted attrRead on
# each new attributeDef that is created.
# {valueType: "boolean", required: true}
attributeDefs.create.grant.all.attrRead          = false

# If set to _true_, the ALL subject will be granted attrUpdate on
# each new attributeDef that is created.
# {valueType: "boolean", required: true}
attributeDefs.create.grant.all.attrUpdate        = false

# If set to _true_, the ALL subject will be granted attrView on
# each new attributeDef that is created.
# {valueType: "boolean", required: true}
attributeDefs.create.grant.all.attrView          = false

# If set to _true_, the ALL subject will be granted attrDefAttrRead on
# each new attributeDef that is created.
# {valueType: "boolean", required: true}
attributeDefs.create.grant.all.attrDefAttrRead   = false

# If set to _true_, the ALL subject will be granted attrDefAttrAdmin on
# each new attributeDef that is created.
# {valueType: "boolean", required: true}
attributeDefs.create.grant.all.attrDefAttrUpdate = false

# if set to true, then the ALL subject will be granted view on new entities
# {valueType: "boolean", required: true}
entities.create.grant.all.view = false

# GRP-1664: do not add admin privileges to root or wheel when creating objects
# {valueType: "boolean", required: true}
privileges.assignAdminToWheelOrRootOnCreate = false

# GRP-1665: do not add admin privileges to inherited admins
# {valueType: "boolean", required: true}
privileges.assignAdminToInheritedAdminsOnCreate = false

# A wheel group allows you to enable non-GrouperSystem subjects to act
# like a root user when interacting with the registry.
# {valueType: "boolean", required: true}
groups.wheel.use                      = true

# Set to the name of the group you want to treat as the wheel group.
# The members of this group will be treated as root-like users.
# {valueType: "group", required: true}
groups.wheel.group                    = $$grouper.rootStemForBuiltinObjects$$:sysadmingroup

# A viewonly wheel group allows you to enable non-GrouperSystem subjects to act
# like a root user when viewing the registry.
# {valueType: "boolean", required: true}
groups.wheel.viewonly.use                      = true

# Set to the name of the group you want to treat as the viewonly wheel group.
# The members of this group will be treated as root-like users when viewing objects.
# {valueType: "group", required: true}
groups.wheel.viewonly.group                    = $$grouper.rootStemForBuiltinObjects$$:sysadminViewersGroup

# A readonly wheel group allows you to enable non-GrouperSystem subjects to act
# like a root user when reading the registry.
# {valueType: "boolean", required: true}
groups.wheel.readonly.use                      = true

# Set to the name of the group you want to treat as the readonly wheel group.
# The members of this group will be treated as root-like users when reading objects.
# {valueType: "group", required: true}
groups.wheel.readonly.group                    = $$grouper.rootStemForBuiltinObjects$$:sysadminReadersGroup


# To change the internal names for GrouperAll and GrouperSystem
# uncomment and change. Review UI nav.properties to ensure consistency
# {valueType: "string", required: true}
subject.internal.grouperall.name   = EveryEntity

# {valueType: "string", required: true}
subject.internal.groupersystem.name   = GrouperSysAdmin

# Search and sort strings for internal users
# {valueType: "string", multiple: true}
internalSubjects.searchAttribute0.el = ${subject.name},${subject.id}

# {valueType: "string"}
internalSubjects.sortAttribute0.el = ${subject.name}


#by default, anyone with admin rights on a group can edit the types or attributes
#specify types (related attributes will also be protected) which are wheel only, or restricted to a certain group
# {valueType: "boolean", required: true, regex: "^security\\.types\\.([^.]+)\\.wheelOnly$"}
#security.types.typeName.wheelOnly = true

#by default, anyone with admin rights on a group can edit the types or attributes
#specify types (related attributes will also be protected) which are wheel only, or restricted to a certain group
# {valueType: "boolean", required: true}
security.types.grouperLoader.wheelOnly = true

#by default, anyone with admin rights on a group can edit the types or attributes
#specify types (related attributes will also be protected) which are wheel only, or restricted to a certain group
# {valueType: "boolean", required: true}
security.types.grouperGroupMembershipSettings.wheelOnly = true

# if only a certain group can control the type
# {valueType: "group", required: true, regex: "^security\\.types\\.([^.]+)\\.allowOnlyGroup$"}
#security.types.typeName.allowOnlyGroup = $$grouper.rootStemForBuiltinObjects$$:someAdminGroup

# If this property is set, then to move a stem, in addition to having the appropriate stem privileges for the stem being moved and the destination stem,
# a user must also be a member of the defined group.  Note that users in the wheel group will have access regardless of this property.
# {valueType: "group", required: true}
#security.stem.groupAllowedToMoveStem = $$grouper.rootStemForBuiltinObjects$$:someAdminGroup

# If this property is set, then to rename a stem, in addition to having the appropriate stem privilege for the stem being renamed,
# a user must also be a member of the defined group.  Note that users in the wheel group will have access regardless of this property.
# {valueType: "group", required: true}
#security.stem.groupAllowedToRenameStem = $$grouper.rootStemForBuiltinObjects$$:someAdminGroup

# If this property is set, then to copy a stem, a user must be a member of the defined group.  Note that users in the wheel group will have access regardless of this property.
# {valueType: "group", required: true}
#security.stem.groupAllowedToCopyStem = $$grouper.rootStemForBuiltinObjects$$:someAdminGroup

# By default, all users have access to sort using any of the sort strings in the member table.
# You can restrict to wheel only or to a certain group.  The integer index denotes the specific string
# {valueType: "group", required: true, regex: "^security\\.member\\.sort\\.string([0-9]+)\\.allowOnlyGroup$"}
#security.member.sort.string0.allowOnlyGroup = $$grouper.rootStemForBuiltinObjects$$:someGroup

# By default, all users have access to sort using any of the sort strings in the member table.
# You can restrict to wheel only or to a certain group.  The integer index denotes the specific string
# {valueType: "boolean", required: true, regex: "^security\\.member\\.sort\\.string([0-9]+)\\.wheelOnly$"}
#security.member.sort.string0.wheelOnly = true

# By default, all users have access to search strings in the member table.
# You can restrict to wheel only or to a certain group.  The integer index denotes the specific string
# {valueType: "group", required: true, regex: "^security\\.member\\.search\\.string([0-9]+)\\.allowOnlyGroup$"}
#security.member.search.string0.allowOnlyGroup = $$grouper.rootStemForBuiltinObjects$$:someGroup

# By default, all users have access to search strings in the member table.
# You can restrict to wheel only or to a certain group.  The integer index denotes the specific string
# {valueType: "boolean", required: true, regex: "^security\\.member\\.search\\.string([0-9]+)\\.wheelOnly$"}
#security.member.search.string2.wheelOnly = true

# if all folders should be shown only if there is an object inside that the user can see (or a privilege on that folder).
# this has been re-coded and is the new setting.  The old setting "security.show.folders.where.user.can.see.subobjects" is not used anymore
# {valueType: "boolean", required: true}
security.folders.are.viewable.by.all = false

# put in a group name to exclude non admins who have a lot of privileges who have bad performance
# {valueType: "group"}
security.show.all.folders.if.in.group = $$grouper.rootStemForBuiltinObjects$$:sysadminStemViewers

# recalc in change log if the user has needed privileges in the last X seconds, default to 604800 which is one week
# so if someone has needed stem view privileges in the last week, then have the change log keep it up to date
# 0 means dont do this for anyone (full recalc each time), -1 means do this for everyone who has ever checked stem view,
# other negative values are not valid.
# {valueType: "integer"}
security.folders.view.privileges.recalcChangeLog.ifNeededInLastSeconds = 604800

# log error if performance is above this number of seconds.  tells you to exclude some users or disable feature
# leave blank or -1 to disable
# {valueType: "integer", required: true}
security.show.all.folders.log.above.seconds = 30

# log security folder view privilege change log consumer
# {valueType: "boolean", required: true}
security.folder.view.privileges.changeLogConsumer.log = false

# log security folder view privilege full daemon
# {valueType: "boolean", required: true}
security.folder.view.privileges.fullDaemon.log = false

# group which pre-loads stem view privileges in the full daemon run.  Run the full to prime the privileges or wait for it to run
# {valueType: "String", required: true}
security.folder.view.privileges.precompute.group = $$grouper.rootStemForBuiltinObjects$$:privilege:stemViewPrecompute

###################################
## Member sort and search
###################################

# Attributes of members are kept in the grouper_members table to allow easy sorting and searching (for instance when listing group members).
# When performing a sort or search and an index is not specified, then a default index will be used as configured below.  The value is comma-separated,
# so that if the user does not have access to the first index, then next will be tried and so forth.
# Note:  all sources should have attributes configured for all default indexes.
# {valueType: "integer", required: true}
member.search.defaultIndexOrder=0

# {valueType: "integer", required: true}
member.sort.defaultIndexOrder=0


###################################
## Database confirmation of changes
## whitelist (allow) and blacklist (deny) for db/ldap data or object deletes, without prompting the user to confirm
## if a listing is in the whitelist (allow), it will be allowed to delete db/ldap
## if a listing is in the blacklist (deny), it will be denied from deleting db/ldap
## multiple inputs can be entered with .0, .1, .2, etc.  These numbers must be sequential, starting with 0
## for ldap, the user will be something like this: uid=admin,ou=system
## for ldap, the url will be something like this: ldap://localhost:10389
###################################

# allow this database user to make changes to the DDL without confirmation (e.g. non-prod, testing)
# {valueType: "string", required: true, regex: "^db\\.change\\.allow\\.user\\.([0-9]+)$"}
db.change.allow.user.0=grouper_v5abc

# allow this database user to make changes to the DDL without confirmation (e.g. non-prod, testing)
# {valueType: "string", required: true, regex: "^db\\.change\\.allow\\.url\\.([0-9]+)$"}
db.change.allow.url.0=jdbc:postgresql://localhost:5432/postgres?currentSchema=grouper_v5abc

# allow this database user to make changes to the DDL without confirmation (e.g. non-prod, testing)
# {valueType: "string", required: true, regex: "^db\\.change\\.allow\\.user\\.([0-9]+)$"}
db.change.allow.user.1=grouper1

# allow this database user to make changes to the DDL without confirmation (e.g. non-prod, testing)
# {valueType: "string", required: true}
db.change.allow.url.1=jdbc:mysql://localhost:3306/grouper1?useSSL=false

# allow this database user to make changes to the DDL without confirmation (e.g. non-prod, testing)
# {valueType: "string", required: true}
db.change.deny.user.0=grouper2

# allow this database user to make changes to the DDL without confirmation (e.g. non-prod, testing)
# {valueType: "string", required: true}
db.change.deny.url.0=jdbc:mysql://localhost:3306/grouper2?useSSL=false

# if should give error when detect driver mismatch (set to false if using an
# unknown driver, and tell the grouper team so we can add to list)
# {valueType: "boolean", required: true}
db.log.driver.mismatch = true

###################################
## Grouper include / exclude and requireGroups
## If enabled, will make sure the Type is installed, and when that type is
## applied to a group, it will auto-create the other groups needed to manage the include and exclude lists
## see: https://bugs.internet2.edu/jira/browse/GRP-178
## the naming settings below are only used when the type is applied to a group, will not affect
## existing include/exclude groups
###################################

#if the addIncludeExclude and requireInGroups should be enabled, and if the type(s) should be
#auto-created, and used to auto create groups to facilitate include and exclude lists, and require lists
# {valueType: "boolean", required: true}
grouperIncludeExclude.use = false

# {valueType: "boolean", required: true}
grouperIncludeExclude.requireGroups.use = false

# for requireGroups (groups that the members must be to be in the overall group).  name is the name of the attribute or type.
# note attributes are a global namespace, so you might want to use a naming convention,
# e.g. prefix with "require".   increment the integer to add multiple
# {valueType: "string", required: true, regex: "^grouperIncludeExclude\\.requireGroup\\.name\\.([0-9]+)$"}
#grouperIncludeExclude.requireGroup.name.0 = requireActiveEmployee

# requireGroups: attributeOrType is either attribute for an attribute underneath the requireInGroups type, or type to be a top level type.
# increment the integer to add multiple
# {valueType: "string", required: true, regex: "^grouperIncludeExclude\\.requireGroup\\.attributeOrType\\.([0-9]+)$"}
#grouperIncludeExclude.requireGroup.attributeOrType.0 = type

# requireGroups: group that is required ("and"ed).   increment the integer to add multiple
# {valueType: "group", required: true, regex: "^grouperIncludeExclude\\.requireGroup\\.group\\.([0-9]+)$"}
#grouperIncludeExclude.requireGroup.group.0 = school:community:activeEmployee

# requireGroups: description is the tooltip.   increment the integer to add multiple
# {valueType: "string", regex: "^grouperIncludeExclude\\.requireGroup\\.description\\.([0-9]+)$"}
#grouperIncludeExclude.requireGroup.description.0 = If value is true, members of the overall group must be an active employee (in the school:community:activeEmployee group).  Otherwise, leave this value not filled in.


# set name for include/exclude
# {valueType: "string"}
grouperIncludeExclude.type.name = addIncludeExclude

# set tooltip for include/exclude
# {valueType: "string"}
grouperIncludeExclude.tooltip = Select this type to auto-create other groups which facilitate having include and exclude list

# set name for requireGroups
# {valueType: "string"}
grouperIncludeExclude.requireGroups.type.name = requireInGroups

# set tooltip for requireGroups
# {valueType: "string"}
grouperIncludeExclude.requireGroups.tooltip = Select this type to auto-create other groups which set up group math so that other groups can be required for membership (e.g. activeEmployee)

# require also in groups (ad hoc)
# leave grouperIncludeExclude.andGroups.attributeName blank if you dont want to use this attribute...
# though if you were using it, it wont remove already configured groups
# {valueType: "string"}
grouperIncludeExclude.requireGroups.attributeName = requireAlsoInGroups

# toolip for require also in groups
# {valueType: "string"}
grouperIncludeExclude.requireGroups.attribute.tooltip = Enter in comma separated group path(s).  An entity must be in these groups for it to be in the overall group.  e.g. stem1:stem2:group1, stem1:stem3:group2

#suffixes for various include/exclude groups (can use ${space} for space).
#note, these should uniquely identify various parts of the include/exclude.
#i.e. if the grouperIncludeExclude type is applied to a group with a suffix of the include suffix,
#the other groups will not be created...
# {valueType: "string"}
grouperIncludeExclude.systemOfRecord.extension.suffix = _systemOfRecord

# suffix for include group of include/exclude
# {valueType: "string"}
grouperIncludeExclude.include.extension.suffix = _includes

# suffix for exclude group of include/exclude
# {valueType: "string"}
grouperIncludeExclude.exclude.extension.suffix = _excludes

# suffix for system-of_record and includes (virtual union) group of include/exclude
# {valueType: "string"}
grouperIncludeExclude.systemOfRecordAndIncludes.extension.suffix = _systemOfRecordAndIncludes

# suffix for includes minus excludes group of include/exclude
# {valueType: "string"}
grouperIncludeExclude.includesMinusExcludes.extension.suffix = _includesMinusExcludes

# suffix of the require groups helper group
# note, put a ${i} in there for where the 1 based index will go
# {valueType: "string"}
grouperIncludeExclude.requireGroups.extension.suffix = _requireGroups${i}

# display extension suffix for system of record group
# suffixes for various include/exclude groups (can use ${space} for space)
# {valueType: "string"}
grouperIncludeExclude.systemOfRecord.displayExtension.suffix = ${space}system of record

# display extension suffix for include group
# {valueType: "string"}
grouperIncludeExclude.include.displayExtension.suffix = ${space}includes

# display extension suffix for exclude group
# {valueType: "string"}
grouperIncludeExclude.exclude.displayExtension.suffix = ${space}excludes

# display extension suffix for system of record and include group
# {valueType: "string"}
grouperIncludeExclude.systemOfRecordAndIncludes.displayExtension.suffix = ${space}system of record and includes

# display extension suffix for include minus exclude group.  this is used if you have include/exclude and requireGroups
# {valueType: "string"}
grouperIncludeExclude.includesMinusExcludes.displayExtension.suffix = ${space}includes minus excludes

# require gruops display extension suffix.
# note, put a ${i} in there for where the 1 based index will go
# {valueType: "string"}
grouperIncludeExclude.requireGroups.displayExtension.suffix = ${space}requireGroups ${i}

# include/exclude overall description
#can use ${extension} as the group extension, or ${displayExtension} for group display extension
# {valueType: "string"}
grouperIncludeExclude.overall.description = Group containing list of ${displayExtension} after adding the includes and subtracting the excludes

# include/exclude systemOfRecord description
# {valueType: "string"}
grouperIncludeExclude.systemOfRecord.description = Group containing list of ${displayExtension} (generally straight from the system of record) without yet considering manual include or exclude lists

# include/exclude include description
# {valueType: "string"}
grouperIncludeExclude.include.description = Group containing manual list of includes for group ${displayExtension} which will be added to the system of record list (unless the subject is also in the excludes group)

# include/exclude exclude description
# {valueType: "string"}
grouperIncludeExclude.exclude.description = Group containing manual list of excludes for group ${displayExtension} which will not be in the overall group

# include/exclude systemOfRecord-and-includes description
# {valueType: "string"}
grouperIncludeExclude.systemOfRecordAndIncludes.description = Internal utility group for group ${displayExtension} which facilitates the group math for the include and exclude lists

# include/exclude includes minus excludes description
# {valueType: "string"}
grouperIncludeExclude.includesMinusExclude.description = Internal utility group for group ${displayExtension} which facilitates includes, excludes, and required groups (e.g. activeEmployee)

# requireGroups description
# note, put a ${i} in there for where the 1 based index will go
# {valueType: "string"}
grouperIncludeExclude.requireGroups.description = Internal utility group for group ${displayExtension} which facilitates required groups (e.g. activeEmployee)

# if should use transaction in include/exclude
# {valueType: "boolean", required: true}
grouperIncludeExcludeUseTransaction = true


###################################
## Composites
###################################

# When immediate membership changes are made, if the group being modified matches this regex, 
# then composite membership changes will be made synchronously instead of by the daemon
# {valueType: "string"}
composites.synchronousCalculationGroupNameRegex =

###################################
## Subject settings
###################################

# if finding across multiple threadable sources, use threads to do the work faster
# {valueType: "boolean", required: true}
subjects.allPage.useThreadForkJoin = false

# if finding across multiple threadable sources, use threads to do the work faster
# {valueType: "boolean", required: true}
subjects.idOrIdentifier.useThreadForkJoin = false

# if the creator and last updater should be group subject attributes (you get
# a performance gain if you set to false, but if true you can see subject id from UI in 2.0
# {valueType: "boolean", required: true}
subjects.group.useCreatorAndModifierAsSubjectAttributes = true

# customize subjects by implementing this interface: edu.internet2.middleware.grouper.subj.SubjectCustomizer
# or extending this class: edu.internet2.middleware.grouper.subj.SubjectCustomizerBase (recommended)
# note the instance will be reused to make sure it is threadsafe
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.subj.SubjectCustomizerBase"}
subjects.customizer.className =

# if we should use a root session if one isnt started for subject lookups (behavior in v2.0-
# {valueType: "boolean", required: true}
subjects.startRootSessionIfOneIsntStarted = false

###################################
## Hooks
## You can register multiple classes for one hook base class by comma separating the hooks implementations
## You can also register hooks at runtime with:
## GrouperHookType.addHookManual("hooks.group.class", YourSchoolGroupHooks2.class);
###################################

#implement a group attribute hook by extending edu.internet2.middleware.grouper.hooks.AttributeHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.AttributeHooks"}
#hooks.attribute.class=edu.yourSchool.it.YourSchoolGroupHooks,edu.yourSchool.it.YourSchoolGroupHooks2

#implement an attribute def hook by extending edu.internet2.middleware.grouper.hooks.AttributeDefHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.AttributeDefHooks"}
#hooks.attributeDef.class=edu.yourSchool.it.YourSchoolAttributeDefHooks,edu.yourSchool.it.YourSchoolAttributeDefHooks2

#implement an attribute def name hook by extending edu.internet2.middleware.grouper.hooks.AttributeDefNameHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.AttributeDefNameHooks"}
#hooks.attributeDefName.class=edu.yourSchool.it.YourSchoolAttributeDefNameHooks,edu.yourSchool.it.YourSchoolAttributeDefNameHooks2

#implement an attribute assign hook by extending edu.internet2.middleware.grouper.hooks.AttributeAssignHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.AttributeAssignHooks"}
#hooks.attributeAssign.class=edu.yourSchool.it.YourSchoolAttributeAssignHooks,edu.yourSchool.it.YourSchoolAttributeAssignHooks2

#implement an attribute assign hook by extending edu.internet2.middleware.grouper.hooks.AttributeAssignValueHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.AttributeAssignValueHooks"}
#hooks.attributeAssignValue.class=edu.yourSchool.it.YourSchoolAttributeAssignValueHooks,edu.yourSchool.it.YourSchoolAttributeAssignValueHooks2

#implement a group hook by extending edu.internet2.middleware.grouper.hooks.GroupHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.GroupHooks"}
#hooks.group.class=edu.yourSchool.it.YourSchoolGroupHooks,edu.yourSchool.it.YourSchoolGroupHooks2

#implement a grouper lifecycle hook by extending edu.internet2.middleware.grouper.hooks.LifecycleHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.LifecycleHooks"}
#hooks.lifecycle.class=edu.yourSchool.it.YourSchoolLifecycleHooks

#implement a membership hook by extending edu.internet2.middleware.grouper.hooks.MembershipHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.MembershipHooks"}
#hooks.membership.class=edu.yourSchool.it.YourSchoolMembershipHooks

#implement a member hook by extending edu.internet2.middleware.grouper.hooks.MemberHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.MemberHooks"}
#hooks.member.class=edu.yourSchool.it.YourSchoolMemberHooks

#implement a stem hook by extending edu.internet2.middleware.grouper.hooks.StemHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.StemHooks"}
#hooks.stem.class=edu.yourSchool.it.YourSchoolStemHooks

#implement a composite hook by extending edu.internet2.middleware.grouper.hooks.CompositeHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.CompositeHooks"}
#hooks.composite.class=edu.yourSchool.it.YourSchoolCompositeHooks

#implement a field hook by extending edu.internet2.middleware.grouper.hooks.FieldHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.FieldHooks"}
#hooks.field.class=edu.yourSchool.it.YourSchoolFieldHooks

#implement a grouperSession hook by extending edu.internet2.middleware.grouper.hooks.GrouperSessionHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.GrouperSessionHooks"}
#hooks.grouperSession.class=edu.yourSchool.it.YourSchoolGrouperSessionHooks

#implement a groupType hook by extending edu.internet2.middleware.grouper.hooks.GroupTypeHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.GroupTypeHooks"}
#hooks.groupType.class=edu.yourSchool.it.YourSchoolGroupTypeHooks

#implement a groupTypeTuple hook by extending edu.internet2.middleware.grouper.hooks.GroupTypeTupleHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.GroupTypeTupleHooks"}
#hooks.groupTypeTuple.class=edu.yourSchool.it.YourSchoolGroupTypeTupleHooks

#implement a loader hook by extending edu.internet2.middleware.grouper.hooks.LoaderHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.LoaderHooks"}
#hooks.loader.class=edu.yourSchool.it.YourSchoolLoaderHooks

#implement an external subject hook by extending edu.internet2.middleware.grouper.hooks.ExternalSubjectHooks
# {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.hooks.ExternalSubjectHooks"}
#hooks.externalSubject.class=edu.yourSchool.it.YourSchoolExternalSubjectHooks

# if the edu.internet2.middleware.grouper.hooks.examples.GroupUniqueExtensionHook is case insensitive
# {valueType: "boolean", required: true}
hook.group.unique.extension.caseInsensitive = false

# if the auto assign attribute assign hook should be auto registered
# {valueType: "boolean", required: true}
grouperHook.attributeAssign.autoAssign.autoRegister = true

# if the auto register hook checks groups to see if new memberships are valid
# {valueType: "boolean", required: true}
grouperHook.MembershipRequireMembershipHook.autoRegister = true

# if the auto register hook checks stems with same name case insensitive
# {valueType: "boolean", required: true}
grouperHook.StemUniqueNameCaseInsensitiveHook.autoRegister = true

# if the auto register hook checks groups with same name case insensitive
# {valueType: "boolean", required: true}
grouperHook.GroupUniqueNameCaseInsensitiveHook.autoRegister = true

# if the auto register hook checks attribute defs with same name case insensitive
# {valueType: "boolean", required: true}
grouperHook.AttributeDefUniqueNameCaseInsensitiveHook.autoRegister = true

# if the auto register hook checks attribute def names with same name case insensitive
# {valueType: "boolean", required: true}
grouperHook.AttributeDefNameUniqueNameCaseInsensitiveHook.autoRegister = true

# if the hook to veto deprovisioned users should be registered
# {valueType: "boolean", required: true}
grouperHook.MembershipVetoIfDeprovisionedHook.autoRegister = true

###################################
## Rules
###################################

# Rules users who are in the following group can use the actAs field to act as someone else
# You can put multiple groups separated by commas.  e.g. a:b:c, e:f:g
# You can put a single entry as the group the calling user has to be in, and the grouper the actAs has to be in
# separated by 4 colons
# e.g. if the configured values is:       a:b:c, e:f:d :::: r:e:w, x:e:w
# then if the calling user is in a:b:c or x:e:w, then the actAs can be anyone
# if not, then if the calling user is in e:f:d, then the actAs must be in r:e:w.  If multiple rules, then
# if one passes, then it is a success, if they all fail, then fail.
# {valueType: "string"}
rules.act.as.group =

# any actAs subject in this group has access to more objects when the EL fires on
# the IF or THEN EL clause
# {valueType: "group"}
rules.accessToApiInEl.group =

# cache the decision to allow a user to actAs another, so it doesnt have to be calculated each time
# defaults to 30 minutes
# {valueType: "integer", required: true}
rules.act.as.cache.minutes = 30

# uuids (comma separated) of the attribute assign record which is the rule type to the owner object
# e.g. SELECT gaagv.attribute_assign_id FROM grouper_attr_asn_group_v gaagv WHERE gaagv.attribute_def_name_name LIKE '%:rule' AND gaagv.group_name = 'stem:a'
# make sure log info level is set for RuleEngine
# log4j.logger.edu.internet2.middleware.grouper.rules.RuleEngine = INFO
# {valueType: "string"}
rules.attributeAssignTypeIdsToLog = abc1234abc123, def456def345

# if this is true, then log a lot of info about why rules do or do not fire... only turn on temporarily
# since it takes a lot of resources...  note you need log DEBUG set for the rules engine in log4j.properties too e.g.
# log4j.logger.edu.internet2.middleware.grouper.rules = DEBUG
# {valueType: "boolean", required: true}
rules.logWhyRulesDontFire = false

# put in fully qualified classes to add to the EL context.  Note that they need a default constructor
# comma separated.  The alias will be the simple class name without a first cap.
# e.g. if the class is test.Test the alias is "test"
# {valueType: "class", multiple: true}
rules.customElClasses =

# If the CHECK, IF, and THEN are all exactly what is needed for managing inherited stem privileges
# Then allow an actAs GrouperSystem in source g:isa
# {valueType: "boolean", required: true}
rules.allowActAsGrouperSystemForInheritedStemPrivileges =

# If not blank, then keep email templates in this folder instead of classpath
# If in classpath, it is classpath: grouperRulesEmailTemplates/someTemplate.txt
# {valueType: "string"}
rules.emailTemplatesFolder =

# If not blank, then only allow members of this group to create rules in the UI
# {valueType: "string"}
rules.restrictRulesUiToMembersOfThisGroupName = 

# If not blank, then only allow members of this group to send emails from rules
# {valueType: "string"}
rules.restrictRulesEmailSendersToMembersOfThisGroupName = 

# If not blank, then rules associated with these groups require at least VIEW access on the groups and folders associated with the rules 
# {valueType: "string"}
rules.groupNamesRestrictRules =

# If not blank, then rules associated with these folders require at least VIEW access on the groups and folders associated with the rules 
# {valueType: "string"}
rules.stemNamesRestrictRules =

# if in daemon check to see if restricted folders have memberships or privileges from subjects in restricted group
# and remove them
# {valueType: "boolean", required: true}
grouperRuleDaemon_GRP_2143_Remove_memberships_from_restricted_stem_when_removed_from_dependent_group = true

# if in change log check to see if removed users from restricted group has memberships or privileges in folders
# and remove them
# {valueType: "boolean", required: true}
grouperRuleChangeLog_GRP_2143_Remove_memberships_from_restricted_stem_when_removed_from_dependent_group = true

###################################
## Group attribute validation via regex
## You can attach a regex to an attribute name (including built ins)
## If none are registered, the built in hook will not be enabled
## The built ins are description, displayName, extension, displayExtension, name
## Configure a group.attribute.validator.attributeName.X for attribute name
## group.attribute.validator.regex.X for the regex
## group.attribute.validator.vetoMessage.X for the veto message (can contain the variable $attributeValue$ which will substitute)
## the X must be a sequential integer which groups the config entries together.
## do not repeat two config entries
###################################

# if there is not another group extension validation, then validate by alphanumerics, underscore, and dash
# {valueType: "boolean", required: true}
group.validateExtensionByDefault = true

# if there is not another stem extension validation, then validate by alphanumerics, underscore, and dash
# {valueType: "boolean", required: true}
stem.validateExtensionByDefault = true

# if there is not another attributeDef extension validation, then validate by alphanumerics, underscore, and dash
# {valueType: "boolean", required: true}
attributeDef.validateExtensionByDefault = true

# if there is not another attributeDefName extension validation, then validate by alphanumerics, underscore, and dash
# {valueType: "boolean", required: true}
attributeDefName.validateExtensionByDefault = true

# Attach a regex validator by attribute name.  This is the attribute name
# {valueType: "string", required: true, regex: "^group\\.attribute\\.validator\\.attributeName\\.([0-9]+)$"}
# group.attribute.validator.attributeName.0=extension

# Attach a regex validator by attribute name. This is the regex
# {valueType: "string", required: true, regex: "^group\\.attribute\\.validator\\.regex\\.([0-9]+)$"}
# group.attribute.validator.regex.0=^[a-zA-Z0-9]+$

# Attach a regex validator by attribute name.  This is the veto message if a group create has an invalid attribute
# {valueType: "string", required: true, regex: "^group\\.attribute\\.validator\\.vetoMessage\\.([0-9]+)$"}
# group.attribute.validator.vetoMessage.0=Group ID '$attributeValue$' is invalid since it must contain only alpha-numerics


###################################
## Stem attribute validation via regex
## You can attach a regex to an attribute name (including built ins)
## If none are registered, the built in hook will not be enabled
## The built ins are description, displayName, extension, displayExtension, name
## Configure a stem.attribute.validator.attributeName.X for attribute name
## stem.attribute.validator.regex.X for the regex
## stem.attribute.validator.vetoMessage.X for the veto message (can contain the variable $attributeValue$ which will substitute)
## the X must be a sequential integer which groups the config entries together.
## do not repeat two config entries
###################################

# Attach a regex validator by attribute name.  This is the attribute name
# {valueType: "string", required: true, regex: "^stem\\.attribute\\.validator\\.attributeName\\.([0-9]+)$"}
# stem.attribute.validator.attributeName.0=extension

# Attach a regex validator by attribute name. This is the regex
# {valueType: "string", required: true, regex: "^stem\\.attribute\\.validator\\.regex\\.([0-9]+)$"}
# stem.attribute.validator.regex.0=^[a-zA-Z0-9]+$

# Attach a regex validator by attribute name.  This is the veto message if a stem create has an invalid attribute
# {valueType: "string", required: true, regex: "^stem\\.attribute\\.validator\\.vetoMessage\\.([0-9]+)$"}
# stem.attribute.validator.vetoMessage.0=Stem ID '$attributeValue$' is invalid since it must contain only alpha-numerics

###################################
## Attribute def field validation via regex
## You can attach a regex to a field name (including built ins)
## If none are registered, the built in hook will not be enabled
## The built ins are description, extension, name
## Configure a attributeDef.attribute.validator.attributeName.X for attribute name
## attributeDef.attribute.validator.regex.X for the regex
## attributeDef.attribute.validator.vetoMessage.X for the veto message (can contain the variable $attributeValue$ which will substitute)
## the X must be a sequential integer which groups the config entries together.
## do not repeat two config entries
###################################

# Attach a regex validator by field name.  This is the field name
# {valueType: "string", required: true, regex: "^attributeDef\\.attribute\\.validator\\.attributeName\\.([0-9]+)$"}
# attributeDef.attribute.validator.attributeName.0=extension

# Attach a regex validator by field name. This is the regex
# {valueType: "string", required: true, regex: "^attributeDef\\.attribute\\.validator\\.regex\\.([0-9]+)$"}
# attributeDef.attribute.validator.regex.0=^[a-zA-Z0-9]+$

# Attach a regex validator by field name.  This is the veto message if an attributeDef create has an invalid field
# {valueType: "string", required: true, regex: "^attributeDef\\.attribute\\.validator\\.vetoMessage\\.([0-9]+)$"}
# attributeDef.attribute.validator.vetoMessage.0=AttributeDef ID '$attributeValue$' is invalid since it must contain only alpha-numerics

###################################
## Attribute def name field validation via regex
## You can attach a regex to a field name (including built ins)
## If none are registered, the built in hook will not be enabled
## The built ins are description, displayName, extension, displayExtension, name
## Configure a attributeDefName.attribute.validator.attributeName.X for attribute name
## attributeDefName.attribute.validator.regex.X for the regex
## attributeDefName.attribute.validator.vetoMessage.X for the veto message (can contain the variable $attributeValue$ which will substitute)
## the X must be a sequential integer which groups the config entries together.
## do not repeat two config entries
###################################

# Attach a regex validator by field name.  This is the field name
# {valueType: "string", required: true, regex: "^attributeDefName\\.attribute\\.validator\\.attributeName\\.([0-9]+)$"}
#attributeDefName.attribute.validator.attributeName.0=extension

# Attach a regex validator by attribute name. This is the regex
# {valueType: "string", required: true, regex: "^attributeDefName\\.attribute\\.validator\\.regex\\.([0-9]+)$"}
#attributeDefName.attribute.validator.regex.0=^[a-zA-Z0-9]+$

# Attach a regex validator by attribute name.  This is the veto message if an attributeDefName create has an invalid attribute
# {valueType: "string", required: true, regex: "^attributeDefName\\.attribute\\.validator\\.vetoMessage\\.([0-9]+)$"}
#attributeDefName.attribute.validator.vetoMessage.0=AttributeDefName ID '$attributeValue$' is invalid since it must contain only alpha-numerics



#####################################
## Audit settings
#####################################

# if set to true, then exceptions will be thrown if any actions are not audited... exceptions
# should not be thrown since everything should be audited, so this is a switch to make it absorb
# errors if there is a problem (will be logged instead if second param is true)
# {valueType: "boolean", required: true}
audit.requireAuditsForAllActions = false

# if should log audits for missing actions
# {valueType: "boolean", required: true}
audit.logAuditsForMissingActions = false

# max length of text fields in audit if the DB has a constraint.  Might need to set to 2675 for some versions / configs of postgres
# {valueType: "integer", required: true}
audit.maxLengthTruncateTextFieldsIndexed = 4000

#####################################
## Change log settings
#####################################

# if we should insert records into grouper_change_log_temp when events happen
# defaults to true.  Note, it is not currently supported to set this to false...
# {valueType: "boolean", required: true}
changeLog.enabled = true


#####################################
## Settings to track last membership changes for groups and stems.
#####################################

# If true, when an immediate membership changes for a group (either a privilege or a list member),
# then an update will be made to the lastImmediateMembershipChange property for the group.
# {valueType: "boolean", required: true}
groups.updateLastImmediateMembershipTime = false

# If true, when an immediate, composite, or effective membership changes for a group (either a privilege or a list member),
# then an update will be made to the lastMembershipChange property for the group.
# {valueType: "boolean", required: true}
groups.updateLastMembershipTime = false

# If true, when an immediate or effective membership changes for a stem (this would be a naming privilege),
# then an update will be made to the lastMembershipChange property for the stem.
# {valueType: "boolean", required: true}
stems.updateLastMembershipTime = false


#####################################
## Database structure data definition language (DDL) settings
#####################################

# ddlutils db name will be set by default, you can override it here, it must be one of:
# mysql, mysql5, oracle, oracle10, oracle9, postgresql
# {valueType: "string"}
#ddlutils.dbname.override = oracle10

# if you want to not create the subject tables (grouper examples for unit testing),
# then set this to true
# {valueType: "boolean", required: true}
ddlutils.exclude.subject.tables = false

# set the path where ddl scripts are generated (they will be uniquely named in this directory).
# if blank, the directory used will be the current directory
# {valueType: "string"}
ddlutils.directory.for.scripts = ddlScripts

# during schema export, should it install grouper data also or not.  e.g. insert the root stem, default true
# {valueType: "boolean", required: true}
ddlutils.schemaexport.installGrouperData = true

# when grouper starts, should it shut down if not right version?
# {valueType: "boolean", required: true}
ddlutils.failIfNotRightVersion = true

# after you have converted id's, and are happy with the conversion of removing the uuid col,
# this will remove the backup uuid cols when running the gsh command: gsh -registry -deep
# {valueType: "boolean", required: true}
ddlutils.dropBackupUuidCols = false

# after you have converted field id foreign keys, and are happy with the conversion of removing the attribute name,
# membership list name, and type cols,
# this will remove the backup field name/type cols when running the gsh command: gsh -registry -deep
# {valueType: "boolean", required: true}
ddlutils.dropBackupFieldNameTypeCols = false

# before the group name etc was moved to the grouper_groups table, the attributes table
# was backed up.  If it should not be backed up, or if the upgrade is done and works, then it can
# be removed, set to true, run: gsh -registry -deep
# {valueType: "boolean", required: true}
ddlutils.dropAttributeBackupTableFromGroupUpgrade = false

# Since grouper_memberships no longer has effective memberships, that table doesn't need via_id,
# depth and parent_membership.  If they were converted, this will drop the backup of those cols with: gsh -registry -deep
# {valueType: "boolean", required: true}
ddlutils.dropMembershipBackupColsFromOwnerViaUpgrade = false

# After legacy attributes are converted, the backed up tables can be dropped with: gsh -registry -deep
# {valueType: "boolean", required: true}
ddlutils.dropLegacyAttributes = false

# this is the schema ddlutils uses to query metadata with jdbc.  usually this can be omitted,
# and it defaults to your database loginid, however, in postgres, it can be different, so enter here
# in sql server, it might need to be: dbo
# {valueType: "string"}
#ddlutils.schema = public

#if you are running a DB that supports them, but you dont want them, disable comments here (defaults to false)
# {valueType: "boolean", required: true}
ddlutils.disableComments = false

#set to true and we wont subsitute varchar 4000 for text in mysql (wont work in innodb utf-8 databases
# {valueType: "boolean", required: true}
ddlutils.dontSubstituteVarchar4000forTextMysql = false

# this is obscure, but if you are having trouble with direct sql for attribute updates, set this to false
# {valueType: "boolean", required: true}
grouperAllowSqlOnAttributeValueUpdate = true

# if you want to change the max size for names of groups.  Note, cant be larger than the
# database column and unicode might take extra chars.  i.e. if you want to make it smaller that is fine.
# this is for object name and display name
# the default is 1024 or 900 for SQL server
# {valueType: "integer"}
grouper.groupName.maxSize =

# if you want to change the max size for names of attributeDefs.  Note, cant be larger than the
# database column and unicode might take extra chars.  i.e. if you want to make it smaller that is fine.
# this is for object name and display name
# the default is 1024 or 900 for SQL server
# {valueType: "integer"}
grouper.nameOfAttributeDef.maxSize =

# if you want to change the max size for names of attributeDefNames.  Note, cant be larger than the
# database column and unicode might take extra chars.  i.e. if you want to make it smaller that is fine.
# this is for object name and display name
# the default is 1024 or 900 for SQL server
# {valueType: "integer"}
grouper.nameOfAttributeDefName.maxSize =

# if you want to change the max size for names of folders.  Note, cant be larger than the
# database column and unicode might take extra chars.  i.e. if you want to make it smaller that is fine.
# this is for object name and display name
# the default is 1024 or 900 for SQL server
# default for stem name in 2.3 and before is 255: GRP-1807: grouper folder names limited to 255 but should be longer
# {valueType: "integer"}
grouper.stemName.maxSize =

#####################################
## Mail settings
#####################################

#smtp server is a domain name or dns name.  set to "testing" if you want to log instead of send. eg: whatever.school.edu
# {valueType: "string"}
mail.smtp.server =

#leave blank if unauthenticated
# {valueType: "string"}
#mail.smtp.user =

#leave blank if unauthenticated
# {valueType: "password", sensitive: true}
#mail.smtp.pass =

# comma separated group name and uuid's to be allow email addresses to dereference.
# for instance: a:b:c@grouper, def345@grouper
# If a configuration enters in one of those email addresses, and it is in this allow list, then # dereference the group and member and send email to their individual email addresses. Note that # groups in this list can have their members discovered so treat their membership as non private. # using the uuid@grouper gives a little bit of obscurity since the uuid of the group needs to be known # is it is still security by obscurity which is not true security. There is a max of 100 members it will # send to # {valueType: "string", multiple: true} mail.smtp.groupUuidAndNameEmailDereferenceAllow = #leave blank or false for no ssl, true for ssl # {valueType: "boolean"} mail.smtp.ssl = false # leave blank or false for no tls, true for tls # {valueType: "boolean"} mail.smtp.starttls.enable = false # if you are doing SSL/TLS, you should put the smtp server here so it is trusted # {valueType: "string"} mail.smtp.ssl.trust = #leave blank for default (probably 25), if ssl is true, default is 465, else specify # {valueType: "integer"} #mail.smtp.port = # mail transport protocol you generally dont need to change # {valueType: "string", defaultValue: "smtp"} mail.smtp.transport.protocol = # in the java mail settings if "smtp" or whatever the protocol is should be in the property names # {valueType: "boolean", defaultValue: "true"} mail.smtp.use.protocol.in.property.names = # if you have trouble connecting to SSL/TLS, try a different SSL protocol, e.g. TLSv1.2 # {valueType: "string"} # mail.smtp.ssl.protocols = # generally saying SSL true is enough, though you might need to set a class. generally leasve this blank # {valueType: "string"} # mail.smtp.socketFactory.class = # generally you will leave this blank unless doing something advanced # {valueType: "boolean"} # mail.smtp.socketFactory.fallback = #this is the default email address where mail from grouper will come from. eg: [email protected] # {valueType: "string", required: true} mail.smtp.from.address = #this is the subject prefix of emails, which will help differentiate prod vs test vs dev etc. eg: TEST: #note, you can use $space$ to put a space at the end of the config, otherwise it will be trimmed. # {valueType: "string"} mail.smtp.subject.prefix = # in non-prod send all messages to this address to see what messages would have been sent out (or comma separate multiple addresses). # if you set addresses here, no real email will be sent out. eg: [email protected] # {valueType: "string"} mail.smtp.sendAllMessagesHere = # if debug info from java mail should be printed # {valueType: "boolean", defaultValue: "false"} mail.smtp.debug = # if this smtp connector is enabled # {valueType: "boolean", defaultValue: "true"} # mail.smtp.enabled = # content type, default is: text/plain; charset=utf-8 # {valueType: "string"} mail.smtp.grouperEmailContentType = # external system test "to" address type: emailAddress, emailToSubject, emailToGroup # {valueType: "string", required: true, formElement: "dropdown", optionValues: ["emailAddress", "emailToSubject", "emailToGroup"]} mail.smtp.externalSystemTestToType = # external system test "to" address # {valueType: "string", required: true, showEl: "${externalSystemTestToType == 'emailAddress'}"} mail.smtp.externalSystemTestToAddress = # external system test "to" source id, required if not providing an "External system to address" # {valueType: "string", required: true, showEl: "${externalSystemTestToType == 'emailToSubject'}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.subject.provider.SourceManagerOptionValueDriver"} mail.smtp.externalSystemTestToSubjectSourceId = # external system test "to" subject id, required if not providing an "External system to address" though mutually exclusive # {valueType: "string", required: true, showEl: "${externalSystemTestToType == 'emailToSubject'}", formElement: "dropdown", optionValues: ["subjectId", "subjectIdentifier"]} mail.smtp.externalSystemTestToSubjectIdType = # external system test "to" subject id, required if not providing an "External system to address" though mutually exclusive # {valueType: "string", required: true, showEl: "${externalSystemTestToType == 'emailToSubject' && externalSystemTestToSubjectIdType == 'subjectId'}"} mail.smtp.externalSystemTestToSubjectId = # external system test "to" subject id, required if not providing an "External system to address" though mutually exclusive # {valueType: "string", required: true, showEl: "${externalSystemTestToType == 'emailToSubject' && externalSystemTestToSubjectIdType == 'subjectIdentifier'}"} mail.smtp.externalSystemTestToSubjectIdentifier = # external system test "to" a group. Send to group UUID or name? # {valueType: "string", required: true, showEl: "${externalSystemTestToType == 'emailToGroup'}", formElement: "dropdown", optionValues: ["groupUuid", "groupName"]} mail.smtp.externalSystemTestToGroupIdType = # external system test "to" group UUID # {valueType: "string", required: true, showEl: "${externalSystemTestToType == 'emailToGroup' && externalSystemTestToGroupIdType == 'groupUuid'}"} mail.smtp.externalSystemTestToGroupId = # external system test "to" group name # {valueType: "string", required: true, showEl: "${externalSystemTestToType == 'emailToGroup' && externalSystemTestToGroupIdType == 'groupName'}"} mail.smtp.externalSystemTestToGroupName = # subject of email # {valueType: "string", required: true} mail.smtp.externalSystemTestSubject = # body of email # {valueType: "string", required: true, formElement: "textarea"} mail.smtp.externalSystemTestBody = # cc of email # {valueType: "string"} mail.smtp.externalSystemTestCcAddress = # bcc of email # {valueType: "string"} mail.smtp.externalSystemTestBccAddress = # from of email. Will default to the global default from address # {valueType: "string"} mail.smtp.externalSystemTestFromAddress = # comma separated reply-to addresses of email. Will default to the global default from address # {valueType: "string"} mail.smtp.externalSystemTestReplyAddresses = # when running junit tests, this is the address that will be used. eg: [email protected] # {valueType: "string"} # mail.test.address = ##################################### ## Performance timers ##################################### # if log performance info on GroupSave # set in log4j2.xml: log4j.logger.edu.internet2.middleware.grouper.util.PerformanceLogger = INFO # {valueType: "boolean", required: true} grouper.log.performance.info.on.GroupSave = false # if log performance info on StemSave # set in log4j2.xml: log4j.logger.edu.internet2.middleware.grouper.util.PerformanceLogger = INFO # {valueType: "boolean", required: true} grouper.log.performance.info.on.StemSave = false # if log performance info on Stem view screen # set in log4j2.xml: log4j.logger.edu.internet2.middleware.grouper.util.PerformanceLogger = INFO # {valueType: "boolean", required: true} grouper.log.performance.info.on.StemUiView = false # if log performance info on Stem more actions # set in log4j2.xml: log4j.logger.edu.internet2.middleware.grouper.util.PerformanceLogger = INFO # {valueType: "boolean", required: true} grouper.log.performance.info.on.StemUiMoreActions = false # if log performance info on left tree menu # set in log4j2.xml: log4j.logger.edu.internet2.middleware.grouper.util.PerformanceLogger = INFO # {valueType: "boolean", required: true} grouper.log.performance.info.on.UiTreeMenu = false ##################################### ## Misc settings which probably dont need to be changed ##################################### # dao factory has no other options and shouldnt be changed # {valueType: "class", required: true, mustExtendClass: "edu.internet2.middleware.grouper.misc.GrouperDAOFactory"} dao.factory = edu.internet2.middleware.grouper.internal.dao.hib3.Hib3DAOFactory # if tables that are hibernated should have optimistic locking or not (assumes the data layer supports this, hibernate does) # {valueType: "boolean", required: true} dao.optimisticLocking = true # set the API as readonly (e.g. during upgrades). Any updates will throw an exception # {valueType: "boolean", required: true} grouper.api.readonly = false # When searching for memberships using the getMemberships WS (or underlying API call), limit the number of memberships # which can be returned, else throws exception. -1 means dont check. # {valueType: "integer", required: true} ws.getMemberships.maxResultSize = 30000 # When searching for memberships using the getMemberships WS (or underlying API call), limit the page size # which can be returned, else throws exception. # {valueType: "integer", required: true} ws.getMemberships.maxPageSize = 500 # When searching for attribute assignments using the getAttributeAssignments WS (or underlying API call), limit the number of assignments # which can be returned, else throws exception. -1 means dont check. # {valueType: "integer", required: true} ws.findAttrAssignments.maxResultSize = 30000 # When searching attribute def names, this is max size # {valueType: "integer", required: true} findAllAttributeDefNames.maxResultSize = 30000 # create the type and attribuute for membership lite ui config by group # {valueType: "boolean", required: true} membershipUpdateLiteTypeAutoCreate = false # default min idIndex # {valueType: "integer", required: true} grouperTableIndexDefaultMinIndex = 1000000 # min idIndex for groups # {valueType: "integer", required: true} grouper.tableIndex.group.minIndex = 1000000 # min idIndex for folders # {valueType: "integer", required: true} grouper.tableIndex.stem.minIndex = 1000000 # min idIndex for attributeDefs # {valueType: "integer", required: true} grouper.tableIndex.attributeDef.minIndex = 1000000 # min idIndex for attributeDefNames # {valueType: "integer", required: true} grouper.tableIndex.attributeDefName.minIndex = 1000000 # verify that table indexes are set and the pointers are ok, incurs a bit of overhead to grouper startup # {valueType: "boolean", required: true} grouper.tableIndex.verifyOnStartup = true # in different circumstances, retrieve a different number of IDs at once. # if it is a system where the JVM is starting and stopping (e.g. GSH), then # dont reserve that many at once # {valueType: "integer", required: true} grouper.tableIndex.reserveIdsGsh = 1 # in different circumstances, retrieve a different number of IDs at once. # if it is a system where the JVM is starting and stopping (e.g. GSH), then # dont reserve that many at once # {valueType: "integer", required: true} grouper.tableIndex.reserveIdsDefault = 10 # in different circumstances, retrieve a different number of IDs at once. # if it is a system where the JVM is starting and stopping (e.g. GSH), then # dont reserve that many at once # {valueType: "integer", required: true} grouper.tableIndex.reserveIdsLoader = 10 # in different circumstances, retrieve a different number of IDs at once. # if it is a system where the JVM is starting and stopping (e.g. GSH), then # dont reserve that many at once # {valueType: "integer", required: true} grouper.tableIndex.reserveIdsWs = 10 # in different circumstances, retrieve a different number of IDs at once. # if it is a system where the JVM is starting and stopping (e.g. GSH), then # dont reserve that many at once # {valueType: "integer", required: true} grouper.tableIndex.reserveIdsUi = 10 # group who can assign id index cols (also, wheel or root is allowed) # {valueType: "group"} grouper.tableIndex.groupWhoCanAssignIdIndex = $$grouper.rootStemForBuiltinObjects$$:canAssignIdIndex # number of bytes in DB that a non ascii char takes # {valueType: "integer", required: true} grouper.nonAsciiCharDbBytesLength = 3 # cache size for jexl expressions # {valueType: "integer", required: true} jexl.cacheSize = 1024 # when reading writing files from util classes, this is encoding (was ISO-8859-1) # {valueType: "string"} grouper.default.fileEncoding = UTF-8 # if you want a checkbox to not let users add themself to a group # {valueType: "boolean", requiresRestart: "true"} grouper.enable.rule.cannotAddSelfToGroup = false # if you do not want non sysadmins to be able to add EveryEntity to a group or privilege # {valueType: "boolean", requiresRestart: "true"} grouper.enable.rule.cannotAddEveryEntity = false # if you want group admins to be able to assign cannotAddSelf # {valueType: "boolean"} grouper.cannotAddSelfToGroup.allowAssignByGroupAdmins = true # if group admins are not allowed to assign cannotAddSelf, then this group can, if blank then only Grouper admins can assign # {valueType: "string"} grouper.cannotAddSelfToGroup.groupCanAssignByGroupAdmins = $$grouper.rootStemForBuiltinObjects$$:cannotAddSelfToGroup:canAssignCannotAddSelf # if you want group admins to be able to revoke cannotAddSelf # {valueType: "boolean"} grouper.cannotAddSelfToGroup.allowRevokeByGroupAdmins = false # if group admins are not allowed to revoke cannotAddSelf, then this group can, if blank then only Grouper admins can revoke # {valueType: "string"} grouper.cannotAddSelfToGroup.groupCanRevokeByGroupAdmins = $$grouper.rootStemForBuiltinObjects$$:cannotAddSelfToGroup:canRevokeCannotAddSelf # find bad memberships batch size # {valueType: "integer", defaultValue: "1"} findBadMemberships.batchSize = ##################################### ## Testing settings ##################################### # if the ldappc tests should be included when running all tests (default false) # {valueType: "boolean", required: true} junit.test.ldappc = false # if the loader tests should be included when running all tests (default true) # {valueType: "boolean", required: true} junit.test.loader = true # if the tableSync tests should be included when running all tests (default true) # {valueType: "boolean", required: true} junit.test.tableSync = true # if the ddl tests should be included when running all tests (default true) # {valueType: "boolean", required: true} junit.test.ddl = true # if the sql provisioning tests should be included when running all tests (default false) # {valueType: "boolean", required: true} junit.test.sqlProvisioning = false # if the gsh tests should be included when running all tests (default false) # {valueType: "boolean", required: true} junit.test.gsh = false # if the stress tests should be included when running all tests (default false) # {valueType: "boolean", required: true} junit.test.stress = false # if test client configs which requires hardcoded filenames # {valueType: "boolean", required: true} junit.test.clientConfig = false # if grouper should run tests that require tomcat # {valueType: "boolean", defaultValue: "false"} junit.test.tomcat = # if the external subject tests should be included when running all tests, note you need the jabber attribute in the view (default false) # {valueType: "boolean", required: true} junit.test.externalSubjects = false # if the group sync should be tested... note you need the demo server available to test this, or change some settings... # {valueType: "boolean", required: true} junit.test.groupSync = false # unit test group sync url # {valueType: "string"} junit.test.groupSync.url = https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/servicesRest # unit test group sync user # {valueType: "string"} junit.test.groupSync.user = remoteUser # unit test group sync password # {valueType: "password", sensitive: true} junit.test.groupSync.password = R:/pass/grouperDemoRemoteUser.pass # unti test group sync folder #folder where the user can create/stem which the user can use to run tests # {valueType: "stem"} junit.test.groupSync.folder = test2:whateverFolder #this is true unless testing to an older grouper which doesnt support this # {valueType: "boolean", required: true} junit.test.groupSync.pushAddExternalSubjectIfNotExist = true # create remote folder if not exists # {valueType: "boolean", required: true} junit.test.groupSync.createRemoteFolderIfNotExist = true # remote source id # {valueType: "string"} junit.test.groupSync.remoteSourceId = grouperExternal # identifier for remote subject read # {valueType: "string"} junit.test.groupSync.remoteReadSubjectId = identifier # identifier for remote subject write # {valueType: "string"} junit.test.groupSync.remoteWriteSubjectId = identifier # to test this setup the source and set this to true # {valueType: "boolean", required: true} junit.test.ldap.source = false # make sure docker is there # {valueType: "boolean", required: true} junit.test.ldap.dinkel = false # these tests work locally but not on CI server # {valueType: "boolean", required: true} junit.test.databaseCache = false # command to start tomcat for unit tests, # e.g. cmd /c C:/mchyzer/tomcatJunit/bin/startup.bat # e.g. bash /some/where/tomcat/startup.sh # set to "none" and you have 10 seconds to start it on prompt # {valueType: "string"} junit.test.tomcat.startCommand = # command to stop tomcat for unit tests, # e.g. cmd /c C:/mchyzer/tomcatJunit/bin/shutdown.bat # e.g. bash /some/where/tomcat/shutdown.sh # set to "none" and you have 10 seconds to stop it on prompt # {valueType: "string"} junit.test.tomcat.stopCommand = # http port to look for to see if tomcat has started, e.g. 8500 # {valueType: "integer", defaultValue: "8080"} junit.test.tomcat.port = 8080 # ip address for tomcat # {valueType: "string", defaultValue: "0.0.0.0"} junit.test.tomcat.ipAddress = 0.0.0.0 # domain name for tomcat # {valueType: "string", defaultValue: "localhost"} junit.test.tomcat.domainName = localhost # if should wait for tomcat start command to return (unix?) or spawn a thread (windows?) # {valueType: "boolean"} junit.test.tomcat.waitForProcessReturn = # if this is ssl # {valueType: "boolean", defaultValue: "false"} junit.test.tomcat.ssl = # sleep on startup to wait for ldap # {valueType: "integer", defaultValue: "14000"} junit.test.ldapSleepMillisOnTestStartup = ##################################### ## Attribute framework ##################################### # root stem in grouper where built in attributes are put # {valueType: "stem"} grouper.attribute.rootStem = $$grouper.rootStemForBuiltinObjects$$:attribute # comma separated names of attribute defs will not be audited or change log or point in time # same as ${edu.internet2.middleware.grouper.cfg.GrouperConfig.retrieveConfig().propertyValueStringRequired('grouper.attribute.rootStem')} # e.g. $$grouper.attribute.rootStem$$:userData:grouperUserDataValueDef # note: some of these are hard coded in GrouperConfig.java # {valueType: "attributeDef", multiple: true} grouper.attribute.namesOfAttributeDefsToIgnoreAuditsChangeLogPit = # comma separated names of attribute def names will not be audited or change log or point in time # note: some of these are hard coded in GrouperConfig.java # e.g. $$grouper.attribute.rootStem$$:attestation:attestationCalculatedDaysLeft # {valueType: "attributeDefName", multiple: true} grouper.attribute.namesOfAttributeDefNamesToIgnoreAuditsChangeLogPit = # allow every entity to be able to read and assign subject identifiers to local entities they own # note: there is also: grouper.permissions.limits.builtin.createAs.public # {valueType: "boolean", required: true} grouper.attribute.allow.everyEntity.privileges = false ##################################### ## Centrally managed permissions ##################################### # if the permissions limits should be readable and updatable by GrouperAll (set when created)... # note there is also: grouper.attribute.allow.everyEntity.privileges # {valueType: "boolean", required: true} grouper.permissions.limits.builtin.createAs.public = false # text amount less than # {valueType: "string"} grouper.permissions.limits.builtin.displayExtension.limitAmountLessThan = amount less than # text amount less than equal to # {valueType: "string"} grouper.permissions.limits.builtin.displayExtension.limitAmountLessThanOrEqual = amount less than or equal to # text expression # {valueType: "string"} grouper.permissions.limits.builtin.displayExtension.limitExpression = Expression # text ip address on network realm # {valueType: "string"} grouper.permissions.limits.builtin.displayExtension.limitIpOnNetworkRealm = ipAddress on network realm # text ip address on networks # {valueType: "string"} grouper.permissions.limits.builtin.displayExtension.limitIpOnNetworks = ipAddress on networks # text labels contain # {valueType: "string"} grouper.permissions.limits.builtin.displayExtension.limitLabelsContain = labels contains # text weekday 9 to 5 # {valueType: "string"} grouper.permissions.limits.builtin.displayExtension.limitWeekday9to5 = Weekday 9 to 5 # el classes to add to the el context for a limitExpression. Comma-separated fully qualified classnames # {valueType: "class", multiple: true} grouper.permissions.limits.el.classes = # permission limits linked to subclasses of edu.internet2.middleware.grouper.permissions.limits.PermissionLimitBase by the name of the attribute (the attributeDefName not the attributeDef)) mutually exclusive with limitNameOfAttributeDef # {valueType: "string", regex: "^grouper\\.permissions\\.limits\\.logic\\.([^.]+)\\.limitName$"} # grouper.permissions.limits.logic.someName.limitName = # permission limits where all attribute names for the limit attribute def should be configured mutually exclusive with limitName # {valueType: "string", regex: "^grouper\\.permissions\\.limits\\.logic\\.([^.]+)\\.limitNameOfAttributeDef$"} # grouper.permissions.limits.logic.someName.limitNameOfAttributeDef = # permission limits linked to subclasses of edu.internet2.middleware.grouper.permissions.limits.PermissionLimitBase # {valueType: "class", regex: "^grouper\\.permissions\\.limits\\.logic\\.([^.]+)\\.logicClass$", mustExtendClass: "edu.internet2.middleware.grouper.permissions.limits.PermissionLimitBase"} # grouper.permissions.limits.logic.someName.logicClass = # if you are doing ip address limits, you can put realms here # {valueType: "string", multiple: true, regex: "^grouper\\.permissions\\.limits\\.realm\\.([^.]+)$"} # grouper.permissions.limits.realm.someName = 1.2.3.4/24, 2.3.4.5/16 ##################################### ## External subjects ##################################### # Use new UI to self register external users # {valueType: "boolean", required: true} externalSubject.selfRegister.useNewUI = true #manages the description of a user automatically # {valueType: "string"} externalSubjects.desc.el = ${grouperUtil.appendPrefixIfStringNotBlank('[unverifiedInfo]', ' ', grouperUtil.appendIfNotBlankString(externalSubject.name, ' - ', externalSubject.institution))} [externalUserID] ${externalSubject.identifier} #search and sort strings added to member objects, increment the index to add multiple # {valueType: "string", regex: "^externalSubjects\\.searchAttribute([0-9]+)\\.el$"} externalSubjects.searchAttribute0.el = ${subject.name},${subjectUtils.defaultIfBlank(subject.getAttributeValue("institution"), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValue("identifier"), "")},${subject.id},${subjectUtils.defaultIfBlank(subject.getAttributeValue("email"), "")} # external subject sort attribute, increment the index to add multiple # {valueType: "string", regex: "^externalSubjects\\.sortAttribute([0-9]+)\\.el$"} externalSubjects.sortAttribute0.el = ${subject.name} # external subject sort attribute, increment the index to add multiple # {valueType: "string"} externalSubjects.sortAttribute1.el = ${subjectUtils.defaultIfBlank(subject.getAttributeValue("identifier"), "")} # external subject sort attribute, increment the index to add multiple # {valueType: "string"} externalSubjects.sortAttribute2.el = ${subjectUtils.defaultIfBlank(subject.getAttributeValue("institution"), "")} # false if the description should be managed via EL (config above) # {valueType: "boolean", required: true} externalSubjects.desc.manual = false # external subject name required # {valueType: "boolean", required: true} externalSubjects.name.required = true # external subject email required # {valueType: "boolean", required: true} externalSubjects.email.required = false # external subject email enabled # {valueType: "boolean", required: true} externalSubjects.email.enabled = true # these field names (uuid, institution, identifier, uuid, email, name) or attribute names # will be toLowered, and appended with comma separators. e.g. if you add attributes, add them here too # {valueType: "string", multiple: true} externalSubjects.searchStringFields = name, institution, identifier, uuid, email # external subject institution required # {valueType: "boolean", required: true} externalSubjects.institution.required = false # external subject institution enabled # {valueType: "boolean", required: true} externalSubjects.institution.enabled = true # note, this must be only alphanumeric lower case or underscore # (valid db column name, subject attribute name) # {valueType: "string", regex: "^externalSubjects\\.attributes\\.([^.]+)\\.systemName$"} # externalSubjects.attributes.jabber.systemName = jabber # if the external subject attribute is required # {valueType: "boolean", regex: "^externalSubjects\\.attributes\\.([^.]+)\\.required$"} # externalSubjects.attributes.jabber.required = false # comment on column in DB (no special characters allowed) # {valueType: "string", regex: "^externalSubjects\\.attributes\\.([^.]+)\\.comment$"} # externalSubjects.attributes.jabber.comment = The jabber ID of the user # if wheel or root can edit external users # {valueType: "boolean", required: true} externalSubjects.wheelOrRootCanEdit = true # group which is allowed to edit external users # {valueType: "group", required: true} externalSubjects.groupAllowedForEdit = # if the view on the external subjects should be created. # turn this off if it doesnt compile, othrewise should be fine # {valueType: "boolean", required: true} externalSubjects.createView = true #name of external subject source, defaults to grouperExternal # {valueType: "string"} externalSubject.sourceId = grouperExternal # external subject source name # {valueType: "string"} externalSubject.sourceName = External Users # grouper can auto create a jdbc2 source for the external subjects # {valueType: "boolean", required: true} externalSubjects.autoCreateSource = true # put in fully qualified classes to add to the EL context. Note that they need a default constructor # comma separated. The alias will be the simple class name without a first cap. # e.g. if the class is test.Test the alias is "test" # {valueType: "class", required: true, multiple: true} externalSubjects.customElClasses = # change these to affect the storage where external subjects live (e.g. to store in ldap), # must implement each respective storable interface # {valueType: "class", mustImplementInterface: "edu.internet2.middleware.grouper.externalSubjects.ExternalSubjectStorable"} externalSubjects.storage.ExternalSubjectStorable.class = edu.internet2.middleware.grouper.externalSubjects.ExternalSubjectDbStorage # change these to affect the storage where external subjects live (e.g. to store in ldap), # must implement each respective storable interface # {valueType: "class", mustImplementInterface: "edu.internet2.middleware.grouper.externalSubjects.ExternalSubjectAttributeStorable"} externalSubjects.storage.ExternalSubjectAttributeStorable.class = edu.internet2.middleware.grouper.externalSubjects.ExternalSubjectAttributeDbStorage # you can use the variables $newline$, $inviteLink$. Note, you need to change this default message... # {valueType: "string"} externalSubjectsInviteDefaultEmail = Hello,$newline$$newline$This is an invitation to register at our site to be able to access our applications. This invitation expires in 7 days. Click on the link below and sign in with your InCommon credentials. If you do not have InCommon credentials you can register at a site like protectnetwork.org and use those credentials.$newline$$newline$$inviteLink$$newline$$newline$Regards. # default subject for email # {valueType: "string"} externalSubjectsInviteDefaultEmailSubject = Register to access applications # you can use the variables $newline$, $inviteeIdentifier$, $inviteeEmailAddress$. Note, you need to change this default message... # {valueType: "string"} externalSubjectsNotifyInviterEmail = Hello,$newline$$newline$This is a notification that user $inviteeIdentifier$ from email address $inviteeEmailAddress$ has registered with the identity management service. They can now use applications at this institution.$newline$$newline$Regards. # {valueType: "string"} externalSubjectsNotifyInviterSubject = $inviteeIdentifier$ has registered # numner of days after which this request will expire. If -1, then will not expire # {valueType: "integer", required: true} externalSubjectsInviteExpireAfterDays = 7 #put some group names comma separated for groups to auto add subjects to # {valueType: "group", multiple: true} externalSubjects.autoaddGroups= #should be insert, or update, or insert,update # {valueType: "string", multiple: true} externalSubjects.autoaddGroupActions=insert,update #if a number is here, expire the group assignment after a certain number of days # {valueType: "integer"} externalSubjects.autoaddGroupExpireAfterDays= # add multiple group assignment actions by URL param: externalSubjectInviteName # {valueType: "string", regex: "^externalSubjects\\.autoadd\\.([^.]+)\\.externalSubjectInviteName$"} #externalSubjects.autoadd.testingLibrary.externalSubjectInviteName=library # comma separated groups to add for this type of invite # {valueType: "group", multiple: true, regex: "^externalSubjects\\.autoadd\\.([^.]+)\\.groups$"} #externalSubjects.autoadd.testingLibrary.groups= # should be insert, update, or insert,update # {valueType: "string", multiple: true, regex: "^externalSubjects\\.autoadd\\.([^.]+)\\.groups$"} #externalSubjects.autoadd.testingLibrary.actions=insert,update # expire after days # {valueType: "integer", regex: "^externalSubjects\\.autoadd\\.([^.]+)\\.groups$"} #externalSubjects.autoadd.testingLibrary.expireAfterDays= #if registrations are only allowed if invited or existing... # {valueType: "boolean", required: true} externalSubjects.registerRequiresInvite=true #make sure the identifier when logging in is like an email address or eppn, e.g. [email protected] # {valueType: "boolean", required: true} externalSubjects.validateIndentiferLikeEmail=true #put regexes here, increment the 0 for multiple entries, e.g. restrict your own institution #note, the extensions must be sequential (dont skip), regex e.g. ^.*@myschool\\.edu$ # {valueType: "string", regex: "^externalSubjects\\.regexForInvalidIdentifier\\.([0-9]+)$"} externalSubjects.regexForInvalidIdentifier.0= ##################################### ## Org management ##################################### # if the orgs table(s) should be included in the DDL (includes the hierarchical table # {valueType: "boolean", required: true} orgs.includePocOrgsTablesInDdl = false # loader connection of the database where orgs are (grouper means the grouper db in grouper.hibernate.properties) # {valueType: "string"} orgs.databaseName = grouper #table name of the org table (can prefix by schema name if you like) # {valueType: "string"} orgs.orgTableName = grouperorgs_poc_orgs #column names of this table # {valueType: "string"} orgs.orgIdCol = id # column of org name # {valueType: "string"} orgs.orgNameCol = org_name # column of org display name # {valueType: "string"} orgs.orgDisplayNameCol = org_display_name # column or org parent id # {valueType: "string"} orgs.orgParentIdCol = parent_id # stem where the orgs are, e.g. poc:orgs # {valueType: "stem"} orgs.parentStemName = poc:orgs #org config name # {valueType: "group"} orgs.configGroupName = poc:orgs:orgsConfig ###################################### ## Grouper client connections ## if this grouper needs to talk to another grouper, this is the client connection information ###################################### # id of the source, should match the part in the property name # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.id$"} #grouperClient.someOtherSchool.id = someOtherSchool # url of web service, should include everything up to the first resource to access # e.g. https://groups.school.edu/grouperWs/servicesRest # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.properties\\.grouperClient\\.webService\\.url$"} #grouperClient.someOtherSchool.properties.grouperClient.webService.url = https://some.other.school.edu/grouperWs/servicesRest # login ID # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.properties\\.grouperClient\\.webService\\.login$"} #grouperClient.someOtherSchool.properties.grouperClient.webService.login = someRemoteLogin # password for shared secret authentication to web service # or you can put a filename with an encrypted password # {valueType: "password", sensitive: true, regex: "^grouperClient\\.([^.]+)\\.properties\\.grouperClient\\.webService\\.password$"} #grouperClient.someOtherSchool.properties.grouperClient.webService.password = ********* # client version should match or be related to the server on the other end... # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.properties\\.grouperClient\\.webService\\.client\\.version$"} #grouperClient.someOtherSchool.properties.grouperClient.webService.client.version = v2_0_000 # this is the subject to act as local, if blank, act as GrouperSystem, specify with SubjectFinder packed string, e.g. # subjectIdOrIdentifier or sourceId::::subjectId or ::::subjectId or sourceId::::::subjectIdentifier or ::::::subjectIdentifier # sourceId::::::::subjectIdOrIdentifier or ::::::::subjectIdOrIdentifier # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.localActAsSubject$"} #grouperClient.someOtherSchool.localActAsSubject = # the id of this source, generally the same as the name in the property name. This is mandatory # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.source\\.([^.]+)\\.id$"} #grouperClient.someOtherSchool.source.jdbc.id = jdbc # the part between "grouperClient.someOtherSchool.source." and ".id" links up the configs, # in this case, "jdbc", make sure it has no special chars. sourceId can be blank if you dont want to specify # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.source\\.([^.]+)\\.local\\.sourceId$"} #grouperClient.someOtherSchool.source.jdbc.local.sourceId = jdbc # this is the identifier that goes between them, it is "id" or an attribute name. subjects without this attribute will not be processed # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.source\\.([^.]+)\\.local\\.read\\.subjectId$"} #grouperClient.someOtherSchool.source.jdbc.local.read.subjectId = identifier # this is the identifier to lookup to add a subject, should be "id" or "identifier" or "idOrIdentifier" # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.source\\.([^.]+)\\.local\\.write\\.subjectId$"} #grouperClient.someOtherSchool.source.jdbc.local.write.subjectId = identifier # sourceId of the remote system, can be blank # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.source\\.([^.]+)\\.remote\\.sourceId$"} #grouperClient.someOtherSchool.source.jdbc.remote.sourceId = jdbc # this is the identifier that goes between them, it is "id" or an attribute name. subjects without this attribute will not be processed # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.source\\.([^.]+)\\.remote\\.read\\.subjectId$"} #grouperClient.someOtherSchool.source.jdbc.remote.read.subjectId = # this is the identifier to lookup to add a subject, should be "id" or "identifier" or "idOrIdentifier" # {valueType: "string", regex: "^grouperClient\\.([^.]+)\\.source\\.([^.]+)\\.remote\\.write\\.subjectId$"} #grouperClient.someOtherSchool.source.jdbc.remote.write.subjectId = ###################################### ## Sync to/from another grouper ## Only sync one group to one other group, do not sync one group to ## two report groupers. If you need to do this, add the group to another group ###################################### # we need to know where our # connection name in grouper client connections above # {valueType: "string", regex: "^syncAnotherGrouper\\.([^.]+)\\.connectionName$"} #syncAnotherGrouper.testGroup0.connectionName = someOtherSchool # incremental or push or pull or incremental_push. Note, incremental push is cron'ed and incremental (to make sure no discrepancies arise) # {valueType: "string", regex: "^syncAnotherGrouper\\.([^.]+)\\.syncType$"} #syncAnotherGrouper.testGroup0.syncType = incremental_push # local group which is being synced # {valueType: "group", regex: "^syncAnotherGrouper\\.([^.]+)\\.local\\.groupName$"} #syncAnotherGrouper.testGroup0.local.groupName = test:testGroup # remote group at another grouper which is being synced # {valueType: "string", regex: "^syncAnotherGrouper\\.([^.]+)\\.remote\\.groupName$"} #syncAnotherGrouper.testGroup0.remote.groupName = test2:testGroup2 # if subjects are external and should be created if not exist # {valueType: "string", regex: "^syncAnotherGrouper\\.([^.]+)\\.addExternalSubjectIfNotFound$"} #syncAnotherGrouper.testGroup0.addExternalSubjectIfNotFound = true ########################################### ## Text bundles for UI ########################################### # the default index # {valueType: "integer"} grouper.text.defaultBundleIndex = 0 # language for this bundle # {valueType: "string", regex: "^grouper.text.bundle.([0-9]+).language$"} grouper.text.bundle.0.language = en # country for this bundle # {valueType: "string", regex: "^grouper.text.bundle.([0-9]+).country$"} grouper.text.bundle.0.country = us # filename in the package grouperText that is before the .base.properties, and .properties # {valueType: "string", regex: "^grouper.text.bundle.([0-9]+).fileNamePrefix$"} grouper.text.bundle.0.fileNamePrefix = grouperText/grouper.textNg.en.us ################################### ## User data settings ################################### # amount of time to cache groups in use # {valueType: "integer", required: true} grouperUserData.group.cache.seconds = 120 ###################################### ## Legacy attributes ###################################### # legacy attribute base stem # {valueType: "stem"} legacyAttribute.baseStem=$$grouper.rootStemForBuiltinObjects$$:legacy:attribute # legacy attribute prefix for group types # {valueType: "string"} legacyAttribute.groupTypeDef.prefix=legacyGroupTypeDef_ # legacy attribute prefix for attribute definitions # {valueType: "string"} legacyAttribute.attributeDef.prefix=legacyAttributeDef_ # legacy custom list def prefix # {valueType: "string"} legacyAttribute.customListDef.prefix=legacyCustomListDef_ # legacy attribute group type prefix # {valueType: "string"} legacyAttribute.groupType.prefix=legacyGroupType_ # legacy attribute prefix # {valueType: "string"} legacyAttribute.attribute.prefix=legacyAttribute_ # legacy custom list prefix # {valueType: "string"} legacyAttribute.customList.prefix=legacyCustomList_ # if we should use threads in legacy attribute migration # {valueType: "boolean", required: true} legacyAttributeMigration.useThreads = true # if we are using threads in legacy attribute migration, this is the threads pool size # {valueType: "integer"} legacyAttributeMigration.threadPoolSize = 20 ###################################### ## Group types edit view ## Identify marker attributes or single valued string attributes to be viewed or edited on group screen ## "theConfigId" is the config ID of the attribute ###################################### # attribute name that should be able to be seen on screen, e.g. a:b:c # {valueType: "string"} #groupScreen.attribute.theConfigId.attributeName = # label on the left side of screen for attribute # {valueType: "string"} #groupScreen.attribute.theConfigId.label = # description on the right side of screen for attribute # {valueType: "string"} #groupScreen.attribute.theConfigId.description = # numeric index of the order of the attribute on the screen # {valueType: "integer"} #groupScreen.attribute.theConfigId.index = ###################################### ## Point in time audit ###################################### # if grouper should use threads when syncing point in time # {valueType: "boolean", required: true} pit.sync.useThreads = true # grouper pit thread pool size # {valueType: "integer", required: true} pit.sync.threadPoolSize = 20 ###################################### ## Stem sets ###################################### # {valueType: "boolean", required: true} stemSet.sync.useThreads = true # {valueType: "integer", required: true} stemSet.sync.threadPoolSize = 20 ###################################### ## Group sets ###################################### # {valueType: "boolean", required: true} groupSet.sync.useThreads = true # {valueType: "integer", required: true} groupSet.sync.threadPoolSize = 20 ######################## ## LDAP provisioning hook ## Will add the LDAPProvisioningExclude group type to groups that shouldnt be provisioned ######################## # Increment the integer starting with 0 to add multiple. Will add the LDAPProvisioningExclude group type to groups that shouldnt be provisioned, e.g. .*_excludes$, .*_includes$, .*_systemOfRecord$, .*_systemOfRecordAndIncludes$ # {valueType: "string", regex: "^LDAPProvisioningHook\\.exclude\\.regex\\.([0-9]+)$"} #LDAPProvisioningHook.exclude.regex.0=.*_excludes$ ######################################### ## Unresolvable Subject Deletion Utility ######################################### # folder where system objects are for usdu # {valueType: "stem"} usdu.systemFolder = $$grouper.rootStemForBuiltinObjects$$:usdu # global across all sources: Don't do anything if more than this number of unresolvable subjects are found # {valueType: "integer", required: true} usdu.failsafe.maxUnresolvableSubjects = 500 # global across all sources: if the first X subjects should be removed but stop after that limit: usdu.failsafe.maxUnresolvableSubjects usdu.failsafe.removeUpToFailsafe = false # global across all sources: only delete unresolvables if unresolvable for 30 days. -1 means remove now # {valueType: "integer", required: false} usdu.delete.ifAfterDays = 30 # local to one source supersedes the global settings: source ID # {valueType: "string", required: true, regex: "^usdu\\.source\\.([^.]+)\\.sourceId$"} # usdu.source.someLabel.sourceId = someSourceId # local to one source supersedes the global settings: Don't do anything if more than this number of unresolvable subjects are found # {valueType: "integer", required: true, regex: "^usdu\\.source\\.([^.]+)\\.failsafe\\.maxUnresolvableSubjects$"} # usdu.source.someLabel.failsafe.maxUnresolvableSubjects = 500 # local to one source supersedes the global settings: if the first X subjects should be removed but stop after that limit: usdu.failsafe.maxUnresolvableSubjects # {valueType: "integer", required: true, regex: "^usdu\\.source\\.([^.]+)\\.failsafe\\.removeUpToFailsafe$"} # usdu.source.someLabel.failsafe.removeUpToFailsafe = false # local to one source supersedes the global settings: Don't do anything if more than this number of unresolvable subjects are found # {valueType: "integer", required: true, regex: "^usdu\\.source\\.([^.]+)\\.delete\\.ifAfterDays$"} # usdu.source.someLabel.delete.ifAfterDays = 30 ######################################## ## Diagnostics ## In UI and WS ######################################## #if ignore tests. Note, in job names, invalid chars need to be replaced with underscore (e.g. colon) #anything in this regex: [^a-zA-Z0-9._-] # {valueType: "boolean", required: true, regex: "^ws\\.diagnostic\\.ignore\\.([a-zA-Z0-9._-]+)$"} ws.diagnostic.ignore.memoryTest = false #if ignore tests. Note, in job names, invalid chars need to be replaced with underscore (e.g. colon) #anything in this regex: [^a-zA-Z0-9._-] # {valueType: "boolean", required: true} ws.diagnostic.ignore.dbTest_grouper = false #if ignore tests. Note, in job names, invalid chars need to be replaced with underscore (e.g. colon) #anything in this regex: [^a-zA-Z0-9._-] # {valueType: "boolean", required: true} ws.diagnostic.ignore.source_jdbc = false #if ignore tests. Note, in job names, invalid chars need to be replaced with underscore (e.g. colon) #anything in this regex: [^a-zA-Z0-9._-] # {valueType: "boolean", required: true} ws.diagnostic.ignore.loader_CHANGE_LOG_changeLogTempToChangeLog = false #if ignore sync all pit tables one timer. #anything in this regex: [^a-zA-Z0-9._-] # {valueType: "boolean", required: true} ws.diagnostic.ignore.loader_OTHER_JOB_syncAllPitTables = false #if ignore sync all set tables one timer. #anything in this regex: [^a-zA-Z0-9._-] # {valueType: "boolean", required: true} ws.diagnostic.ignore.loader_OTHER_JOB_syncAllSetTables = false # this is 52 hours... 48 for 2 days, and 4 more for the job to run. So if the warehouse is down for updates, # then the daily job will not give an error # {valueType: "integer", required: true} ws.diagnostic.defaultMinutesSinceLastSuccess = 3120 # change log can only for 30 minutes of failing before diagnostics fails # {valueType: "integer", required: true} ws.diagnostic.defaultMinutesChangeLog = 30 # number of minute that can go by without a success before an error is thrown # {valueType: "integer", required: true, regex: "^ws\\.diagnostic\\.minutesSinceLastSuccess\\.([a-zA-Z0-9._-]+)$"} ws.diagnostic.minutesSinceLastSuccess.loader_SQL_GROUP_LIST__aStem_aGroup2 = 60 # list groups which should check the size, in this case, "employee" or "students" in the key name is a variable # {valueType: "group", required: true, regex: "^ws\\.diagnostic\\.checkGroupSize\\.([a-zA-Z0-9._-]+)\\.groupName$"} # ws.diagnostic.checkGroupSize.employees.groupName = community:employees # min group size of known groups # {valueType: "integer", required: true, regex: "^ws\\.diagnostic\\.checkGroupSize\\.([a-zA-Z0-9._-]+)\\.minSize$"} # ws.diagnostic.checkGroupSize.employees.minSize = 28000 #if a change log consumer hasn't had a success but it is running and progress is being made, treat as a success # {valueType: "boolean", required: true} ws.diagnostic.successIfChangeLogConsumerProgress = true # usdu daemon minutes since success 10 days # {valueType: "integer"} ws.diagnostic.minutesSinceLastSuccess.loader_OTHER_JOB_usduDaemon = 14400 # allow diagnostics from these IP ranges, e.g. 1.2.3.4/32 or 2.3.4.5/24, comma separated, leave blank if available from everywhere # {valueType: "string", multiple: true} ws.diagnostic.sourceIpAddresses = # if status details should be sent to the client or just logged # {valueType: "boolean", required: true} ws.diagnostic.sendDetailsInResponse = true ######################################### ## Instrumentation ######################################### # if instrumentation is thread enabled # {valueType: "boolean", required: true} instrumentation.thread.enabled = true # make updates in this many seconds # {valueType: "integer", required: true} instrumentation.updateGrouperIntervalInSeconds = 3600 # must be divisible by 3600 # {valueType: "integer", required: true} instrumentation.updateIncrements = 3600 # you may want to use a substring instead of the full hostname (e.g. ui-01 instead of grouper-ui-01.xyz.edu) if you're sending this to TIER # {valueType: "string", required: true} instrumentation.serverLabel.el = ${grouperUtil.hostname()} # number of days to retain instrumentation data. -1 is forever. # {valueType: "integer", required: true} instrumentation.retainData.days=30 # number of days to retain instrumentation instances without any activity. -1 is forever. Only applicable if instrumentation.retainData.days is not -1. # {valueType: "integer", required: true} instrumentation.retainInactiveInstances.days=365 # if set, will save the instance file containing the server uuid into this directory. Otherwise, will use /opt/grouper/instrumentation # {valueType: "string"} #instrumentation.instanceFile.directory = ######################################### ## GSH ######################################### # if legacy gsh should be used # {valueType: "boolean", required: true} gsh.useLegacy = false # when starting gsh, whether to immediately exit if there's a problem verifying the subject source configuration and connections # {valueType: "boolean", required: true} gsh.exitOnSubjectCheckConfigProblem = true # if running gsh with a file or runarg parameter and there's an error, whether to exit instead of continuing with the next command # {valueType: "boolean", required: true} gsh.exitOnNonInteractiveError = true # if running gsh in an otherjob or programmatically, exit if a line has an errror # {valueType: "boolean", required: true} gsh.exitOnProgrammaticError = true ######################################### ## Messages ######################################### # if a message is not marked as processed in this many seconds, then send again to be processed # {valueType: "integer", required: true} grouper.builtin.messaging.timeout.receive.seconds = 300 # number of seconds to sleep while waiting to see if the database has records, minimum 1 # {valueType: "integer", required: true} grouper.builtin.messaging.polling.sleep.seconds = 5 # default page size for messages # {valueType: "integer", required: true} grouper.builtin.messaging.defaultPageSize = 10 # max page size for messages # {valueType: "integer", required: true} grouper.builtin.messaging.maxPageSize = 50 ######################################### ## Attestation ######################################### #default value of attestation days until recertify. Every group/folder can define their own days until recertify value and if they don't provide, use the following one. # {valueType: "integer", required: true} attestation.default.daysUntilRecertify = 180 #number of groups shown in the body of attestation email # {valueType: "integer", required: true} attestation.email.group.count = 100 #attestation reminder email subject # {valueType: "string"} attestation.reminder.email.subject = You have $objectCount$ groups and/or folders that require attestation #attestation reminder email body (links and groups/folders are added dynamically) # {valueType: "string"} attestation.reminder.email.body = You need to attest the following groups and/or folders. Review each group/folder and click the button to mark it as reviewed. # attestation line in email when there are more than 100 emails # {valueType: "string"} attestation.reminder.email.body.greaterThan100 = There are $remaining$ more groups and/or folders to be attested. ################################### ## Deprovisioning ################################### # if deprovisioning should be enabled # {valueType: "boolean", required: true} deprovisioning.enable = true # comma separated affiliations for deprovisioning e.g. employee, student, etc # these need to be alphanumeric suitable for properties keys for further config or for group extensions # {valueType: "string"} deprovisioning.affiliations = # Group name of the group that identifies generally if an entity is in this affiliation. So if a group is deprovisioned # by various affiliations, then only deprovision if the entity in the group is not in any affiliation eligible group. # e.g. VPN is deprovisioned by affiliations employee and student. If the person is no longer an employee, but is still # a student, then dont deprovision. # for example deprovisioning.affiliation_.groupNameMeansInAffiliation set to a:b:c # deprovisioning.affiliation_employee.groupNameMeansInAffiliation = community:employee # number of minutes to cache deprovisioned members / admins # {valueType: "integer", required: true} deprovisioning.cacheMembersForMinutes = 5 # number of seconds to wait for refresh before giving up and using failsafe (if caching) # {valueType: "integer", required: true} deprovisioning.cacheFailsafeSeconds = 10 # folder where system objects are for deprovisioning # e.g. managersWhoCanDeprovision_ # e.g. usersWhoHaveBeenDeprovisioned_ # {valueType: "stem"} deprovisioning.systemFolder = $$grouper.rootStemForBuiltinObjects$$:deprovisioning # autocreate the deprovisioning groups # {valueType: "boolean", required: true} deprovisioning.autocreate.groups = true # default if the loader should not let deprovisioned users in that affiliation in loader jobs # {valueType: "boolean", required: true} deprovisioning.autoChangeLoader = true # users in this group who are admins of a affiliation but who are not Grouper SysAdmins, will be # able to deprovision from all grouper groups/objects, not just groups they have access to UPDATE/ADMIN # {valueType: "group"} deprovisioning.admin.group = $$deprovisioning.systemFolder$$:deprovisioningAdmins # number of days in deproivisioning group. Should be the amount of time for # systems of record to catch up and # for people to change external systems of record in manual processes # {valueType: "integer", required: true} deprovisioning.defaultNumberOfDaysInDeprovisioningGroup = 14 #number of objects shown in the body of deprovisioning email # {valueType: "integer", required: true} deprovisioning.email.object.count = 100 #deprovisioning reminder email subject # {valueType: "string"} deprovisioning.reminder.email.subject = You have $objectCount$ objects that have suggested users to be deprovisioned #deprovisioning reminder email body (links and groups are added dynamically) # {valueType: "string"} deprovisioning.reminder.email.body = You need to review the memberships of the following objects. Review the memberships of each object and click: Group actions -> Deprovisioning -> Members of this object have been reviewed # deprovisioning email line when there are more than 100 objects to be reviewed # {valueType: "string"} deprovisioning.reminder.email.body.greaterThan100 = There are $remaining$ more objects to be reviewed. ################################### ## Grouper object types ################################### # if object types should be enabled # {valueType: "boolean", required: true} objectTypes.enable = true # folder where system objects are for objectTypes # {valueType: "stem"} objectTypes.systemFolder = $$grouper.rootStemForBuiltinObjects$$:objectTypes # maximum groups/stems to show when suggesting auto assign types # {valueType: "integer"} objectTypes.max.autoAssign.objectCount = 2000 ################################### ## Grouper workflow approvals ################################### # if workflow should be enabled # {valueType: "boolean", required: true} workflow.enable = true # folder where system objects are for workflow # {valueType: "stem"} workflow.systemFolder = $$grouper.rootStemForBuiltinObjects$$:workflow # workflow editors group name # {valueType: "group"} workflow.editorsGroup = $$grouper.rootStemForBuiltinObjects$$:workflowEditors # workflow config types. comma separated list. grouper must be in the list # {valueType: "string"} workflow.configTypes = grouper # workflow storage option. valid values are database, fileSystem or S3 # {valueType: "string", required: true} workflow.storage.option = database # file system path where worklow files will be stored, e.g. /opt/grouper/workflow # {valueType: "string", required: false} workflow.file.system.path = /tmp/grouper/workflow # grouper workflow s3 bucket name where the files will be uploaded # {valueType: "string", required: false} workflow.s3.bucket.name = # grouper workflow s3 region e.g. us-west-2 # {valueType: "string", required: false} workflow.s3.region = # grouper workflow s3 access key # {valueType: "string", required: false} workflow.s3.access.key = # grouper workflow s3 secret key # {valueType: "string", required: false} workflow.s3.secret.key = #grouper workflow email subject # {valueType: "string"} workflow.email.subject = Report $$reportConfigName$$ generated #grouper workflow email body. Can use variables # {valueType: "string"} workflow.email.body = Hello $$subjectName$$, \n\n Report $$reportConfigName$$ has been generated. Download the report: $$reportLink$$ \n\n Thanks ######################################### ## Provisioning in UI ######################################### # if provisioning in ui should be enabled # {valueType: "boolean", required: true} provisioningInUi.enable = true # folder where system objects are for provisioning # {valueType: "stem"} provisioningInUi.systemFolder = $$grouper.rootStemForBuiltinObjects$$:provisioning # key for target # {valueType: "string"} #provisioning.target.pspngLdap1.key = pspngLdap1Key # members of this group, wheel group members and system user are allowed to assign this target # {valueType: "group"} #provisioning.target.pspngLdap1.groupAllowedToAssign = # should this target be assigned to only one stem # {valueType: "boolean", required: false} #provisioning.target.pspngLdap1.allowAssignmentsOnlyOnOneStem = false # should this target be read only # {valueType: "boolean", required: false} #provisioning.target.pspngLdap1.readOnly = false ###################################### ## Grouper Reporting ###################################### # folder where system objects are for reporting config # {valueType: "stem"} reportConfig.systemFolder = $$grouper.rootStemForBuiltinObjects$$:reportConfig # if grouper reporting should be enabled # {valueType: "boolean", required: true} grouperReporting.enable = true # grouper reporting storage option. valid values are database, fileSystem or S3 # {valueType: "string", required: true} reporting.storage.option = database # grouper reporting file system path where reports will be stored, e.g. /opt/grouper/reports # {valueType: "string", required: false} reporting.file.system.path = # grouper reporting s3 bucket name where the reports will be uploaded # {valueType: "string", required: false} reporting.s3.bucket.name = # grouper reporting s3 bucket name where the reports will be uploaded, e.g. us-west-2 # {valueType: "string", required: false} reporting.s3.region = # grouper reporting s3 access key # {valueType: "string", required: false} reporting.s3.access.key = # grouper reporting s3 secret key # {valueType: "string", required: false} reporting.s3.secret.key = #grouper reporting email subject # {valueType: "string"} reporting.email.subject = Report $$reportConfigName$$ generated #grouper reporting email body. Can use variables # {valueType: "string"} reporting.email.body = Hello $$subjectName$$, \n\n Report $$reportConfigName$$ has been generated. Download the report: $$reportLink$$ \n\n Thanks ######################################### ## LDAP ######################################### # you shouldnt need to change this, but this is the implementation of the # ldap sessions. examples are: # edu.internet2.middleware.grouper.ldap.ldaptive.LdaptiveSessionImpl (must be this) # ${valueType: "class", mustImplementInterface: "edu.internet2.middleware.grouper.ldap.LdapSession"} ldap.implementation.className = edu.internet2.middleware.grouper.ldap.ldaptive.LdaptiveSessionImpl ######################################### ## Custom composites ## This feature allows users to easily do a custom intersection or complement on their group with another group when viewing the members in the Grouper UI. ## Define your custom composites in the override configuration. Users must have READ privilege on the group. ######################################### # Each custom composite also needs to be defined in the Grouper UI text properties in order to provide a friendly description in the UI. customCompositeMinusEmployees and customCompositeIntersectIt are also defined as examples there. # {valueType: "string", regex: "^grouper\\.membership\\.customComposite\\.uiKey\\.\\d+$"} # grouper.membership.customComposite.uiKey.0 = customCompositeMinusEmployees # complement or intersection # {valueType: "string", regex: "^grouper\\.membership\\.customComposite\\.compositeType\\.\\d+$"} # grouper.membership.customComposite.compositeType.0 = complement # {valueType: "group", regex: "^grouper\\.membership\\.customComposite\\.groupName\\.\\d+$"} # grouper.membership.customComposite.groupName.0 = ref:activeEmployees ######################################### ## Custom veto composites membership requirement ## This feature allows users to auto-veto ineligible members or remove them when they become ineligible. ## Note that each custom composite also needs to be defined in the Grouper UI text properties in order ## to provide a friendly description in the UI. customCompositeMinusEmployees and customCompositeIntersectIt are also defined as examples there. ######################################### # how long should logs of membership requirement logs be stored in database? # {valueType: "integer", regex: "^grouper\\.membershipRequirement\\.keepLogsForDays$"} grouper.membershipRequirement.keepLogsForDays = 90 # should hook for membership veto be enabled # {valueType: "boolean", regex: "^grouper\\.membershipRequirement\\.hookEnable$"} grouper.membershipRequirement.hookEnable = true # should changeLog for membership veto change log be enabled in general # {valueType: "boolean", regex: "^grouper\\.membershipRequirement\\.changeLogEnable$"} grouper.membershipRequirement.changeLogEnable = true # ui key to externalize text # {valueType: "string", regex: "^grouper\\.membershipRequirement\\.[^.]+\\.uiKey$"} #grouper.membershipRequirement.someConfigId.uiKey = customVetoCompositeRequireEmployee # attribute name that signifies this requirement # {valueType: "string", regex: "^grouper\\.membershipRequirement\\.[^.]+\\.attributeName$"} #grouper.membershipRequirement.someConfigId.attributeName = etc:attribute:customComposite:requireEmployee # group name which is the population group # {valueType: "group", regex: "^grouper\\.membershipRequirement\\.[^.]+\\.requireGroupName$"} #grouper.membershipRequirement.someConfigId.requireGroupName = org:centralIt:staff:itStaff # if the overall hook is enabled, is the hook for this specific config enabled? defaults to true. # {valueType: "boolean", regex: "^grouper\\.membershipRequirement\\.[^.]+\\.hookEnable$"} #grouper.membershipRequirement.someConfigId.hookEnable = true ######################################### ## Unique extension in folder hook ######################################### # comma separated folder names (id path). Configure multiple with different config ids # {valueType: "string", regex: "^groupUniqueExtensionInFolderHook\\.[^.]+\\.folderNames$"} #groupUniqueExtensionInFolderHook.someConfigId.folderNames = a:b, b:c # optional config for case sensitive extensions (default true) # {valueType: "string", regex: "^groupUniqueExtensionInFolderHook\\.[^.]+\\.caseSensitive$"} #groupUniqueExtensionInFolderHook.someConfigId.caseSensitive = false ################################## ## Membership self read ################################## # Allow users to see their own memberships on groups that they have VIEW privilege on # {valueType: "boolean", defaultValue : "false"} grouper.membership.allowSelfRead = false ################################## ## Lockout groups. Could be used for other things, but used for policy group templates at least ## if there is no allowed group, then anyone could use it ################################## # group name of a lockout group # {valueType: "group", regex: "^grouper\\.lockoutGroup\\.name\\.\\d+$"} # grouper.lockoutGroup.name.0 = ref:lockout # allowed to use this lockout group. If not configured, anyone could use # {valueType: "group", regex: "^grouper\\.lockoutGroup\\.allowedToUse\\.\\d+$"} # grouper.lockoutGroup.allowedToUse.0 = ref:lockoutCanUse ################################## ## Require groups. Could be used for other things, but used for policy group templates at least ## if there is no allowed group, then anyone could use it ################################## # group name of a require group # {valueType: "group", regex: "^grouper\\.requireGroup\\.name\\.\\d+$"} # grouper.requireGroup.name.0 = ref:active # allowed to use this require group. If not configured, anyone could use # {valueType: "group", regex: "^grouper\\.lockoutGroup\\.requireGroup\\.\\d+$"} # grouper.requireGroup.allowedToUse.0 = ref:activeCanUse ################################## ## Visualization ## Object styles for visualization modules ################################## # semicolon-delimited regular expressions for folder names to exclude; # for example, ^etc:.*;^$ will filter out folders etc:* and the root folder # {valueType: "string"} visualization.skipFolderNamePatterns = # semicolon-delimited regular expressions for group names to exclude # {valueType: "string"} visualization.skipGroupNamePatterns = # sample style properties, for illustration. It's useful to have property names # correspond to css styles, so that they can be plugged in directly to output, # without needing to rename them # {valueType: "string"} visualization.style.default.style = # default color # {valueType: "string"} visualization.style.default.color = # default bgcolor # {valueType: "string"} visualization.style.default.bgcolor = # default border # {valueType: "string"} visualization.style.default.border = # default font # {valueType: "string"} visualization.style.default.font = Courier,monospace # default font size # {valueType: "string"} visualization.style.default.font-size = 12.0 # default font color # {valueType: "string"} visualization.style.default.font-color = black # default shape # {valueType: "string"} visualization.style.default.shape = # default shape stype # {valueType: "string"} visualization.style.default.shape-style = # default edge style # {valueType: "string"} visualization.style.default.edge-style = # default arrow tail # {valueType: "string"} visualization.style.default.arrowtail = # default arrow head # {valueType: "string"} visualization.style.default.arrowhead = # default dir # {valueType: "string"} visualization.style.default.dir = # default inherit # {valueType: "string"} visualization.style.default.inherit = # set up a default style inheritance (can be overridden for specific modules) # {valueType: "string"} visualization.style.start_group.inherit = group # skipt group inherit # {valueType: "string"} visualization.style.skip_group.inherit = group # inherit loader group # {valueType: "string"} visualization.style.loader_group.inherit = group # inherit loader group # {valueType: "string"} visualization.style.start_loader_group.inherit = loader_group,start_group # inherit simple loader group # {valueType: "string"} visualization.style.simple_loader_group.inherit = loader_group # inherit simple loader group # {valueType: "string"} visualization.style.start_simple_loader_group.inherit = simple_loader_group,start_group # inherit intersect group # {valueType: "string"} visualization.style.intersect_group.inherit = group # inherit complement group # {valueType: "string"} visualization.style.complement_group.inherit = group # inherit start stem # {valueType: "string"} visualization.style.start_stem.inherit = stem # inherit skip stem # {valueType: "string"} visualization.style.skip_stem.inherit = stem # inherit start subject # {valueType: "string"} visualization.style.start_subject.inherit = subject # inherit edge loader # {valueType: "string"} visualization.style.edge_loader.inherit = edge # inherit edge membership # {valueType: "string"} visualization.style.edge_membership.inherit = edge # inherit edge provisioner # {valueType: "string"} visualization.style.edge_provisioner.inherit = edge # inherit edge complement left # {valueType: "string"} visualization.style.edge_complement_left.inherit = edge # inherit edge complement right # {valueType: "string"} visualization.style.edge_complement_right.inherit = edge # inherit edge intersect left # {valueType: "string"} visualization.style.edge_intersect_left.inherit = edge # inherit edge intersect right # {valueType: "string"} visualization.style.edge_intersect_right.inherit = edge # inherit edge intersect # {valueType: "string"} visualization.style.edge_intersect.inherit = edge # inherit group is member # {valueType: "string"} visualization.style.group_is_member.inherit = group # inherit group is not member # {valueType: "string"} visualization.style.group_is_not_member.inherit = group # inherit start group is member # {valueType: "string"} visualization.style.start_group_is_member.inherit = start_group,group_is_member # inherit loader group is member # {valueType: "string"} visualization.style.loader_group_is_member.inherit = loader_group,group_is_member # inherit start loader group is member # {valueType: "string"} visualization.style.start_loader_group_is_member.inherit = start_loader_group,group_is_member # inherit simple loader group is member # {valueType: "string"} visualization.style.simple_loader_group_is_member.inherit = simple_loader_group,group_is_member # inherit start simple loader group is member # {valueType: "string"} visualization.style.start_simple_loader_group_is_member.inherit = start_simple_loader_group,group_is_member # inherit complement group is member # {valueType: "string"} visualization.style.complement_group_is_member.inherit = complement_group,group_is_member # inherit intersect group is member # {valueType: "string"} visualization.style.intersect_group_is_member.inherit = intersect_group,group_is_member # inherit start group is not member # {valueType: "string"} visualization.style.start_group_is_not_member.inherit = start_group,group_is_not_member # inherit loader group is not member # {valueType: "string"} visualization.style.loader_group_is_not_member.inherit = loader_group,group_is_not_member # inherit start loader group is not member # {valueType: "string"} visualization.style.start_loader_group_is_not_member.inherit = start_loader_group,group_is_not_member # inherit simple loader group is not member # {valueType: "string"} visualization.style.simple_loader_group_is_not_member.inherit = simple_loader_group,group_is_not_member # inherit start simple loader group is not member # {valueType: "string"} visualization.style.start_simple_loader_group_is_not_member.inherit = start_simple_loader_group,group_is_not_member # inherit complement group is not member # {valueType: "string"} visualization.style.complement_group_is_not_member.inherit = complement_group,group_is_not_member # inherit intersect group is not member # {valueType: "string"} visualization.style.intersect_group_is_not_member.inherit = intersect_group,group_is_not_member # Link type to determine which UiV2Visualization method to invoke. Mostly relies on inheritence for subtypes # {valueType: "string"} visualization.style.stem.linkType = stem # link type group # {valueType: "string"} visualization.style.group.linkType = group # link type subject # {valueType: "string"} visualization.style.subject.linkType = subject # link type loader group # {valueType: "string"} visualization.style.loader_group.linkType = group # link type group is member # {valueType: "string"} visualization.style.group_is_member.linkType = group # link type group is not member # {valueType: "string"} visualization.style.group_is_not_member.linkType = group # Base type used in the ui to reduce the number of types to check; relies a lot on inheritence # {valueType: "string"} visualization.style.stem.baseType = stem # group base type # {valueType: "string"} visualization.style.group.baseType = group # subject base type # {valueType: "string"} visualization.style.subject.baseType = subject # loader group base type # {valueType: "string"} visualization.style.loader_group.baseType = loader_group # complement group base type # {valueType: "string"} visualization.style.complement_group.baseType = complement_group # intersect group base type # {valueType: "string"} visualization.style.intersect_group.baseType = intersect_group # Used to determine some calculated display text # {valueType: "string"} visualization.style.stem.displayTag = folder # group display tag # {valueType: "string"} visualization.style.group.displayTag = group # intersect group display tag # {valueType: "string"} visualization.style.intersect_group.displayTag = intersection group # complement group display tag # {valueType: "string"} visualization.style.complement_group.displayTag = complement group # subject display tag # {valueType: "string"} visualization.style.subject.displayTag = subject # provisioner display tag # {valueType: "string"} visualization.style.provisioner.displayTag = provisioner # loader group display tag # {valueType: "string"} visualization.style.loader_group.displayTag = loader job # enabled style modules, comma-separated # {valueType: "string"} visualization.modules = text, dot # styles for GraphViz dot format # {valueType: "string"} visualization.module.dot.graph.style = center=true; splines=spline; ratio=auto; ranksep = ".5"; nodesep = ".25 equally"; rankdir=LR; fontname="Courier,monospace"; bgcolor=gray91; packmode=clust; # dot graph node style # {valueType: "string"} visualization.module.dot.graph.nodestyle = shape=rect; fontname="Courier,monospace"; fontsize="12.0"; # dot stem color # {valueType: "string"} visualization.module.dot.stem.color = powderblue # dot stem shape # {valueType: "string"} visualization.module.dot.stem.shape = folder # dot stem style # {valueType: "string"} visualization.module.dot.stem.style = filled # dot start stem border # {valueType: "string"} visualization.module.dot.start_stem.border = 1 # start stem color e.g. deepskyblue # {valueType: "string"} visualization.module.dot.start_stem.color = sandybrown # dot skip stem color # {valueType: "string"} visualization.module.dot.skip_stem.color = sandybrown # dot group is member color # {valueType: "string"} visualization.module.dot.group_is_member.fillcolor = forestgreen # dot group is member style # {valueType: "string"} visualization.module.dot.group_is_member.style = filled # dot group is member fontcolor # {valueType: "string"} visualization.module.dot.group_is_member.fontcolor = white # dot group is not member color # {valueType: "string"} visualization.module.dot.group_is_not_member.fillcolor = mistyrose # dot group is not member style # {valueType: "string"} visualization.module.dot.group_is_not_member.style = filled # dot group is not member fontcolor # {valueType: "string"} visualization.module.dot.group_is_not_member.fontcolor = black # dot start group color # {valueType: "string"} visualization.module.dot.start_group.color = sandybrown # dot start group style # {valueType: "string"} visualization.module.dot.start_group.style = bold # dot start group border # {valueType: "string"} visualization.module.dot.start_group.border = 1 # dot intersect group color # {valueType: "string"} visualization.module.dot.intersect_group.color = blue # dot intersect group style # {valueType: "string"} visualization.module.dot.intersect_group.style = bold # dot start intersect group color # {valueType: "string"} visualization.module.dot.start_intersect_group.color = sandybrown # dot complement group color # {valueType: "string"} visualization.module.dot.complement_group.color = green4 # dot complement group style # {valueType: "string"} visualization.module.dot.complement_group.style = bold # dot start complement group color # {valueType: "string"} visualization.module.dot.start_complement_group.color = sandybrown # dot subject color # {valueType: "string"} visualization.module.dot.subject.color = sandybrown # dot subject style # {valueType: "string"} visualization.module.dot.subject.style = filled # dot provisioner color # {valueType: "string"} visualization.module.dot.provisioner.color = red # dot edge style # {valueType: "string"} visualization.module.dot.edge.style = solid # dot edge loader color # {valueType: "string"} visualization.module.dot.edge_loader.color = forestgreen # dot edge loader style # {valueType: "string"} visualization.module.dot.edge_loader.style = dashed # dot edge provisioner color # {valueType: "string"} visualization.module.dot.edge_provisioner.color = red # dot edge provisioner style # {valueType: "string"} visualization.module.dot.edge_provisioner.style = dashed # dot edge membership style # {valueType: "string"} visualization.module.dot.edge_membership.style = dashed # dot edge complement left color # {valueType: "string"} visualization.module.dot.edge_complement_left.color = green3 # dot edge complement left headlabel # {valueType: "string"} visualization.module.dot.edge_complement_left.headlabel = "(+)" # dot edge complement left labeldistance # {valueType: "string"} visualization.module.dot.edge_complement_left.labeldistance = 2 # dot edge complement right color # {valueType: "string"} visualization.module.dot.edge_complement_right.color = red3 # dot edge complement right style # {valueType: "string"} visualization.module.dot.edge_complement_right.style = dashed # dot edge complement right headlabel # {valueType: "string"} visualization.module.dot.edge_complement_right.headlabel = "(-)" # dot edge complement right labeldistance # {valueType: "string"} visualization.module.dot.edge_complement_right.labeldistance = 2 # dot edge intersect left color # {valueType: "string"} visualization.module.dot.edge_intersect_left.color = blue # dot edge intersect left headlabel # {valueType: "string"} visualization.module.dot.edge_intersect_left.headlabel = "(i)" # dot edge intersect left labeldistance # {valueType: "string"} visualization.module.dot.edge_intersect_left.labeldistance = 2 # dot edge intersect right color # {valueType: "string"} visualization.module.dot.edge_intersect_right.color = blue # dot edge intersect right headlabel # {valueType: "string"} visualization.module.dot.edge_intersect_right.headlabel = "(i)" # dot edge intersect right labeldistance # {valueType: "string"} visualization.module.dot.edge_intersect_right.labeldistance = 2 # graph viz start stem label styles # {valueType: "string"} # visualization.module.graphviz.start_stem.label_styles = BGCOLOR="purple3" COLOR="blue" # graphviz start stem label fontstyles # {valueType: "string"} # visualization.module.graphviz.start_stem.label_fontstyles = COLOR="white" # graphviz loader group label fontstyles # {valueType: "string"} # visualization.module.graphviz.loader_group.label_fontstyles = COLOR="white" ################################## ## Configuration in the DB ################################## # seconds between checking to see if the config files are updated in the database. If anything edited, then refresh all. # Note that the last edited is stored in a config property for deletes. -1 means dont check for incrementals. # Note if *.config.secondsBetweenUpdateChecks is greater than this number # for this config, then it wont update until that amount has passed. # {valueType: "integer", required: true} grouper.config.secondsBetweenUpdateChecksToDb = 30 # seconds between full refreshes of the database config # {valueType: "integer", required: true} grouper.config.secondsBetweenFullRefresh = 600 # millis since that config inserted, edited or deleted. Grouper will update this config. Do not edit it # Note change this with jdbc and dont audit. # if grouper.config.secondsBetweenUpdateChecks is -1, then dont use this property # {valueType: "integer", required: true} grouper.config.millisSinceLastDbConfigChanged = 0 ################################## ## Proxy config ################################## # proxy requests here, e.g. https://server:1234 # {valueType: "string"} grouper.http.proxy.url = # socks or http # {valueType: "string", formElement: "dropdown", optionValues: ["PROXY_HTTP", "PROXY_SOCKS5"]} grouper.http.proxy.type = # if this is blank then all urls are included by default. If there is a regex here, then only include urls that match, e.g. ^abc$ # note for SFTP the url is sftp://the.host.name # {valueType: "string"} grouper.http.proxy.includeUrlRegexPattern = # if this is blank then excludes are not considered by default. If there is a regex here, then only exclude urls that match, e.g. ^abc$ # note for SFTP the url is sftp://the.host.name # {valueType: "string"} grouper.http.proxy.excludeUrlRegexPattern = ################################## ## SFTP sites ## the "configId" will be the identifier used in code to pull up that site, dont put special chars in it ## you shouldnt have the same host and username in two different configIds since its essentially the primary key ## e.g. if you sftp server is "depot.school.edu", the configId could be "depot" ################################## # SFTP needs to use some files to connect. Keep this in a dir that only the tomcat user can read # otherwise it will use the tmp dir configured in grouper.properties. # {valueType: "string"} grouperSftpBaseDirName = # default proxy host for all sftp external systems # {valueType: "string"} grouperSftp.proxyHost = # default proxy port for all sftp external systems # {valueType: "integer"} grouperSftp.proxyPort = # default proxy type for all sftp external systems: PROXY_HTTP, PROXY_SOCKS5, PROXY_STREAM # {valueType: "string", formElement: "dropdown", optionValues: ["PROXY_HTTP", "PROXY_SOCKS5", "PROXY_STREAM"]} grouperSftp.proxyType = # host: e.g. some.server.com # {valueType: "string", regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.host$", required: true} # grouperSftp.site.configId.host = # user: e.g. someuser # {valueType: "string", regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.user$", required: true} # grouperSftp.site.configId.user = # you can encrypt the private key to connect with. if its more than 4k encrypted, then take it in chunks and they will be concatenated # and use _0, _1, _2, etc. Note, replace newlines with $newline$ so it fits in a textfield # {valueType: "password", sensitive: true, regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.secret\\.privateKey_[0-9]$"} # grouperSftp.site.configId.secret.privateKey_0 = # private key passphrase # {valueType: "password", sensitive: true, regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.secret\\.privateKeyPassphrase$"} # grouperSftp.site.configId.secret.privateKeyPassphrase = # password if not using private key # {valueType: "password", sensitive: true, regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.password$"} # grouperSftp.site.configId.password = # connect to the host, and copy the known_hosts entry for the host to connect to # e.g. host.whatever ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA3B00cx5W9KPSjzik3E # {valueType: "string", regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.knownHostsEntry$"} # grouperSftp.site.configId.knownHostsEntry = # if any temporary files (e.g. private key and known hosts) should be deleted after session, default true # {valueType: "boolean", defaultValue: "true", regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.deleteTempFilesAfterSession$"} # grouperSftp.site.configId.deleteTempFilesAfterSession = # timeout in millis defaults to 10000 # {valueType: "integer", regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.timeoutMillis$"} # grouperSftp.site.configId.timeoutMillis = # if this sftp connector is enabled # {valueType: "boolean", regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.enabled$", defaultValue: "true"} # grouperSftp.site.configId.enabled = # Proxy host for this sftp external system, or default to the global default: grouper.properties: grouperSftp.proxyHost # {valueType: "string", regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.proxyHost$"} # grouperSftp.site.configId.proxyHost = # Proxy port for this sftp external system, or default to the global default: grouper.properties: grouperSftp.proxyPort # {valueType: "integer", regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.proxyPort$"} # grouperSftp.site.configId.proxyPort = # Proxy type for this sftp external system: PROXY_HTTP, PROXY_SOCKS5, PROXY_STREAM, or default to the global default: grouper.properties: grouperSftp.proxyType # {valueType: "string", regex: "^grouperSftp\\.site\\.[a-zA-Z0-9._-]+\\.proxyType$", formElement: "dropdown", optionValues: ["PROXY_HTTP", "PROXY_SOCKS5", "PROXY_STREAM"]} # grouperSftp.site.configId.proxyType = ################################## ## authentication hash type ################################## # hash for DB authn # {valueType: "string", required: true} grouper.authentication.encryptionType = SHA-256 # if we should cache UI authns # {valueType: "boolean", required : true} grouper.authentication.UI.cache = false # if we should cache WS authns # {valueType: "boolean", required : true} grouper.authentication.WS.cache = false # cache timeout for UI authns # {valueType: "integer", required: true} grouper.authentication.UI.cacheTimeMinutes = 2 # cache timeout for WS authns # {valueType: "integer", required: true} grouper.authentication.WS.cacheTimeMinutes = 2 # when splitting basic auth header (which doesnt handle colons well), split on first or last colon # first colon means usernames dont have colons, but passwords do. # splitting on last colon means usernames have colons (e.g. local entities), but passwords dont # note you can also escape colons # {valueType: "boolean", defaultValue : "false"} grouper.authentication.splitBasicAuthOnFirstColon = false # You can escape colons in usernames and passwords, and they will be unescaped. escape with : # set this to false to not unescape colons # {valueType: "boolean", defaultValue : "false"} grouper.authentication.basicAuthUnescapeColon = true ################################## ## ws self-service jwt ################################## # if public private key should be enabled # {valueType: "boolean", defaultValue: "true"} grouper.selfService.jwt.enable = # if you fill in a group name here, then only members of this group can manage jwt private keys on the ui # {valueType: "string"} grouper.selfService.jwt.groupNameAllowedToManage = # maximum number of seconds for which a jwt can stay valid # {valueType: "integer"} grouper.selfService.jwt.maxValidTimeInSeconds = 600 ############################################ ## dev environment allow missing servlets ############################################ # {valueType: "string", required: false} grouper.dev.env.allowMissingServlets = false ############################################ ## O365 connector ## See documentation at http://graph.microsoft.io/en-us/docs ############################################ # tenant ID # {valueType: "string", required: true, regex: "^grouper\\.o365Connector\\.([^.]+)\\.tenantId$"} # grouper.o365Connector.myO365.tenantId = # client ID # {valueType: "string", required: true, regex: "^grouper\\.o365Connector\\.([^.]+)\\.clientId$"} # grouper.o365Connector.myO365.clientId = # client secret # {valueType: "password", required: true, regex: "^grouper\\.o365Connector\\.([^.]+)\\.clientSecret$"} # grouper.o365Connector.myO365.clientSecret = # ID attribute # {valueType: "string", required: true, regex: "^grouper\\.o365Connector\\.([^.]+)\\.idAttribute$"} # grouper.o365Connector.myO365.idAttribute = # group JEXL # {valueType: "string", required: true, regex: "^grouper\\.o365Connector\\.([^.]+)\\.groupJexl$"} # grouper.o365Connector.myO365.groupJexl = # if this O365 connector is enabled # {valueType: "boolean", regex: "^grouper\\.o365Connector\\.([^.]+)\\.enabled$", defaultValue: "true"} # grouper.o365Connector.myO365.enabled = ############################################ ## Google connector ## A Google Apps admin must follow the steps at Perform Google Apps Domain-Wide Delegation of Authority to ## create a service application/account that is used by the provisioner to connect to Google. The steps can ## be followed as written with one exception. The account will need to be given these grants: ## https://www.googleapis.com/auth/admin.directory.user, https://www.googleapis.com/auth/admin.directory.group, ## https://www.googleapis.com/auth/apps.groups.settings. ############################################ # The Google managed domain name. (e.g. example.org) # {valueType: "string", required: true, regex: "^grouper\\.googleConnector\\.([^.]+)\\.domain$"} # grouper.googleConnector.myGoogle.domain = # The service account email address created by Google. # {valueType: "string", required: true, regex: "^grouper\\.googleConnector\\.([^.]+)\\.serviceAccountEmail$"} # grouper.googleConnector.myGoogle.serviceAccountEmail = # The path of the PKCS12 file created and downloaded from Google. The OS account running Grouper # needs to have read permissions to this file. Access to this file should be limited. # {valueType: "string", regex: "^grouper\\.googleConnector\\.([^.]+)\\.serviceAccountPKCS12FilePath$"} # grouper.googleConnector.myGoogle.serviceAccountPKCS12FilePath = # If not reading from a file, this is the private key. You can get it by running "openssl pkcs12 -info -in pathToYourP12File -nodes" # {valueType: "password", formElement: "textarea", regex: "^grouper\\.googleConnector\\.([^.]+)\\.serviceAccountPrivateKeyPEM$"} # grouper.googleConnector.myGoogle.serviceAccountPrivateKeyPEM = # This is the account that all actions will be made by. It needs to exists and will be the creator and modifier # account associated with the Google auditing logs. # {valueType: "string", required: true, regex: "^grouper\\.googleConnector\\.([^.]+)\\.serviceImpersonationUser$"} # grouper.googleConnector.myGoogle.serviceImpersonationUser = # Google app token url # {valueType: "string", defaultValue: "https://oauth2.googleapis.com/token", regex: "^grouper\\.googleConnector\\.([^.]+)\\.tokenUrl$"} # grouper.googleConnector.myGoogle.tokenUrl = # Base url for google directory APIs # {valueType: "string", defaultValue: "https://admin.googleapis.com/admin/directory/v1", regex: "^grouper\\.googleConnector\\.([^.]+)\\.directoryApiBaseUrl$"} # grouper.googleConnector.myGoogle.directoryApiBaseUrl = # URL for google group settings api # {valueType: "string", defaultValue: "https://www.googleapis.com/groups/v1/groups", regex: "^grouper\\.googleConnector\\.([^.]+)\\.groupSettingsApiBaseUrl$"} # grouper.googleConnector.myGoogle.groupSettingsApiBaseUrl = # page size for groups # {valueType: "integer", defaultValue: "200", regex: "^grouper\\.googleConnector\\.([^.]+)\\.pageSizeGroup$"} # grouper.googleConnector.myGoogle.pageSizeGroup = # page size for users # {valueType: "integer", defaultValue: "500", regex: "^grouper\\.googleConnector\\.([^.]+)\\.pageSizeUser$"} # grouper.googleConnector.myGoogle.pageSizeUser = # page size for memberships # {valueType: "integer", defaultValue: "200", regex: "^grouper\\.googleConnector\\.([^.]+)\\.pageSizeMembership$"} # grouper.googleConnector.myGoogle.pageSizeMembership = # proxy requests here, e.g. https://server:1234 # {valueType: "string", regex: "^grouper\\.googleConnector\\.([^.]+)\\.proxyUrl$"} # grouper.googleConnector.myGoogle.proxyUrl = # socks or http # {valueType: "string", regex: "^grouper\\.googleConnector\\.([^.]+)\\.proxyType$", formElement: "dropdown", optionValues: ["PROXY_HTTP", "PROXY_SOCKS5"]} # grouper.googleConnector.myGoogle.proxyType = # if this google connector is enabled # {valueType: "boolean", regex: "^grouper\\.googleConnector\\.([^.]+)\\.enabled$", defaultValue: "true"} # grouper.googleConnector.myGoogle.enabled = ############################################ ## ActiveMQ ############################################ # host address of activemq queue. eg: example.org # {valueType: "string", required: true, regex: "^grouper\\.activeMqConnector\\.([^.]+)\\.host$"} # grouper.activeMqConnector.myConnector.host = # port of activemq queue, default is 5672 # {valueType: "integer", required: true, regex: "^grouper\\.activeMqConnector\\.([^.]+)\\.port$"} # grouper.activeMqConnector.myConnector.port = # username of activemq queue # {valueType: "string", required: true, regex: "^grouper\\.activeMqConnector\\.([^.]+)\\.username$"} # grouper.activeMqConnector.myConnector.username = # password of activemq queue # {valueType: "password", required: true, regex: "^grouper\\.activeMqConnector\\.([^.]+)\\.password$"} # grouper.activeMqConnector.myConnector.password = # if this activemq connector is enabled # {valueType: "boolean", regex: "^grouper\\.activeMqConnector\\.([^.]+)\\.enabled$", defaultValue: "true"} # grouper.activeMqConnector.myConnector.enabled = ############################################ ## RabbitMQ ############################################ # host address of rabbitmq queue. eg: example.org # {valueType: "string", required: true, regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.host$"} # grouper.rabbitMqConnector.myConnector.host = # virtual host address of rabbitmq queue. eg: example.org # {valueType: "string", required: true, regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.virtualhost$"} # grouper.rabbitMqConnector.myConnector.virtualhost = # port of rabbitmq queue # {valueType: "integer", required: true, regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.port$"} # grouper.rabbitMqConnector.myConnector.port = # username # {valueType: "string", required: true, regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.username$"} # grouper.rabbitMqConnector.myConnector.username = # password # {valueType: "password", required: true, regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.password$"} # grouper.rabbitMqConnector.myConnector.password = # set the following three properties if you want to use TLS connection to rabbitmq. All three need to be populated. # TLS Version. eg: TLSv1.1 # {valueType: "string", regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.tlsVersion$"} # grouper.rabbitMqConnector.myConnector.tlsVersion = # path to trust store file # {valueType: "string", regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.pathToTrustStore$"} # grouper.rabbitMqConnector.myConnector.pathToTrustStore = # trust passphrase # {valueType: "password", regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.trustPassphrase$"} # grouper.rabbitMqConnector.myConnector.trustPassphrase = # if this rabbitmq connector is enabled # {valueType: "boolean", regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.enabled$", defaultValue: "true"} # grouper.rabbitMqConnector.myConnector.enabled = ############################################ ## AWS SQS ############################################ # access key # {valueType: "string", required: true, regex: "^grouper\\.sqsConnector\\.([^.]+)\\.accessKey$"} # grouper.sqsConnector.myConnector.accessKey = # secret key # {valueType: "password", required: true, regex: "^grouper\\.sqsConnector\\.([^.]+)\\.secretKey$"} # grouper.sqsConnector.myConnector.secretKey = # if this SQS connector is enabled # {valueType: "boolean", regex: "^grouper\\.sqsConnector\\.([^.]+)\\.enabled$", defaultValue: "true"} # grouper.sqsConnector.myConnector.enabled = ############################################ ## Duo connector ############################################ # endpoint domain name # {valueType: "string", required: true, regex: "^grouper\\.duoConnector\\.([^.]+)\\.adminDomainName$"} # grouper.duoConnector.myConnector.adminDomainName = # integration key # {valueType: "string", required: true, regex: "^grouper\\.duoConnector\\.([^.]+)\\.adminIntegrationKey$"} # grouper.duoConnector.myConnector.adminIntegrationKey = # secret key # {valueType: "password", required: true, regex: "^grouper\\.duoConnector\\.([^.]+)\\.adminSecretKey$"} # grouper.duoConnector.myConnector.adminSecretKey = # Use SSL # {valueType: "boolean", defaultValue: "true", regex: "^grouper\\.duoConnector\\.([^.]+)\\.useSsl$"} # grouper.duoConnector.myConnector.useSsl = # proxy requests here, e.g. https://server:1234 # {valueType: "string", regex: "^grouper\\.duoConnector\\.([^.]+)\\.proxyUrl$"} # grouper.duoConnector.myConnector.proxyUrl = # socks or http # {valueType: "string", regex: "^grouper\\.duoConnector\\.([^.]+)\\.proxyType$", formElement: "dropdown", optionValues: ["PROXY_HTTP", "PROXY_SOCKS5"]} # grouper.duoConnector.myConnector.proxyType = # if this duo connector is enabled # {valueType: "boolean", regex: "^grouper\\.duoConnector\\.([^.]+)\\.enabled$", defaultValue: "true"} # grouper.duoConnector.myConnector.enabled = ############################################ ## Duo mock ############################################ # endpoint domain name # {valueType: "string"} # grouperTest.duo.mock.configId = ############################################ ## Remedy connector ############################################ # url # {valueType: "string", required: true, regex: "^grouper\\.remedyConnector\\.([^.]+)\\.url$"} # grouper.remedyConnector.myConnector.url = # authentication url # {valueType: "string", required: true, regex: "^grouper\\.remedyConnector\\.([^.]+)\\.tokenUrl$"} # grouper.remedyConnector.myConnector.tokenUrl = # username # {valueType: "string", required: true, regex: "^grouper\\.remedyConnector\\.([^.]+)\\.username$"} # grouper.remedyConnector.myConnector.username = # password # {valueType: "password", required: true, regex: "^grouper\\.remedyConnector\\.([^.]+)\\.password$"} # grouper.remedyConnector.myConnector.password = # if this remedy connector is enabled # {valueType: "boolean", regex: "^grouper\\.remedyConnector\\.([^.]+)\\.enabled$", defaultValue: "true"} # grouper.remedyConnector.myConnector.enabled = ############################################ ## Remedy digital marketplace connector ############################################ # url # {valueType: "string", required: true, regex: "^grouper\\.remedyDigitalMarketplaceConnector\\.([^.]+)\\.url$"} # grouper.remedyDigitalMarketplaceConnector.myConnector.url = # authentication url # {valueType: "string", required: true, regex: "^grouper\\.remedyDigitalMarketplaceConnector\\.([^.]+)\\.tokenUrl$"} # grouper.remedyDigitalMarketplaceConnector.myConnector.tokenUrl = # username # {valueType: "string", required: true, regex: "^grouper\\.remedyDigitalMarketplaceConnector\\.([^.]+)\\.username$"} # grouper.remedyDigitalMarketplaceConnector.myConnector.username = # password # {valueType: "password", required: true, regex: "^grouper\\.remedyDigitalMarketplaceConnector\\.([^.]+)\\.password$"} # grouper.remedyDigitalMarketplaceConnector.myConnector.password = # X-Requested-By # {valueType: "string", required: true, regex: "^grouper\\.remedyDigitalMarketplaceConnector\\.([^.]+)\\.xRequestedByHeader$"} # grouper.remedyDigitalMarketplaceConnector.myConnector.xRequestedByHeader = ############################################ ## Recent memberships ############################################ # if the recent-membership loader job should be created and scheduled nightly at 3:41am. It runs real time too so it shouldnt # need to run more frequently than daily # {valueType: "boolean", defaultValue: "true"} grouper.recentMemberships.loaderJob.enable = true # if this digital marketplace connector is enabled # {valueType: "boolean", regex: "^grouper\\.remedyDigitalMarketplaceConnector\\.([^.]+)\\.enabled$", defaultValue: "true"} # grouper.remedyDigitalMarketplaceConnector.myConnector.enabled = ############################################ ## Grouper cache database ############################################ # If we should run a thread to check the database to see if a cache changed in another JVM # {valueType: "boolean", defaultValue: "true"} grouper.cache.database.use = true # How much time to sleep between checks in seconds # {valueType: "integer", defaultValue: "5"} grouper.cache.database.checkIncrementalAfterSeconds = 5 # How much time in between full checks (select all from cache instance table) # {valueType: "integer", defaultValue: "3600"} grouper.cache.database.checkFullAfterSeconds = 3600 ############################################ ## External systems ############################################ # How much time to sleep between checks in seconds # {valueType: "integer", defaultValue: "60"} grouper.externalSystem.connectionRefresher.checkIntervalInSeconds = 60 ############################################ ## Mock services ############################################ # If requests and responses should be logged # {valueType: "boolean", defaultValue: "false"} grouper.mock.services.logRequestsResponses = false ############################################ ## Custom UI ############################################ # enabled or disabled # {valueType: "boolean", defaultValue: "true", order: 1000 } # grouperCustomUI.testCustomUI.enabled = # group uuid # {valueType: "string", required: true, order: 2000 } # grouperCustomUI.testCustomUI.groupUUIDOrName = # use externalized text for labels and descriptions? # {valueType: "boolean", defaultValue: "false", order: 3000 } # grouperCustomUI.testCustomUI.externalizedText = # number of queries # {valueType: "string", defaultValue: "0", subSection: "cuQuery", order: 4000, formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100"] } # grouperCustomUI.testCustomUI.numberOfQueries = # user query type # {valueType: "string", order: 7000, showEl: "${numberOfQueries > $i$}", repeatGroup: "cuQuery", repeatCount: 100, formElement: "dropdown", optionValues: ["azure", "expressionLanguage", "grouper", "ldap", "sql", "zoom"] } # grouperCustomUI.testCustomUI.cuQuery.$i$.userQueryType = # uuid of attribute def to look up # {valueType: "string", order: 8000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'expressionLanguage' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.attributeDefId = # azure group id # {valueType: "string", order: 9000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.azureGroupId = # bind variable 0 # {valueType: "string", order: 10000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.bindVar0 = # bind variable 0 type # {valueType: "string", order: 11000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.bindVar0Type = # bind variable 1 # {valueType: "string", order: 12000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.bindVar1 = # bind variable 1 type # {valueType: "string", order: 13000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.bindVar1Type = # bind variable 2 # {valueType: "string", order: 14000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.bindVar2 = # bind variable 2 type # {valueType: "string", order: 15000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.bindVar2Type = # config id # {valueType: "string", order: 16000, requiredEl: "${cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'zoom'}", showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'zoom' || cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.configId = # enabled # {valueType: "boolean", order: 17000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'zoom' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'expressionLanguage') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.enabled = # error label # {valueType: "string", order: 18000, requiredEl: "${cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'zoom'}", showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'zoom' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'expressionLanguage') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.errorLabel = # field names # {valueType: "string", order: 19000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'grouper') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.fieldNames = # for logged in user # {valueType: "boolean", order: 20000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'expressionLanguage') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.forLoggedInUser = # group id # {valueType: "string", order: 21000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'expressionLanguage') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.groupId = # group name # {valueType: "string", order: 22000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'expressionLanguage') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.groupName = # label # {valueType: "string", order: 23000, required: true, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'zoom' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'expressionLanguage') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.label = # label externalized text key # {valueType: "string", order: 23500, required: true, showEl: "${numberOfQueries > $i$ && externalizedText && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'zoom' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'expressionLanguage')}", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.labelExternalizedTextKey = # ldap attribute to retrieve # {valueType: "string", order: 24000, showEl: "${numberOfQueries > $i$ && cuQuery.$i$.userQueryType == 'ldap'}", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.ldapAttributeToRetrieve = # ldap filter # {valueType: "string", order: 25000, showEl: "${numberOfQueries > $i$ && cuQuery.$i$.userQueryType == 'ldap'}", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.ldapFilter = # ldap search dn # {valueType: "string", order: 26000, showEl: "${numberOfQueries > $i$ && cuQuery.$i$.userQueryType == 'ldap'}", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.ldapSearchDn = # name of attribute def # {valueType: "string", order: 27000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'expressionLanguage') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.nameOfAttributeDef = # order # {valueType: "integer", order: 28000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'zoom' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'expressionLanguage') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.order = # query # {valueType: "string", order: 29000, showEl: "${numberOfQueries > $i$ && cuQuery.$i$.userQueryType == 'sql'}", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.query = # script # {valueType: "string", order: 30000, requiredEl: "${cuQuery.$i$.userQueryType == 'expressionLanguage'}", showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'zoom' || cuQuery.$i$.userQueryType == 'expressionLanguage') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.script = # stem id # {valueType: "string", order: 31000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'expressionLanguage' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.stemId = # stem name # {valueType: "string", order: 32000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'expressionLanguage' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.stemName = # variable to assign # {valueType: "string", order: 33000, required: true, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'expressionLanguage' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'zoom') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.variableToAssign = # variable to assign on error # {valueType: "string", order: 34000, requiredEl: "${cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'zoom'}", showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'zoom' || cuQuery.$i$.userQueryType == 'expressionLanguage' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'sql') }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.variableToAssignOnError = # variable type # {valueType: "string", order: 35000, showEl: "${numberOfQueries > $i$ && (cuQuery.$i$.userQueryType == 'expressionLanguage' || cuQuery.$i$.userQueryType == 'grouper' || cuQuery.$i$.userQueryType == 'ldap' || cuQuery.$i$.userQueryType == 'sql' || cuQuery.$i$.userQueryType == 'azure' || cuQuery.$i$.userQueryType == 'zoom' ) }", repeatGroup: "cuQuery", repeatCount: 100} # grouperCustomUI.testCustomUI.cuQuery.$i$.variableType = # number of text configs # {valueType: "string", defaultValue: "0", subSection: "cuTextConfigs", order: 36000, formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100"] } # grouperCustomUI.testCustomUI.numberOfTextConfigs = # custom ui text type # {valueType: "string", order: 37000, required: true, showEl: "${numberOfTextConfigs > $i$ }", repeatGroup: "cuTextConfig", repeatCount: 100, formElement: "dropdown", optionValues: ["canAssignVariables", "canSeeScreenState", "canSeeUserEnvironment", "emailBccGroupName", "emailBody", "emailSubject", "emailToUser", "enrollButtonShow", "enrollButtonText", "enrollmentLabel", "header", "helpLink", "instructions1", "logo", "managerInstructions", "unenrollButtonShow", "unenrollButtonText", "manageMembership", "redirectToUrl", "gshScript"]} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.textType = # enabled # {valueType: "boolean", order: 37500, showEl: "${numberOfTextConfigs > $i$ }", repeatGroup: "cuTextConfig", repeatCount: 100} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.enabled = # end if matches # {valueType: "boolean", order: 38000, defaultValue: "false", showEl: "${numberOfTextConfigs > $i$ }", repeatGroup: "cuTextConfig", repeatCount: 100} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.endIfMatches = # index # {valueType: "integer", order: 39000, required: true, showEl: "${numberOfTextConfigs > $i$ }", repeatGroup: "cuTextConfig", repeatCount: 100} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.index = # default text # {valueType: "boolean", order: 40000, defaultValue: "false", showEl: "${numberOfTextConfigs > $i$ }", repeatGroup: "cuTextConfig", repeatCount: 100} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.defaultText = # text # {valueType: "string", order: 41000, required: true, showEl: "${numberOfTextConfigs > $i$ && !(cuTextConfig.$i$.textType == 'canAssignVariables' || cuTextConfig.$i$.textType == 'canSeeScreenState' || cuTextConfig.$i$.textType == 'canSeeUserEnvironment' || cuTextConfig.$i$.textType == 'emailToUser' || cuTextConfig.$i$.textType == 'enrollButtonShow' || cuTextConfig.$i$.textType == 'unenrollButtonShow' || cuTextConfig.$i$.textType == 'manageMembership' ) }", formElement: "textarea", repeatGroup: "cuTextConfig", repeatCount: 100} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.text = # text is script? # {valueType: "boolean", order: 41500, defaultValue: "false", showEl: "${numberOfTextConfigs > $i$ && (cuTextConfig.$i$.textType == 'canAssignVariables' || cuTextConfig.$i$.textType == 'canSeeScreenState' || cuTextConfig.$i$.textType == 'canSeeUserEnvironment' || cuTextConfig.$i$.textType == 'emailToUser' || cuTextConfig.$i$.textType == 'enrollButtonShow' || cuTextConfig.$i$.textType == 'unenrollButtonShow' || cuTextConfig.$i$.textType == 'manageMembership' ) }", repeatGroup: "cuTextConfig", repeatCount: 100} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.textIsScript = # text boolean scalar # {valueType: "boolean", order: 41600, required: true, showEl: "${numberOfTextConfigs > $i$ && !cuTextConfig.$i$.textIsScript && (cuTextConfig.$i$.textType == 'canAssignVariables' || cuTextConfig.$i$.textType == 'canSeeScreenState' || cuTextConfig.$i$.textType == 'canSeeUserEnvironment' || cuTextConfig.$i$.textType == 'emailToUser' || cuTextConfig.$i$.textType == 'enrollButtonShow' || cuTextConfig.$i$.textType == 'unenrollButtonShow' || cuTextConfig.$i$.textType == 'manageMembership' ) }", repeatGroup: "cuTextConfig", repeatCount: 100} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.textBoolean = # text boolean script # {valueType: "string", order: 41700, required: true, showEl: "${numberOfTextConfigs > $i$ && cuTextConfig.$i$.textIsScript && (cuTextConfig.$i$.textType == 'canAssignVariables' || cuTextConfig.$i$.textType == 'canSeeScreenState' || cuTextConfig.$i$.textType == 'canSeeUserEnvironment' || cuTextConfig.$i$.textType == 'emailToUser' || cuTextConfig.$i$.textType == 'enrollButtonShow' || cuTextConfig.$i$.textType == 'unenrollButtonShow' || cuTextConfig.$i$.textType == 'manageMembership' ) }", repeatGroup: "cuTextConfig", repeatCount: 100} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.textBooleanScript = # script # {valueType: "string", order: 42000, showEl: "${numberOfTextConfigs > $i$ }", repeatGroup: "cuTextConfig", repeatCount: 100} # grouperCustomUI.testCustomUI.cuTextConfig.$i$.script = ############################################ ## Gsh templates configuration ############################################ # Template type # {valueType: "string", required: true, order: 500, formElement: "dropdown", optionValues: ["gsh", "abac"] } # grouperGshTemplate.testGshTemplate.templateType = # enabled or disabled # {valueType: "boolean", defaultValue: "true", order: 1000 } # grouperGshTemplate.testGshTemplate.enabled = # GSH template version. V1 is the original legacy version. V2 needs to implement edu.internet2.middleware.grouper.app.gsh.template.GshTemplateV2 and assign to: # gsh_builtin_gshTemplateRuntime.assignGshTemplateV2(gshTemplateV2); # {valueType: "string", defaultValue: "V1", order: 3000, formElement: "dropdown", optionValues: ["V1", "V2"] } # grouperGshTemplate.testGshTemplate.templateVersion = # show on folders # {valueType: "boolean", defaultValue: "false", order: 6000, showEl: "${templateType == 'gsh'}" } # grouperGshTemplate.testGshTemplate.showOnFolders = # folder show type # {valueType: "string", required: true, order: 7000, showEl: "${showOnFolders}", formElement: "dropdown", optionValues: ["certainFolders", "allFolders"] } # grouperGshTemplate.testGshTemplate.folderShowType = # comma separated folder uuids/names to show # {valueType: "string", required: true, order: 8000, showEl: "${showOnFolders && folderShowType == 'certainFolders'}"} # grouperGshTemplate.testGshTemplate.folderUuidToShow = # folder show on descendants # {valueType: "string", required: true, order: 9000, showEl: "${showOnFolders && folderShowType == 'certainFolders'}", formElement: "dropdown", optionValues: ["certainFolders", "oneChildLevel", "certainFoldersAndOneChildLevel", "descendants", "certainFoldersAndDescendants"]} # grouperGshTemplate.testGshTemplate.folderShowOnDescendants = # show on groups # {valueType: "boolean", defaultValue: "false", order: 9100, showEl: "${templateType == 'gsh'}" } # grouperGshTemplate.testGshTemplate.showOnGroups = # groups show type # {valueType: "string", required: true, order: 9200, showEl: "${showOnGroups}", formElement: "dropdown", optionValues: ["certainGroups", "groupsInFolder", "allGroups"] } # grouperGshTemplate.testGshTemplate.groupShowType = # comma separated group uuids/names to show # {valueType: "string", required: true, order: 9300, showEl: "${showOnGroups && groupShowType == 'certainGroups'}"} # grouperGshTemplate.testGshTemplate.groupUuidsToShow = # folder uuid/name under which all the groups will see this template # {valueType: "string", required: true, order: 9400, showEl: "${showOnGroups && groupShowType == 'groupsInFolder'}"} # grouperGshTemplate.testGshTemplate.folderUuidForGroupsInFolder = # group show on descendants # {valueType: "string", required: true, order: 9500, showEl: "${showOnGroups && groupShowType == 'groupsInFolder'}", formElement: "dropdown", optionValues: ["oneChildLevel", "descendants"]} # grouperGshTemplate.testGshTemplate.groupShowOnDescendants = # default run button group or folder # {valueType: "string", order: 9550, showEl: "${showOnFolders || showOnGroups}", formElement: "dropdown", optionValues: ["group", "folder"] } # grouperGshTemplate.testGshTemplate.runButtonGroupOrFolder = # group uuid or name for which this template will be run as default # {valueType: "string", required: true, order: 9600, showEl: "${showOnGroups && runButtonGroupOrFolder == 'group' && showOnGroups}"} # grouperGshTemplate.testGshTemplate.defaultRunButtonGroupUuidOrName = # folder uuid or name for which this template will be run as default # {valueType: "string", required: true, order: 9650, showEl: "${showOnFolders && runButtonGroupOrFolder == 'folder' && showOnFolders}"} # grouperGshTemplate.testGshTemplate.defaultRunButtonFolderUuidOrName = # security run type # {valueType: "string", required: true, order: 10000,formElement: "dropdown", optionValues: ["wheel", "specifiedGroup", "privilegeOnObject", "everyone"] } # grouperGshTemplate.testGshTemplate.securityRunType = # group uuid can run # {valueType: "string", required: true, order: 11000, showEl: "${securityRunType == 'specifiedGroup'}"} # grouperGshTemplate.testGshTemplate.groupUuidCanRun = # require folder privilege # {valueType: "string", required: true, order: 12000, showEl: "${showOnFolders && securityRunType == 'privilegeOnObject'}", formElement: "dropdown", optionValues: ["admin", "create", "stemAttrRead", "stemAttrUpdate"] } # grouperGshTemplate.testGshTemplate.requireFolderPrivilege = # run as type # {valueType: "string", required: true, order: 14000, formElement: "dropdown", optionValues: ["currentUser", "GrouperSystem", "specifiedSubject"] } # grouperGshTemplate.testGshTemplate.runAsType = # act as group uuid # {valueType: "string", order: 14500, showEl: "${templateType == 'gsh'}" } # grouperGshTemplate.testGshTemplate.actAsGroupUUID = # run as specified subject source id # {valueType: "string", required: true, order: 15000, formElement: "dropdown", showEl: "${runAsType == 'specifiedSubject'}", optionValuesFromClass: "edu.internet2.middleware.subject.provider.SourceManagerOptionValueDriver" } # grouperGshTemplate.testGshTemplate.runAsSpecifiedSubjectSourceId = # run as specified subject id # {valueType: "string", required: true, order: 16000, showEl: "${runAsType == 'specifiedSubject'}"} # grouperGshTemplate.testGshTemplate.runAsSpecifiedSubjectId = # use externalized text for labels and descriptions? # {valueType: "boolean", defaultValue: "false", order: 16500 } # grouperGshTemplate.testGshTemplate.externalizedText = # template name externalized text key # {valueType: "string", required: true, order: 17000, showEl: "${externalizedText}" } # grouperGshTemplate.testGshTemplate.templateNameExternalizedTextKey = # template name # {valueType: "string", required: true, order: 17500, showEl: "${!externalizedText}" } # grouperGshTemplate.testGshTemplate.templateName = # template description externalized text key # {valueType: "string", required: true, order: 18000, showEl: "${externalizedText}"} # grouperGshTemplate.testGshTemplate.templateDescriptionExternalizedTextKey = # template description # {valueType: "string", required: true, order: 18500, showEl: "${!externalizedText}", formElement: "textarea"} # grouperGshTemplate.testGshTemplate.templateDescription = # should show in More actions # {valueType: "boolean", defaultValue: "false", order: 18550, showEl: "${templateType == 'gsh'}"} # grouperGshTemplate.testGshTemplate.showInMoreActions = # More actions externalized label # {valueType: "string", required: true, order: 18551, showEl: "${externalizedText && showInMoreActions}" } # grouperGshTemplate.testGshTemplate.moreActionsLabelExternalizedTextKey = # More actions label # {valueType: "string", required: true, order: 18552, showEl: "${!externalizedText && showInMoreActions}" } # grouperGshTemplate.testGshTemplate.moreActionsLabel = # Display error message and output on screen # {valueType: "boolean", defaultValue: "false", order: 18555 } # grouperGshTemplate.testGshTemplate.displayErrorOutput = # gsh lightweight # {valueType: "boolean", defaultValue: "false", order: 18600, showEl: "${templateType == 'gsh'}" } # grouperGshTemplate.testGshTemplate.gshLightweight = # run gsh script in a transaction # {valueType: "boolean", defaultValue: "true", order: 18700, showEl: "${templateType == 'gsh'}" } # grouperGshTemplate.testGshTemplate.runGshInTransaction = # use individual audits? # {valueType: "boolean", defaultValue: "true", order: 18800, showEl: "${templateType == 'gsh'}" } # grouperGshTemplate.testGshTemplate.useIndividualAudits = # consolidate output # {valueType: "boolean", defaultValue: "true", order: 18900, showEl: "${templateType == 'gsh'}" } # grouperGshTemplate.testGshTemplate.consolidateOutput = # simplified ui # {valueType: "boolean", defaultValue: "false", order: 18950 } # grouperGshTemplate.testGshTemplate.simplifiedUi = # allow WS from no owner # {valueType: "boolean", defaultValue: "false", order: 18975 } # grouperGshTemplate.testGshTemplate.allowWsFromNoOwner = # gsh template code # {valueType: "string", required: true, order: 19000, formElement: "textarea" } # grouperGshTemplate.testGshTemplate.gshTemplate = # number of inputs # {valueType: "string", defaultValue: "0", order: 20000, formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50"] } # grouperGshTemplate.testGshTemplate.numberOfInputs = # input name # {valueType: "string", required: true, order: 21000, showEl: "${numberOfInputs > $i$}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.name = # label externalized text key # {valueType: "string", order: 22000, required: true, showEl: "${numberOfInputs > $i$ && externalizedText}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.labelExternalizedTextKey = # label text # {valueType: "string", order: 22500, required: true, showEl: "${numberOfInputs > $i$ && !externalizedText}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.label = # label externalized description key # {valueType: "string", order: 23000, required: true, showEl: "${numberOfInputs > $i$ && externalizedText}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.descriptionExternalizedTextKey = # description # {valueType: "string", order: 23500, required: true, showEl: "${numberOfInputs > $i$ && !externalizedText}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.description = # input type # {valueType: "string", order: 24000, showEl: "${numberOfInputs > $i$}", defaultValue: "string", repeatGroup: "input", repeatCount: 50, formElement: "dropdown", optionValues: ["integer", "boolean", "string"]} # grouperGshTemplate.testGshTemplate.input.$i$.type = # form element type # {valueType: "string", order: 25000, showEl: "${numberOfInputs > $i$ && input.$i$.type != 'boolean' }", defaultValue: "text", repeatGroup: "input", repeatCount: 50, formElement: "dropdown", optionValues: ["text", "textarea", "dropdown", "password"]} # grouperGshTemplate.testGshTemplate.input.$i$.formElementType = # value format for dropdowns # {valueType: "string", order: 25500, showEl: "${numberOfInputs > $i$ && input.$i$.formElementType == 'dropdown'}", defaultValue: "csv", repeatGroup: "input", repeatCount: 50, formElement: "dropdown", optionValues: ["csv", "dynamicFromTemplate", "javaclass", "json", "sql"]} # grouperGshTemplate.testGshTemplate.input.$i$.dropdownValueFormat = # value format csv # {valueType: "string", order: 25600, showEl: "${numberOfInputs > $i$ && input.$i$.formElementType == 'dropdown' && input.$i$.dropdownValueFormat == 'csv'}", required: true, repeatGroup: "input", repeatCount: 50, formElement: "textarea"} # grouperGshTemplate.testGshTemplate.input.$i$.dropdownCsvValue = # value format sql database # {valueType: "string", order: 25630, showEl: "${numberOfInputs > $i$ && input.$i$.formElementType == 'dropdown' && input.$i$.dropdownValueFormat == 'sql'}", required: true, repeatGroup: "input", repeatCount: 50, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem"} # grouperGshTemplate.testGshTemplate.input.$i$.dropdownSqlDatabase = # value format sql # {valueType: "string", order: 25640, showEl: "${numberOfInputs > $i$ && input.$i$.formElementType == 'dropdown' && input.$i$.dropdownValueFormat == 'sql'}", required: true, repeatGroup: "input", repeatCount: 50, formElement: "textarea"} # grouperGshTemplate.testGshTemplate.input.$i$.dropdownSqlValue = # cache for minutes (default 2) # {valueType: "string", order: 25660, showEl: "${numberOfInputs > $i$ && input.$i$.formElementType == 'dropdown' && input.$i$.dropdownValueFormat == 'sql'}", defaultValue: "2", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.dropdownSqlCacheForMinutes = # value format json # {valueType: "string", order: 25700, showEl: "${numberOfInputs > $i$ && input.$i$.formElementType == 'dropdown' && input.$i$.dropdownValueFormat == 'json'}", required: true, repeatGroup: "input", repeatCount: 50, formElement: "textarea"} # grouperGshTemplate.testGshTemplate.input.$i$.dropdownJsonValue = # value format javaclass # {valueType: "string", order: 25800, showEl: "${numberOfInputs > $i$ && input.$i$.formElementType == 'dropdown' && input.$i$.dropdownValueFormat == 'javaclass'}", required: true, repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.dropdownJavaClassValue = # max length # {valueType: "integer", defaultValue: "500", order: 26500, showEl: "${numberOfInputs > $i$ && (input.$i$.formElementType == 'text' || input.$i$.formElementType == 'textarea') && input.$i$.type != 'boolean'}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.maxLength = # index # {valueType: "string", order: 26000, showEl: "${numberOfInputs > $i$}", defaultValue: "0", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.index = # validation type # {valueType: "string", required: true, order: 27000, showEl: "${numberOfInputs > $i$ && input.$i$.type != 'boolean' && input.$i$.formElementType != 'dropdown'}", repeatGroup: "input", repeatCount: 50, formElement: "dropdown", optionValues: ["builtin", "regex", "jexl", "none"]} # grouperGshTemplate.testGshTemplate.input.$i$.validationType = # builtin validation type # {valueType: "string", required: true, order: 27500, showEl: "${numberOfInputs > $i$ && input.$i$.validationType == 'builtin'}", repeatGroup: "input", repeatCount: 50, formElement: "dropdown", optionValues: ["alpha", "alphaNumeric", "alphaNumericUnderscore", "alphaNumericDash", "alphaNumericUnderscoreDash", "noColons"]} # grouperGshTemplate.testGshTemplate.input.$i$.validationBuiltin = # validation regex # {valueType: "string", required: true, order: 28000, showEl: "${numberOfInputs > $i$ && input.$i$.validationType == 'regex'}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.validationRegex = # validation jexl # {valueType: "string", required: true, order: 29000, showEl: "${numberOfInputs > $i$ && input.$i$.validationType == 'jexl'}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.validationJexl = # validation message exteranlized text key # {valueType: "string", order: 30000, repeatGroup: "input", repeatCount: 50, showEl: "${numberOfInputs > $i$ && externalizedText && input.$i$.validationType != 'none' && input.$i$.type != 'boolean' && input.$i$.formElementType != 'dropdown'}"} # grouperGshTemplate.testGshTemplate.input.$i$.validationMessageExternalizedTextKey = # validation message text # {valueType: "string", order: 30500, repeatGroup: "input", repeatCount: 50, showEl: "${numberOfInputs > $i$ && !externalizedText && input.$i$.validationType != 'none' && input.$i$.type != 'boolean' && input.$i$.formElementType != 'dropdown'}"} # grouperGshTemplate.testGshTemplate.input.$i$.validationMessage = # required or not # {valueType: "boolean", defaultValue: "false", order: 31000, repeatGroup: "input", repeatCount: 50, showEl: "${numberOfInputs > $i$}"} # grouperGshTemplate.testGshTemplate.input.$i$.required = # default value for the input if none is provided # {valueType: "string", order: 32000, repeatGroup: "input", repeatCount: 50, showEl: "${numberOfInputs > $i$ && !input.$i$.required}"} # grouperGshTemplate.testGshTemplate.input.$i$.defaultValue = # show el jexl # {valueType: "string", order: 33000, showEl: "${numberOfInputs > $i$}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.showEl = # trim whitespace in values # {valueType: "boolean", order: 33500, defaultValue: "true", showEl: "${numberOfInputs > $i$ && input.$i$.type != 'boolean' && input.$i$.formElementType !='dropdown'}", repeatGroup: "input", repeatCount: 50} # grouperGshTemplate.testGshTemplate.input.$i$.trimWhitespace = # number of tests # {valueType: "string", defaultValue: "0", order: 34000, subSection: "test", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20"] } # 1grouperGshTemplate.testGshTemplate.numberOfTests = # delete side effects if exist gsh # {valueType: "string", order: 35000, formElement: "textarea", showEl: "${numberOfTests > $i$}", repeatGroup: "test", repeatCount: 20} # 1grouperGshTemplate.testGshTemplate.test.$i$.deleteSideEffectsIfExistGsh = # set up gsh # {valueType: "string", order: 36000, formElement: "textarea", showEl: "${numberOfTests > $i$}", repeatGroup: "test", repeatCount: 20} # 1grouperGshTemplate.testGshTemplate.test.$i$.setupGsh = # test gsh # {valueType: "string", order: 37000, formElement: "textarea", required: true, showEl: "${numberOfTests > $i$}", repeatGroup: "test", repeatCount: 20} # 1grouperGshTemplate.testGshTemplate.test.$i$.testGsh = # verify gsh # {valueType: "string", order: 37000, formElement: "textarea", showEl: "${numberOfTests > $i$}", repeatGroup: "test", repeatCount: 20} # 1grouperGshTemplate.testGshTemplate.test.$i$.verifyGsh = ############################################ ## Ws trusted jwt config ############################################ # enabled or disabled # {valueType: "boolean", defaultValue: "true", order: 1000 } # grouper.jwt.trusted.testConfigId.enabled = # subject source id # {valueType: "string", order: 2000, formElement: "checkbox", checkboxValuesFromClass: "edu.internet2.middleware.grouper.SubjectFinder"} # grouper.jwt.trusted.testConfigId.subjectSourceIds = # subject id type # {valueType: "string", required: true, order: 3000, formElement: "dropdown", optionValues: ["subjectId", "subjectIdentifier", "subjectIdOrIdentifier"] } # grouper.jwt.trusted.testConfigId.subjectIdType = # some claim name that has the subjectId in it. optional, can just label claim name as "subjectId", "subjectIdentifier", or "subjectIdOrIdentifier". e.g. employeeId # {valueType: "string", order: 4000 } # grouper.jwt.trusted.testConfigId.subjectIdClaimName = # JWTs only last for so long. e.g. 600 is 10 minutes. -1 means never expire (not recommended) # {valueType: "integer", order: 5000} # grouper.jwt.trusted.testConfigId.expirationSeconds = # number of keys # {valueType: "string", defaultValue: "0", order: 6000, formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] } # grouper.jwt.trusted.testConfigId.numberOfKeys = # public key # {valueType: "string", formElement: "textarea", required: true, order: 7000, showEl: "${numberOfKeys > $i$}", repeatGroup: "key", repeatCount: 10} # grouper.jwt.trusted.testConfigId.key.$i$.publicKey = # encryption type # {valueType: "string", required: true, order: 8000, showEl: "${numberOfKeys > $i$}", repeatGroup: "key", repeatCount: 10, formElement: "dropdown", optionValues: ["RS-256", "RS-384", "RS-512"]} # grouper.jwt.trusted.testConfigId.key.$i$.encryptionType = # optional: yyyy-mm-dd hh:mm:ss.SSS # {valueType: "string", order: 9000, showEl: "${numberOfKeys > $i$}", repeatGroup: "key", repeatCount: 10} # grouper.jwt.trusted.testConfigId.key.$i$.expiresOn = ###################################### ## Global entity attribute resolvers ## These SQL or LDAP attribute resolvers could be used in multiple provisioners or other areas ## entityAttributeResolverId is the unique configId for the attribute resolver ###################################### # Entity attribute resolver type # {valueType: "string", order: 1000, regex: "^entityAttributeResolver\\.([^.]+)\\.resolverType$", required: true, formElement: "dropdown", optionValues: ["sql", "ldap"]} # entityAttributeResolver.entityAttributeResolverId.resolverType = # if this resolver is enabled # {valueType: "boolean", defaultValue: "true", order: 2000 } # entityAttributeResolver.entityAttributeResolverId.enabled = # SQL configId for database connection, default to grouper database # {valueType: "string", order: 3000, regex: "^entityAttributeResolver\\.([^.]+)\\.sqlConfigId$", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem", showEl: "${resolverType == 'sql'}"} # entityAttributeResolver.entityAttributeResolverId.sqlConfigId = # Table of user data, must have a subject source (optional), and matching/search col (required), and columns with single valued attributes # {valueType: "string", order: 4000, regex: "^entityAttributeResolver\\.([^.]+)\\.tableOrViewName$", required: true, showEl: "${resolverType == 'sql'}"} # entityAttributeResolver.entityAttributeResolverId.tableOrViewName = # Comma separated column names from the entity attributes table that need to be added as attributes in the target system # {valueType: "string", order: 4500, regex: "^entityAttributeResolver\\.([^.]+)\\.columnNames$", required: true, showEl: "${resolverType == 'sql'}"} # entityAttributeResolver.entityAttributeResolverId.columnNames = # The subject source id column # {valueType: "string", order: 5000, regex: "^entityAttributeResolver\\.([^.]+)\\.subjectSourceIdColumn$", showEl: "${resolverType == 'sql'}", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.subject.provider.SourceManagerOptionValueDriver"} # entityAttributeResolver.entityAttributeResolverId.subjectSourceIdColumn = # Column that searches and matches an entity # {valueType: "string", order: 6000, regex: "^entityAttributeResolver\\.([^.]+)\\.subjectSearchMatchingColumn$", required: true, showEl: "${resolverType == 'sql'}"} # entityAttributeResolver.entityAttributeResolverId.subjectSearchMatchingColumn = # Grouper attribute that matches the row # {valueType: "string", order: 7000, regex: "^entityAttributeResolver\\.([^.]+)\\.grouperAttributeThatMatchesRow$", required: true, showEl: "${resolverType == 'sql'}", formElement: "dropdown", optionValues: ['subjectId', 'subjectIdentifer0']} # entityAttributeResolver.entityAttributeResolverId.grouperAttributeThatMatchesRow = # The last updated column, e.g. a timestamp or number field (number of millis since 1970) # {valueType: "string", order: 8000, regex: "^entityAttributeResolver\\.([^.]+)\\.lastUpdatedColumn$", showEl: "${resolverType == 'sql'}"} # entityAttributeResolver.entityAttributeResolverId.lastUpdatedColumn = # The last updated column type, e.g. timestamp, millisSince1970. If this is provided then the incremental provisioner will process people that have been recently updated # {valueType: "string", order: 9000, regex: "^entityAttributeResolver\\.([^.]+)\\.lastUpdatedColumn$", showEl: "${resolverType == 'sql'}", formElement: "dropdown", optionValues: ['timestamp', 'millisSince1970']} # entityAttributeResolver.entityAttributeResolverId.lastUpdatedType = # LDAP configId for connection # {valueType: "string", order: 10000, regex: "^entityAttributeResolver\\.([^.]+)\\.ldapConfigId$", required: true, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.externalSystem.LdapGrouperExternalSystem", showEl: "${resolverType == 'ldap'}"} #entityAttributeResolver.entityAttributeResolverId.ldapConfigId = # Base DN for search # {valueType: "string", order: 11000, regex: "^entityAttributeResolver\\.([^.]+)\\.baseDn$", showEl: "${resolverType == 'ldap'}", required: true} # entityAttributeResolver.entityAttributeResolverId.baseDn = # subject source id of subjects # {valueType: "string", order: 11500, regex: "^entityAttributeResolver\\.([^.]+)\\.subjectSourceId$", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.subject.provider.SourceManagerOptionValueDriver"} # entityAttributeResolver.entityAttributeResolverId.subjectSourceId = # Search scope, default is SUBTREE_SCOPE # {valueType: "string", order: 12000, regex: "^entityAttributeResolver\\.([^.]+)\\.searchScope$", showEl: "${resolverType == 'ldap'}", required: true, formElement: "dropdown", optionValues: ['ONELEVEL_SCOPE', ' SUBTREE_SCOPE']} # entityAttributeResolver.entityAttributeResolverId.searchScope = # If there is more to the filter for all users or selected user than just the search attribute, then put that here. e.g. if you have a search attribute of employeeID, and you want the # filter to be (&(employeeID=12345678)(objectClass=person)) then you should fill in this value as: (objectClass=person) # {valueType: "string", order: 13000, regex: "^entityAttributeResolver\\.([^.]+)\\.filterPart$", showEl: "${resolverType == 'ldap'}"} # entityAttributeResolver.entityAttributeResolverId.filterPart = # Attributes to retrieve (multi-valued attributes will be stored in appropriate structure) # {valueType: "string", order: 14000, regex: "^entityAttributeResolver\\.([^.]+)\\.ldapAttributes$", showEl: "${resolverType == 'ldap'}", required: true} # entityAttributeResolver.entityAttributeResolverId.ldapAttributes = # Which attributes are multivalued # {valueType: "string", order: 14500, regex: "^entityAttributeResolver\\.([^.]+)\\.multiValuedLdapAttributes$", showEl: "${resolverType == 'ldap'}"} # entityAttributeResolver.entityAttributeResolverId.multiValuedLdapAttributes = # LDAP matching / search attribute, this needs to be the same as the subject ID or subject identifier0 # {valueType: "string", order: 15000, regex: "^entityAttributeResolver\\.([^.]+)\\.subjectSearchMatchingAttribute$", showEl: "${resolverType == 'ldap'}", required: true} # entityAttributeResolver.entityAttributeResolverId.subjectSearchMatchingAttribute = # Grouper attribute that matches the record # {valueType: "string", order: 16000, regex: "^entityAttributeResolver\\.([^.]+)\\.grouperAttributeThatMatchesRecord$", required: true, showEl: "${resolverType == 'ldap'}", formElement: "dropdown", optionValues: ['subjectId', 'subjectIdentifer0']} # entityAttributeResolver.entityAttributeResolverId.grouperAttributeThatMatchesRecord = # If provided the incremental can poll for new records to process. e.g. the filter would be (openldap / edirectory) (modifyTimestamp>=20211119082103Z), or Active Directory: (modifyTimestamp>= 20211119163324.0Z) # {valueType: "string", order: 17000, regex: "^entityAttributeResolver\\.([^.]+)\\.lastUpdatedAttribute$", showEl: "${resolverType == 'ldap'}"} # entityAttributeResolver.entityAttributeResolverId.lastUpdatedAttribute = # This is optional, if not selected it will select default 20211119082103Z for a non AD connection and activeDirectory 20211119163324.0Z for # an active directory connection (which is selected in the external system) # {valueType: "string", order: 18000, regex: "^entityAttributeResolver\\.([^.]+)\\.ldapLastUpdatedFormat$", showEl: "${resolverType == 'ldap'}", formElement: "dropdown", optionValues: ['default', 'activeDirectory']} # entityAttributeResolver.entityAttributeResolverId.ldapLastUpdatedFormat = ############################################ ## OIDC external system ############################################ # if this oidc connector is enabled # {valueType: "boolean", defaultValue: "true", order: 1000 } # grouper.oidcExternalSystem.myOidcConfigId.enabled = # Do you want to specify URLs or want to use the well known URL? # {valueType: "boolean", required: true, order: 1250 } # grouper.oidcExternalSystem.myOidcConfigId.useConfigurationMetadata = # Configuration metadata uri # {valueType: "string", required: true, order: 1500, showEl: "${useConfigurationMetadata}"} # grouper.oidcExternalSystem.myOidcConfigId.configurationMetadataUri = # url to decode the oidc code into an access token: https://idp.institution.edu/idp/profile/oidc/token # {valueType: "string", required: true, order: 2000, showEl: "${!useConfigurationMetadata}" } # grouper.oidcExternalSystem.myOidcConfigId.tokenEndpointUri = # URL to log in (without parameters) https://idp.institution.edu/idp/profile/oidc/authorize # {valueType: "string", required: false, order: 3500, showEl: "${!useConfigurationMetadata}" } # grouper.oidcExternalSystem.myOidcConfigId.authorizeUri = # client id to authorize url (required) # {valueType: "string", required: true, order: 4000 } # grouper.oidcExternalSystem.myOidcConfigId.clientId = # secret to ws (required) # {valueType: "password", sensitive: true, required: true, order: 5000 } # grouper.oidcExternalSystem.myOidcConfigId.clientSecret = # proxy requests here, e.g. https://server:1234 # {valueType: "string", order: 6000 } # grouper.oidcExternalSystem.myOidcConfigId.proxyUrl = # socks or http # {valueType: "string", order: 7000, formElement: "dropdown", optionValues: ["PROXY_HTTP", "PROXY_SOCKS5"] } # grouper.oidcExternalSystem.myOidcConfigId.proxyType = # needed for retrieving an access token, e.g. https://my.app/someUrlBackFromIdp # {valueType: "string", order: 10000 } # grouper.oidcExternalSystem.myOidcConfigId.redirectUri = # Scope to retrieve from oidc, e.g. openid email profile (required) # {valueType: "string", required: true, order: 11000} # grouper.oidcExternalSystem.myOidcConfigId.scope = # subject source id # {valueType: "string", order: 12000, formElement: "checkbox", checkboxValuesFromClass: "edu.internet2.middleware.grouper.SubjectFinder"} # grouper.oidcExternalSystem.myOidcConfigId.subjectSourceIds = # Subject id type # {valueType: "string", required: true, order: 13000, formElement: "dropdown", optionValues: ["subjectId", "subjectIdentifier", "subjectIdOrIdentifier"] } # grouper.oidcExternalSystem.myOidcConfigId.subjectIdType = # Source for claims # {valueType: "string", defaultValue: "userInfoEndpoint", order: 13100, formElement: "dropdown", optionValues: ["userInfoEndpoint", "idToken"]} # grouper.oidcExternalSystem.myOidcConfigId.claimSource = # url to get the user info from the access token https://idp.pennkey.upenn.edu/idp/profile/oidc/userinfo # {valueType: "string", required: true, order: 13200, indent: 1, showEl: "${!useConfigurationMetadata && claimSource == 'userInfoEndpoint'}" } # grouper.oidcExternalSystem.myOidcConfigId.userInfoUri = # Token issuer (iss claim in id token) # {valueType: "string", required: true, order: 13300, indent: 1, showEl: "${!useConfigurationMetadata && claimSource == 'idToken'}" } # grouper.oidcExternalSystem.myOidcConfigId.issuer = # The maximum acceptable clock skew in seconds for timestamps in the id token # {valueType: "integer", defaultValue: "300", order: 13400, indent: 1, showEl: "${claimSource == 'idToken'}" } # grouper.oidcExternalSystem.myOidcConfigId.maxClockSkew = # some claim name that has the subjectId / subjectIdentifier / subjectIdOrIdentifier in it. e.g. preferred_username # {valueType: "string", defaultValue: "preferred_username", order: 14000 } # grouper.oidcExternalSystem.myOidcConfigId.subjectIdClaimName = # e.g. code # {valueType: "string", order: 15000 } # grouper.oidcExternalSystem.myOidcConfigId.oidcResponseType = # Use for UI? # {valueType: "boolean", defaultValue: "false", order: 16000 } # grouper.oidcExternalSystem.myOidcConfigId.useForUi = # Use for WS? # {valueType: "boolean", defaultValue: "false", order: 17000 } # grouper.oidcExternalSystem.myOidcConfigId.useForWs = ############################################ ## osgi config ############################################ # directory of plugins, default to /opt/grouper/grouperWebapp/WEB-INF/grouperPlugins # {valueType: "string", required: true, order: 1000} grouper.osgi.jar.dir = /opt/grouper/grouperWebapp/WEB-INF/grouperPlugins # directory of felix cache of plugins, default to /opt/grouper/grouperWebapp/WEB-INF/grouperFelixCache # {valueType: "string", required: true, order: 2000} grouper.felix.cache.rootdir = /opt/grouper/grouperWebapp/WEB-INF/grouperFelixCache # only enable osgi if you use it # {valueType: "boolean", defaultValue: "false", order: 3000} grouper.osgi.enable = # jar name of plugin e.g. my-plugin-with-embedded-dependencies-1.2.3.jar # {valueType: "string", required: true, order: 10000} # grouperOsgiPlugin.testConfigId.jarName = # number of implementations that this jar provides # {valueType: "integer", required: true, order: 11000, formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] } # grouperOsgiPlugin.testConfigId.numberOfImplementations = # implementation class that implements an interface, e.g. some.package.SomeClass # {valueType: "string", required: true, order: 12000, showEl: "${numberOfImplementations > $i$}", repeatGroup: "osgiImplementation", repeatCount: 10} # grouperOsgiPlugin.testConfigId.osgiImplementation.$i$.implementationClass = # interface that the class implements. e.g. edu.interent2.middleware.grouper.some.package.SomeInterface # {valueType: "string", required: true, order: 13000, showEl: "${numberOfImplementations > $i$}", repeatGroup: "osgiImplementation", repeatCount: 10} # grouperOsgiPlugin.testConfigId.osgiImplementation.$i$.implementsInterface = ############################################ ## logging loggers (levels and appenders) ## dynamically update grouper on config change ############################################ # if should check for dynamic updates # {valueType: "boolean", defaultValue: "true" } # grouper.logging.dynamicUpdates.run = # sleep for this amount of seconds after each run # {valueType: "boolean", defaultValue: "60" } # grouper.logging.dynamicUpdates.checkAfterSeconds = # this is the package or class to log, required # {valueType: "string", regex: "^grouper\\.logger\\.[^.]+\\.name$"} # grouper.logger..name = # required log level, should be one of: off, fatal, error, warn, info, debug, trace, all # {valueType: "string", regex: "^grouper\\.logger\\.[^.]+\\.level$", formElement: "dropdown", optionValues: ["off", "fatal", "error", "warn", "info", "debug", "trace", "all"] } # grouper.logger..level = # which appender to send logs to (optional), default to the appender for the class logs to, or default to: grouper_error # e.g. CATALINA, stderr, grouper_error, grouper_daemon, grouper_pspng, grouper_provisioning, grouper_ws, grouper_ws_longRunning # {valueType: "string", regex: "^grouper\\.logger\\.[^.]+\\.appender$"} # grouper.logger..appender = ########################################################################### ## institution specific external systems. For e.g. for custom provisioner ########################################################################### # This is the external system class that extends edu.internet2.middleware.grouper.app.externalSystem.GrouperExternalSystem # {valueType: "string", regex: "^grouperExtraExternalSystem\\.[^.]+\\.class$", mustExtendClass: "edu.internet2.middleware.grouper.app.externalSystem.GrouperExternalSystem"} # grouperExtraExternalSystem..class = ########################################################################### ## grouper dictionary ########################################################################### # max terms in memory # {valueType: "integer"} grouper.dictionary.maxTermsInMemoryCache = 50000 # how long to cache terms # {valueType: "integer"} grouper.dictionary.cacheStoreForMinutes = 120 ########################################################################### ## privacy realms ########################################################################### # name of this privacy realm, not really used, just here to configure the realm # {valueType: "string", required: true, regex: "^grouperPrivacyRealm\\.[^.]+\\.privacyRealmName$"} # grouperPrivacyRealm.privacyRealmConfigId.privacyRealmName = # if this field can be seen by anyone, even if not authenticated # {valueType: "boolean", defaultValue: "false", regex: "^grouperPrivacyRealm\\.[^.]+\\.privacyRealmPublic$"} # grouperPrivacyRealm.privacyRealmConfigId.privacyRealmPublic = # if this field can be seen by anyone who is authenticated # {valueType: "boolean", defaultValue: "false", regex: "^grouperPrivacyRealm\\.[^.]+\\.privacyRealmAuthenticated$", showEl: "${!privacyRealmPublic}"} # grouperPrivacyRealm.privacyRealmConfigId.privacyRealmAuthenticated = # if this field can be seen by grouper sysadmins who are not in the viewers group # {valueType: "boolean", defaultValue: "true", regex: "^grouperPrivacyRealm\\.[^.]+\\.privacyRealmSysadminsCanView$", showEl: "${!privacyRealmPublic && !privacyRealmAuthenticated}"} # grouperPrivacyRealm.privacyRealmConfigId.privacyRealmSysadminsCanView = # group name of the group who can view and use fields marked in this privacy realm # {valueType: "string", required: true, regex: "^grouperPrivacyRealm\\.[^.]+\\.privacyRealmViewersGroupName$", showEl: "${!privacyRealmPublic && !privacyRealmAuthenticated}"} # grouperPrivacyRealm.privacyRealmConfigId.privacyRealmViewersGroupName = # group name of the group who can update and use fields marked in this privacy realm # {valueType: "string", required: true, regex: "^grouperPrivacyRealm\\.[^.]+\\.privacyRealmUpdatersGroupName$", showEl: "${!privacyRealmPublic && !privacyRealmAuthenticated}"} # grouperPrivacyRealm.privacyRealmConfigId.privacyRealmUpdatersGroupName = # group name of the group who can read and use fields marked in this privacy realm # {valueType: "string", required: true, regex: "^grouperPrivacyRealm\\.[^.]+\\.privacyRealmReadersGroupName$", showEl: "${!privacyRealmPublic && !privacyRealmAuthenticated}"} # grouperPrivacyRealm.privacyRealmConfigId.privacyRealmReadersGroupName = ########################################################################### ## grouper data fields ########################################################################### # aliases that this field is referred to as # {valueType: "string", required: true, multiple: true, regex: "^grouperDataField\\.[^.]+\\.fieldAliases$"} # grouperDataField.dataFieldConfigId.fieldAliases = # privacy realm for people who can see or use this data field # {valueType: "string", required: true, regex: "^grouperDataField\\.[^.]+\\.fieldPrivacyRealm$", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.dataField.GrouperPrivacyRealm"} # grouperDataField.dataFieldConfigId.fieldPrivacyRealm = # Description html # {valueType: "string", required: true, regex: "^grouperDataField\\.[^.]+\\.descriptionHtml$", formElement: "textarea"} # grouperDataField.dataFieldConfigId.descriptionHtml = # Data owner html # {valueType: "string", regex: "^grouperDataField\\.[^.]+\\.dataOwnerHtml$", formElement: "textarea"} # grouperDataField.dataFieldConfigId.dataOwnerHtml = # How to get access html # {valueType: "string", regex: "^grouperDataField\\.[^.]+\\.howToGetAccessHtml$", formElement: "textarea"} # grouperDataField.dataFieldConfigId.howToGetAccessHtml = # Zero to many examples html # {valueType: "string", regex: "^grouperDataField\\.[^.]+\\.zeroToManyExamplesHtml$", formElement: "textarea"} # grouperDataField.dataFieldConfigId.zeroToManyExamplesHtml = # if this field can have multiple values # {valueType: "boolean", defaultValue: "false", regex: "^grouperDataField\\.[^.]+\\.fieldMultiValued$"} # grouperDataField.dataFieldConfigId.fieldMultiValued = # data type for this field # {valueType: "string", defaultValue: "string", regex: "^grouperDataField\\.[^.]+\\.fieldDataType$", formElement: "dropdown", optionValues: ["string", "integer", "timestamp", "boolean"]} # grouperDataField.dataFieldConfigId.fieldDataType = # data structure for this field # {valueType: "string", defaultValue: "attribute", regex: "^grouperDataField\\.[^.]+\\.fieldDataStructure$", formElement: "dropdown", optionValues: ["attribute", "rowColumn"]} # grouperDataField.dataFieldConfigId.fieldDataStructure = # use of this field. If it is access related then it will be available in an abac script # {valueType: "string", defaultValue: "access", regex: "^grouperDataField\\.[^.]+\\.fieldDataUse$", formElement: "dropdown", optionValues: ["access", "identifier", "informational"]} # grouperDataField.dataFieldConfigId.fieldDataUse = # if this field is calculated from multiple providers. If it is calculated from one provider, it can be configured in that provider # {valueType: "boolean", defaultValue: "false", regex: "^grouperDataField\\.[^.]+\\.fieldDataCalculated$"} # grouperDataField.dataFieldConfigId.fieldDataCalculated = # script to build this data field value from multiple providers # {valueType: "string", defaultValue: "false", regex: "^grouperDataField\\.[^.]+\\.fieldDataCalculatedScript$", formElement: "textarea"} # grouperDataField.dataFieldConfigId.fieldDataCalculatedScript = # if this informational data field is dynamic based on privacy levels # {valueType: "boolean", defaultValue: "false", regex: "^grouperDataField\\.[^.]+\\.fieldDataInformationalDynamicPrivacyLevel$", showEl: "${fieldDataUse == 'informational'}"} # grouperDataField.dataFieldConfigId.fieldDataInformationalDynamicPrivacyLevel = # Config ids in order to see if the user can see them, # {valueType: "string", regex: "^grouperDataField\\.[^.]+\\.fieldDataInformationalDynamicPrivacyLevelConfigIds$", showEl: "${fieldDataInformationalDynamicPrivacyLevel}"} # grouperDataField.dataFieldConfigId.fieldDataInformationalDynamicPrivacyLevelConfigIds = # does this identifier require the data field name or is the identifier unique across all identifiers # {valueType: "boolean", regex: "^grouperDataField\\.[^.]+\\.fieldDataIdentifierRequiresName$", showEl: "${fieldDataUse == 'identifier'}"} # grouperDataField.dataFieldConfigId.fieldDataIdentifierRequiresName = # field source. Could be sourced from a data provider. Could be sourced from a group membership. # {valueType: "string", defaultValue: "provider", regex: "^grouperDataField\\.[^.]+\\.fieldDataSource$", formElement: "dropdown", optionValues: ["provider", "group"], showEl: "${fieldDataUse == 'access'}"} # grouperDataField.dataFieldConfigId.fieldDataSource = # group name of source of this data field # {valueType: "string", defaultValue: "attribute", regex: "^grouperDataField\\.[^.]+\\.fieldDataGroupName$", showEl: "${fieldDataSource == 'group'}"} # grouperDataField.dataFieldConfigId.fieldDataGroupName = # should this field be stored in PIT. All identifiers will be in PIT. # {valueType: "boolean", regex: "^grouperDataField\\.[^.]+\\.fieldDataStorePit$", showEl: "${fieldDataUse == 'access' || fieldDataUse == 'informational' }"} # grouperDataField.dataFieldConfigId.fieldDataStorePit = # how many days to store PIT. # {valueType: "integer", defaultValue: "730", regex: "^grouperDataField\\.[^.]+\\.fieldDataStorePitDays$", showEl: "${fieldDataStorePit}"} # grouperDataField.dataFieldConfigId.fieldDataStorePitDays = # Is this assignable to groups or individuals. # {valueType: "string", regex: "^grouperDataField\\.[^.]+\\.fieldDataAssignableTo$", formElement: "dropdown", optionValues: ["global", "groups", "individuals"]} # grouperDataField.dataFieldConfigId.fieldDataAssignableTo = # Are the values for this data fields a list of values with less than 100ish options? Used for validation of ABAC scripts # {valueType: "boolean", defaultValue: "false", regex: "^grouperDataField\\.[^.]+\\.fieldDataLov$"} # grouperDataField.dataFieldConfigId.fieldDataLov = # Should the list of value be existing assigned values? This is the easiest way to configure, but every value must be assigned at least once # {valueType: "boolean", defaultValue: "false", regex: "^grouperDataField\\.[^.]+\\.fieldDataLovExistingValues$", showEl: "${fieldDataLov}"} # grouperDataField.dataFieldConfigId.fieldDataLovExistingValues = # Database external system config ID for list of values # {valueType: "string", required: true, regex: "^grouperDataField\\.[^.]+\\.fieldDataLovDatabaseConfigId$", showEl: "${fieldDataLov && !fieldDataLovExistingValues}"} # grouperDataField.dataFieldConfigId.fieldDataLovDatabaseConfigId = # Database query for list of values should have one column and the data type (string, int, etc) will be converted to the data field type. # {valueType: "string", required: true, regex: "^grouperDataField\\.[^.]+\\.fieldDataLovDatabaseConfigId$", showEl: "${fieldDataLov && !fieldDataLovExistingValues}"} # grouperDataField.dataFieldConfigId.fieldDataLovDatabaseQuery = # How long to cache list of values. Note: if a new value is used which is not known, the cache will refresh to be sure. So 1440 (one day) should be fine. # {valueType: "integer", defaultValue: "1440", regex: "^grouperDataField\\.[^.]+\\.fieldDataLovDatabaseConfigId$", showEl: "${fieldDataLov && !fieldDataLovExistingValues}"} # grouperDataField.dataFieldConfigId.fieldDataLovCacheforMinutes = ########################################################################### ## grouper data rows ########################################################################### # aliases that this row is referred to as # {valueType: "string", order: 1000, subSection: "dataRowConfig", required: true, multiple: true, regex: "^grouperDataRow\\.[^.]+\\.rowAliases$"} # grouperDataRow.dataRowConfigId.rowAliases = # privacy realm for people who can see or use this data row # {valueType: "string", order: 2000, subSection: "dataRowConfig", required: true, regex: "^grouperDataRow\\.[^.]+\\.rowPrivacyRealm$", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.dataField.GrouperPrivacyRealm"} # grouperDataRow.dataRowConfigId.rowPrivacyRealm = # Description html # {valueType: "string", required: true, regex: "^dataRowConfigId\\.[^.]+\\.descriptionHtml$", formElement: "textarea"} # grouperDataRow.dataRowConfigId.descriptionHtml = # Data owner html # {valueType: "string", regex: "^dataRowConfigId\\.[^.]+\\.dataOwnerHtml$", formElement: "textarea"} # grouperDataRow.dataRowConfigId.dataOwnerHtml = # How to get access html # {valueType: "string", regex: "^dataRowConfigId\\.[^.]+\\.howToGetAccessHtml$", formElement: "textarea"} # grouperDataRow.dataRowConfigId.howToGetAccessHtml = # Zero to many examples html # {valueType: "string", regex: "^dataRowConfigId\\.[^.]+\\.zeroToManyExamplesHtml$", formElement: "textarea"} # grouperDataRow.dataRowConfigId.zeroToManyExamplesHtml = # number of fields in this row # {valueType: "string", order: 3000, subSection: "dataRowConfig", required: true, regex: "^grouperDataRow\\.[^.]+\\.rowNumberOfDataFields$", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30"]} # grouperDataRow.dataRowConfigId.rowNumberOfDataFields = # data field for this column # {valueType: "string", required: true, order: 4000, showEl: "${rowNumberOfDataFields > $i$}", repeatGroup: "rowDataField", repeatCount: 30, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.dataField.GrouperDataField"} # grouperDataRow.dataRowConfigId.rowDataField.$i$.colDataFieldConfigId = # if this data field is the key or part of a composite key that uniquely matches this row from source and grouper # {valueType: "boolean", order: 4010, defaultValue: "false", showEl: "${rowNumberOfDataFields > $i$}", repeatGroup: "rowDataField", repeatCount: 30} # grouperDataRow.dataRowConfigId.rowDataField.$i$.rowKeyField = ########################################################################### ## grouper data providers ########################################################################### # data provider name, not really needed or used, but there to setup the provider # {valueType: "string", required: true, multiple: true, regex: "^grouperDataProvider\\.[^.]+\\.name$"} # grouperDataProvider.dataProviderConfigId.name = ########################################################################### ## grouper data provider change log query ########################################################################### # data provider config id # {valueType: "string", order: 1000, subSection: "dataProviderChangeLogQueryConfig", required: true, regex: "^grouperDataProviderChangeLogQuery\\.[^.]+\\.providerConfigId$", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.dataField.GrouperDataProvider"} # grouperDataProviderChangeLogQuery.dataProviderChangeLogQueryConfigId.providerConfigId = # data provider change log query type # {valueType: "string", order: 2000, subSection: "dataProviderChangeLogQueryConfig", required: true, regex: "^grouperDataProviderChangeLogQuery\\.[^.]+\\.providerChangeLogQueryType$", formElement: "dropdown", optionValues: ["sql"]} # grouperDataProviderChangeLogQuery.dataProviderChangeLogQueryConfigId.providerChangeLogQueryType = # SQL config id # {valueType: "string", order: 3000, subSection: "dataProviderChangeLogQueryConfig", required: true, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem", regex: "^grouperDataProviderChangeLogQuery\\.[^.]+\\.providerChangeLogQuerySqlConfigId$", showEl: "${providerChangeLogQueryType == 'sql'}"} # grouperDataProviderChangeLogQuery.dataProviderChangeLogQueryConfigId.providerChangeLogQuerySqlConfigId = # SQL change log query # {valueType: "string", order: 4000, subSection: "dataProviderChangeLogQueryConfig", required: true, regex: "^grouperDataProviderChangeLogQuery\\.[^.]+\\.providerChangeLogQuerySqlQuery$", showEl: "${providerChangeLogQueryType == 'sql'}"} # grouperDataProviderChangeLogQuery.dataProviderChangeLogQueryConfigId.providerChangeLogQuerySqlQuery = # Change log attribute that is the primary key # {valueType: "string", order: 5000, subSection: "dataProviderChangeLogQueryConfig", required: true, regex: "^grouperDataProviderChangeLogQuery\\.[^.]+\\.providerChangeLogQueryPrimaryKeyAttribute$"} # grouperDataProviderChangeLogQuery.dataProviderChangeLogQueryConfigId.providerChangeLogQueryPrimaryKeyAttribute = # Change log attribute that contains the timestamp for when this row was added, e.g. a timestamp or number field (number of millis since 1970). Should be indexed where possible. # {valueType: "string", order: 6000, subSection: "dataProviderChangeLogQueryConfig", required: true, regex: "^grouperDataProviderChangeLogQuery\\.[^.]+\\.providerChangeLogQueryTimestampAttribute$"} # grouperDataProviderChangeLogQuery.dataProviderChangeLogQueryConfigId.providerChangeLogQueryTimestampAttribute = # Change log attribute which links this data to subjects # {valueType: "string", order: 7000, subSection: "dataProviderChangeLogQueryConfig", required: true, regex: "^grouperDataProviderChangeLogQuery\\.[^.]+\\.providerChangeLogQuerySubjectIdAttribute$"} # grouperDataProviderChangeLogQuery.dataProviderChangeLogQueryConfigId.providerChangeLogQuerySubjectIdAttribute = # Which type of subject id # {valueType: "string", order: 8000, subSection: "dataProviderChangeLogQueryConfig", regex: "^grouperDataProviderChangeLogQuery\\.[^.]+\\.providerChangeLogQuerySubjectIdType$", formElement: "dropdown", optionValues: ["subjectId", "subjectIdentifier"]} # grouperDataProviderChangeLogQuery.dataProviderChangeLogQueryConfigId.providerChangeLogQuerySubjectIdType = # which subject source this is a subject id for # {valueType: "string", order: 9000, subSection: "dataProviderChangeLogQueryConfig", regex: "^grouperDataProviderChangeLogQuery\\.[^.]+\\.providerChangeLogQuerySubjectSourceId$"} # grouperDataProviderChangeLogQuery.dataProviderChangeLogQueryConfigId.providerChangeLogQuerySubjectSourceId = ########################################################################### ## grouper data provider query ########################################################################### # data provider config id # {valueType: "string", order: 1000, subSection: "dataProviderQueryConfig", required: true, regex: "^grouperDataProviderQuery\\.[^.]+\\.providerConfigId$", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.dataField.GrouperDataProvider"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerConfigId = # data provider query type # {valueType: "string", order: 2000, subSection: "dataProviderQueryConfig", required: true, regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQueryType$", formElement: "dropdown", optionValues: ["sql", "ldap"]} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryType = # SQL config id # {valueType: "string", order: 3000, subSection: "dataProviderQueryConfig", required: true, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem", regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQuerySqlConfigId$", showEl: "${providerQueryType == 'sql'}"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQuerySqlConfigId = # LDAP config id # {valueType: "string", order: 3500, subSection: "dataProviderQueryConfig", required: true, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.externalSystem.LdapGrouperExternalSystem", regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQueryLdapConfigId$", showEl: "${providerQueryType == 'ldap'}"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryLdapConfigId = # SQL query # {valueType: "string", order: 4000, subSection: "dataProviderQueryConfig", required: true, regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQuerySqlQuery$", showEl: "${providerQueryType == 'sql'}"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQuerySqlQuery = # LDAP base dn # {valueType: "string", order: 4100, subSection: "dataProviderQueryConfig", required: true, regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQueryLdapBaseDn$", showEl: "${providerQueryType == 'ldap'}"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryLdapBaseDn = # LDAP search scope # {valueType: "string", order: 4200, subSection: "dataProviderQueryConfig", required: true, regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQueryLdapSearchScope$", showEl: "${providerQueryType == 'ldap'}", formElement: "dropdown", optionValues: ['ONELEVEL_SCOPE', ' SUBTREE_SCOPE']} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryLdapSearchScope = # LDAP filter # {valueType: "string", order: 4300, subSection: "dataProviderQueryConfig", required: true, regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQueryLdapFilter$", showEl: "${providerQueryType == 'ldap'}"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryLdapFilter = # Data structure # {valueType: "string", order: 5000, subSection: "dataProviderQueryConfig", required: true, regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQueryDataStructure$", formElement: "dropdown", optionValues: ["attribute", "row"], showEl: "${providerQueryType == 'sql'}"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryDataStructure = # Data row to link to # {valueType: "string", order: 6000, subSection: "dataProviderQueryConfig", required: true, regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQueryRowConfigId$", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.dataField.GrouperDataRow", showEl: "${providerQueryDataStructure == 'row'}"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryRowConfigId = # Attribute which links this data to subjects # {valueType: "string", order: 7000, subSection: "dataProviderQueryConfig", required: true, regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQuerySubjectIdAttribute$"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQuerySubjectIdAttribute = # Which type of subject id # {valueType: "string", order: 8000, subSection: "dataProviderQueryConfig", regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQuerySubjectIdType$", formElement: "dropdown", optionValues: ["subjectId", "subjectIdentifier"]} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQuerySubjectIdType = # which subject source this is a subject id for # {valueType: "string", order: 9000, subSection: "dataProviderQueryConfig", regex: "^grouperDataProviderQuery\\.[^.]+\\.providerQuerySubjectSourceId$"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQuerySubjectSourceId = # number of fields in this row # {valueType: "string", order: 10000, subSection: "dataProviderQueryConfig", required: true, regex: "^dataProviderQueryConfigId\\.[^.]+\\.rowNumberOfDataFields$", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30"]} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryNumberOfDataFields = # data field for this column # {valueType: "string", order: 11000, showEl: "${providerQueryNumberOfDataFields > $i$}", repeatGroup: "providerQueryDataField", repeatCount: 30, required: true, regex: "^dataProviderQueryConfigId\\.[^.]+\\.providerQueryDataField\\.[0-9]+\\.providerDataFieldConfigId$", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.dataField.GrouperDataField"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryDataField.$i$.providerDataFieldConfigId = # mapping type for this data field, e.g. could be translation eventually # {valueType: "string", order: 12000, showEl: "${providerQueryNumberOfDataFields > $i$}", repeatGroup: "providerQueryDataField", repeatCount: 30, required: true, regex: "^dataProviderQueryConfigId\\.[^.]+\\.providerQueryDataField\\.[0-9]+\\.providerDataFieldMappingType$", formElement: "dropdown", optionValues: ["attribute"]} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryDataField.$i$.providerDataFieldMappingType = # mapping type for this data field # {valueType: "string", order: 13000, showEl: "${providerQueryNumberOfDataFields > $i$}", repeatGroup: "providerQueryDataField", repeatCount: 30, required: true, regex: "^dataProviderQueryConfigId\\.[^.]+\\.providerQueryDataField\\.[0-9]+\\.providerDataFieldAttribute$", showEl: "${providerQueryDataField.$i$.providerDataFieldMappingType == 'attribute'}"} # grouperDataProviderQuery.dataProviderQueryConfigId.providerQueryDataField.$i$.providerDataFieldAttribute = ########################################################################### ## JEXL script testing ########################################################################### # Users have to be sysadmins and member of this group to be able to run JEXL script tests # {valueType: "group"} jexlScriptTestingGroup = $$grouper.rootStemForBuiltinObjects$$:jexlScriptTestingGroup # In order to have institution specific JEXL test example for an existing script type # {valueType: "string"} # jexlScriptTest.institutionExample.. = ########################################################################### ## Box mock testing properties ########################################################################### # box mock config id # {valueType: "string"} # grouperTest.box.mock.configId = # box mock public key # {valueType: "string"} # grouperTest.box.mock.publicKey = # box mock private key # {valueType: "string"} # grouperTest.box.mock.privateKey = # box mock public key id # {valueType: "string"} # grouperTest.box.mock.publicKeyId = ########################################################################### ## Json serializing deserializing settings ########################################################################### # use json lib when legacy is set to true. False means use jackson. Jackson is much faster. # {valueType: "boolean"} grouper.json.serialize.deserialize.useLegacy = false # the legacy serialization would not throw an error if an invalid property is sent (when marhsaled to bean). if there is an # exception with the new way, log it once an hour and use the legacy # {valueType: "boolean"} grouper.json.serialize.deserialize.useLegacyOnError = true # dont fill up logs, only log after this many millis, 1000*60*60 # {valueType: "integer"} grouper.json.serialize.deserialize.parseErrorLogEveryMillis = 3600000 ########################################################################### ## HTTP client settings ########################################################################### # default pool size for an HTTP client. i.e. this is the max number of connections outbound at once per container instance # {valueType: "integer", defaultValue: "100"} httpClientMaxTotalPoolSize = # default number of connections at once for an endpoint from a container # {valueType: "integer", defaultValue: "30"} httpClientDefaultMaxPerRoute = # if HTTP client instances should be re-used # {valueType: "boolean", defaultValue: "true"} httpClientReuse =




© 2015 - 2024 Weber Informatics LLC | Privacy Policy