# # 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, regex: "^security\\.types\\.([^.]+)\\.wheelOnly$"} 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, regex: "^security\\.types\\.([^.]+)\\.wheelOnly$"} 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: "group", required: true, regex: "^security\\.member\\.sort\\.string([0-9]+)\\.allowOnlyGroup$"} #security.member.sort.string1.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.string2.wheelOnly = true # 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.string3.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: "group", required: true, regex: "^security\\.member\\.search\\.string([0-9]+)\\.allowOnlyGroup$"} #security.member.search.string1.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 # 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} #security.member.search.string3.wheelOnly = true # if folders should be shown only if there is an object inside that the user can see # {valueType: "boolean", required: true} security.show.folders.where.user.can.see.subobjects = 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 = # 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 ################################### ## 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=sa # 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:hsqldb:hsql://localhost:9001/grouper # 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, regex: "^db\\.change\\.allow\\.url\\.([0-9]+)$"} 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, regex: "^db\\.change\\.allow\\.user\\.([0-9]+)$"} 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, regex: "^db\\.change\\.allow\\.url\\.([0-9]+)$"} 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 ################################### ## 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 ################################### ## 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 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 ################################### # 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 # 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.1=displayExtension # 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.1=^[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.1=Group name '$attributeValue$' is invalid since it must contain only alpha-numerics or spaces ################################### ## 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 # 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.1=displayExtension # 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.1=^[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.1=Stem name '$attributeValue$' is invalid since it must contain only alpha-numerics or spaces ################################### ## 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 # Attach a regex validator by field name. This is the attribute name # {valueType: "string", required: true, regex: "^attributeDef\\.attribute\\.validator\\.attributeName\\.([0-9]+)$"} #attributeDef.attribute.validator.attributeName.1=displayExtension # 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.1=^[a-zA-Z0-9 ]+$ # Attach a regex validator by attribute name. This is the veto message if an attributeDef create has an invalid attribute # {valueType: "string", required: true, regex: "^attributeDef\\.attribute\\.validator\\.vetoMessage\\.([0-9]+)$"} #attributeDef.attribute.validator.vetoMessage.1=AttributeDef name '$attributeValue$' is invalid since it must contain only alpha-numerics or spaces ################################### ## 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 # Attach a regex validator by attribute name. This is the attribute name # {valueType: "string", required: true, regex: "^attributeDefName\\.attribute\\.validator\\.attributeName\\.([0-9]+)$"} #attributeDefName.attribute.validator.attributeName.1=displayExtension # 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.1=^[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.1=AttributeDefName name '$attributeValue$' is invalid since it must contain only alpha-numerics or spaces ##################################### ## 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 ##################################### ## 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: # axion, cloudscape, db2, db2v8, derby, firebird, hsqldb, interbase, maxdb, mckoi, # mssql, mysql, mysql5, oracle, oracle10, oracle9, postgresql, sapdb, sybase, sybasease15, # # {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 = localhost #leave blank if unauthenticated # {valueType: "string"} #mail.smtp.user = #leave blank if unauthenticated # {valueType: "password", sensitive: true} #mail.smtp.pass = #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"} mail.transport.protocol = smtp # in the java mail settings if "smtp" or whatever the protocol is should be in the property names # {valueType: "boolean"} mail.use.protocol.in.property.names = true # 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: noreply@school.edu # {valueType: "string"} #mail.from.address = #this is the subject prefix of emails, which will help differentiate prod vs test vs dev etc. eg: TEST: # {valueType: "string"} #mail.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: a@b.c # {valueType: "string"} #mail.sendAllMessagesHere = #when running junit tests, this is the address that will be used. eg: a@b.c # {valueType: "string"} #mail.test.address = # if debug info from java mail should be printed # {valueType: "boolean"} mail.debug = false # if this smtp connector is enabled # {valueType: "boolean", defaultValue: "true"} #mail.enabled = # generally do no change this # {valueType: "string"} grouperEmailContentType = text/plain; charset=utf-8 ##################################### ## 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 # min idIndex for groups # {valueType: "integer", required: true} grouper.tableIndex.group.minIndex = 10000 # min idIndex for folders # {valueType: "integer", required: true} grouper.tableIndex.stem.minIndex = 10000 # min idIndex for attributeDefs # {valueType: "integer", required: true} grouper.tableIndex.attributeDef.minIndex = 10000 # min idIndex for attributeDefNames # {valueType: "integer", required: true} grouper.tableIndex.attributeDefName.minIndex = 10000 # 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 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 ##################################### ## 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 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 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 ##################################### ## 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 = # if the attribute loader attributes, and other attributes should be autoconfigured (created, etc) # {valueType: "boolean", required: true} grouper.attribute.loader.autoconfigure = true # allow privileges for attributes be assigned to every entity # note: there is also: grouper.permissions.limits.builtin.createAs.public # {valueType: "boolean", required: true} grouper.attribute.allow.everyEntity.privileges = true ##################################### ## 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 = true # 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 # {valueType: "string", regex: "^grouper\\.permissions\\.limits\\.logic\\.([^.]+)\\.limitName$"} # grouper.permissions.limits.logic.someName.limitName = # 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", regex: "^externalSubjects\\.sortAttribute([0-9]+)\\.el$"} externalSubjects.sortAttribute1.el = ${subjectUtils.defaultIfBlank(subject.getAttributeValue("identifier"), "")} # external subject sort attribute, increment the index to add multiple # {valueType: "string", regex: "^externalSubjects\\.sortAttribute([0-9]+)\\.el$"} 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 # quartz cron where subjects are recalculated if necessary (empty means dont run), e.g. everyday at 3am # {valueType: "string"} externalSubjects.calc.fields.cron = 0 0 3 * * ? # 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. username@school.edu # {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 # quartz cron to schedule the pull or push (incremental is automatic as events happen) (e.g. 5am daily) # {valueType: "string", regex: "^syncAnotherGrouper\\.([^.]+)\\.cron$"} #syncAnotherGrouper.testGroup0.cron = 0 0 5 * * ? # 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 ###################################### ## 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 ######################## # Will add the LDAPProvisioningExclude group type to groups that shouldnt be provisioned # {valueType: "string", regex: "^LDAPProvisioningHook\\.exclude\\.regex\\.([0-9]+)$"} #LDAPProvisioningHook.exclude.regex.0=.*_excludes$ # Will add the LDAPProvisioningExclude group type to groups that shouldnt be provisioned # {valueType: "string", regex: "^LDAPProvisioningHook\\.exclude\\.regex\\.([0-9]+)$"} #LDAPProvisioningHook.exclude.regex.1=.*_includes$ # Will add the LDAPProvisioningExclude group type to groups that shouldnt be provisioned # {valueType: "string", regex: "^LDAPProvisioningHook\\.exclude\\.regex\\.([0-9]+)$"} #LDAPProvisioningHook.exclude.regex.2=.*_systemOfRecord$ # Will add the LDAPProvisioningExclude group type to groups that shouldnt be provisioned # {valueType: "string", regex: "^LDAPProvisioningHook\\.exclude\\.regex\\.([0-9]+)$"} #LDAPProvisioningHook.exclude.regex.3=.*_systemOfRecordAndIncludes$ ######################################### ## 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. false or 0 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, regex: "^ws\\.diagnostic\\.ignore\\.([a-zA-Z0-9._-]+)$"} 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, regex: "^ws\\.diagnostic\\.ignore\\.([a-zA-Z0-9._-]+)$"} 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, regex: "^ws\\.diagnostic\\.ignore\\.([a-zA-Z0-9._-]+)$"} ws.diagnostic.ignore.loader_CHANGE_LOG_changeLogTempToChangeLog = 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 # 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.students.groupName = community:students # min group size of known groups # {valueType: "integer", required: true, regex: "^ws\\.diagnostic\\.checkGroupSize\\.([a-zA-Z0-9._-]+)\\.minSize$"} #ws.diagnostic.checkGroupSize.students.minSize = 18000 #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 # if set, will save the instance file containing the server uuid into this directory. Otherwise, will use the grouper log directory # {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: More 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. # 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. # {valueType: "string", regex: "^grouper\\.membership\\.customComposite\\.uiKey\\.\\d+$"} #grouper.membership.customComposite.uiKey.0 = customCompositeMinusEmployees # {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 # {valueType: "string", regex: "^grouper\\.membership\\.customComposite\\.uiKey\\.\\d+$"} #grouper.membership.customComposite.uiKey.1 = customCompositeIntersectIt # {valueType: "string", regex: "^grouper\\.membership\\.customComposite\\.compositeType\\.\\d+$"} #grouper.membership.customComposite.compositeType.1 = intersection # {valueType: "group", regex: "^grouper\\.membership\\.customComposite\\.groupName\\.\\d+$"} #grouper.membership.customComposite.groupName.1 = org:centralIt:staff:itStaff ################################## ## 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 # 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 # 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 # 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 # 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 start group color # {valueType: "string"} visualization.module.dot.start_group.color = sandybrown # dot start group style # {valueType: "string"} visualization.module.dot.start_group.style = filled # dot start group fontcolor # {valueType: "string"} visualization.module.dot.start_group.fontcolor = white # dot start group border # {valueType: "string"} visualization.module.dot.start_group.border = 1 # dot loader group color # {valueType: "string"} visualization.module.dot.loader_group.color = forestgreen # dot loader group style # {valueType: "string"} visualization.module.dot.loader_group.style = filled # dot loader group fontcolor # {valueType: "string"} visualization.module.dot.loader_group.fontcolor = white # dot intersect group color # {valueType: "string"} visualization.module.dot.intersect_group.color = blue # 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 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 right color # {valueType: "string"} visualization.module.dot.edge_complement_right.color = salmon # dot edge intersect left color # {valueType: "string"} visualization.module.dot.edge_intersect_left.color = blue # dot edge intersect right color # {valueType: "string"} visualization.module.dot.edge_intersect_right.color = blue # 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 ################################## ## 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 = # 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 = ################################## ## 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 ############################################ ## 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", required: true, regex: "^grouper\\.googleConnector\\.([^.]+)\\.serviceAccountPKCS12FilePath$"} # grouper.googleConnector.myGoogle.serviceAccountPKCS12FilePath = # If not reading from a file, this is the secret that is in the file # {valueType: "password", required: true, regex: "^grouper\\.googleConnector\\.([^.]+)\\.serviceAccountPKCS12Pass$"} # grouper.googleConnector.myGoogle.serviceAccountPKCS12Pass = # 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 = # 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", required: true, regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.tlsVersion$"} # grouper.rabbitMqConnector.myConnector.tlsVersion = # path to trust store file # {valueType: "string", required: true, regex: "^grouper\\.rabbitMqConnector\\.([^.]+)\\.pathToTrustStore$"} # grouper.rabbitMqConnector.myConnector.pathToTrustStore = # trust passphrase # {valueType: "password", required: true, 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 = ############################################ ## Remedy connector ############################################ # url # {valueType: "string", required: true, regex: "^grouper\\.remedyConnector\\.([^.]+)\\.url$"} # grouper.remedyConnector.myConnector.url = # 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 = # 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 = ############################################ ## 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 ############################################ ## Gsh templates configuration ############################################ # enabled or disabled # {valueType: "boolean", defaultValue: "true", order: 1000 } # grouperGshTemplate.testGshTemplate.enabled = # show on folders # {valueType: "boolean", defaultValue: "false", order: 6000 } # grouperGshTemplate.testGshTemplate.showOnFolders = # folder show type # {valueType: "string", required: true, order: 7000, showEl: "${showOnFolders}", formElement: "dropdown", optionValues: ["certainFolder", "allFolders"] } # grouperGshTemplate.testGshTemplate.folderShowType = # folder uuid to show # {valueType: "string", required: true, order: 8000, showEl: "${folderShowType == 'certainFolder'}"} # grouperGshTemplate.testGshTemplate.folderUuidToShow = # folder show on descendants # {valueType: "string", required: true, order: 9000, showEl: "${folderShowType == 'certainFolder'}", formElement: "dropdown", optionValues: ["certainFolder", "oneChildLevel", "certainFolderAndOneChildLevel", "descendants", "certainFolderAndDescendants"]} # grouperGshTemplate.testGshTemplate.folderShowOnDescendants = # 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} # 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", order: 18000, showEl: "${externalizedText}"} # grouperGshTemplate.testGshTemplate.templateDescriptionExternalizedTextKey = # template description # {valueType: "string", order: 18500, showEl: "${!externalizedText}", formElement: "textarea"} # grouperGshTemplate.testGshTemplate.templateDescription = # should show in More actions # {valueType: "boolean", defaultValue: "false", order: 18550 } # 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 } # grouperGshTemplate.testGshTemplate.gshLightweight = # run gsh script in a transaction # {valueType: "boolean", defaultValue: "true", order: 18700 } # grouperGshTemplate.testGshTemplate.runGshInTransaction = # use individual audits? # {valueType: "boolean", defaultValue: "true", order: 18800 } # grouperGshTemplate.testGshTemplate.useIndividualAudits = # 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", "dropdown"]} # 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", "json", "javaclass"]} # 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 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$.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"] } # grouperGshTemplate.testGshTemplate.numberOfTests = # delete side effects if exist gsh # {valueType: "string", order: 35000, formElement: "textarea", showEl: "${numberOfTests > $i$}", repeatGroup: "test", repeatCount: 20} # grouperGshTemplate.testGshTemplate.test.$i$.deleteSideEffectsIfExistGsh = # set up gsh # {valueType: "string", order: 36000, formElement: "textarea", showEl: "${numberOfTests > $i$}", repeatGroup: "test", repeatCount: 20} # grouperGshTemplate.testGshTemplate.test.$i$.setupGsh = # test gsh # {valueType: "string", order: 37000, formElement: "textarea", required: true, showEl: "${numberOfTests > $i$}", repeatGroup: "test", repeatCount: 20} # grouperGshTemplate.testGshTemplate.test.$i$.testGsh = # verify gsh # {valueType: "string", order: 37000, formElement: "textarea", showEl: "${numberOfTests > $i$}", repeatGroup: "test", repeatCount: 20} # grouperGshTemplate.testGshTemplate.test.$i$.verifyGsh =