# # 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 client configuration # $Id: grouper.client.base.properties,v 1.24 2009-12-30 04:23:02 mchyzer Exp $ # # The grouper client uses Grouper Configuration Overlays (documented on wiki) # By default the configuration is read from grouper.client.base.properties # (which should not be edited), and the grouper.client.properties overlays # the base settings. See the grouper.client.base.properties for the possible # settings that can be applied to the grouper.client.properties ######################################## ## Web service Connection settings ######################################## # url of web service, should include everything up to the first resource to access # e.g. http://groups.school.edu:8090/grouper-ws/servicesRest # e.g. https://groups.school.edu/grouper-ws/servicesRest # {valueType: "string"} grouperClient.webService.url.elConfig = ${elUtils.processEnvVarOrFile('GROUPER_CLIENT_WS_URL')} # kerberos principal used to connect to web service # {valueType: "string"} grouperClient.webService.login.elConfig = ${elUtils.processEnvVarOrFile('GROUPER_CLIENT_WS_LOGIN')} # password for shared secret authentication to web service # or you can put a filename with an encrypted password # {valueType: "password", sensitive: true} grouperClient.webService.password.elConfig = ${elUtils.processEnvVarOrFile('GROUPER_CLIENT_WS_PASSWORD')} ######################################## ## LDAP connection settings ######################################## # url of directory, including the base DN (distinguished name) # e.g. ldap://server.school.edu/dc=school,dc=edu # e.g. ldaps://server.school.edu/dc=school,dc=edu # {valueType: "string"} grouperClient.ldap.url.elConfig = ${elUtils.processEnvVarOrFile('GROUPER_CLIENT_LDAP_URL')} # kerberos principal used to connect to ldap # {valueType: "string"} grouperClient.ldap.login.elConfig = ${elUtils.processEnvVarOrFile('GROUPER_CLIENT_LDAP_LOGIN')} # password for shared secret authentication to ldap # or you can put a filename with an encrypted password # {valueType: "password", sensitive: true} grouperClient.ldap.password.elConfig = ${elUtils.processEnvVarOrFile('GROUPER_CLIENT_LDAP_PASSWORD')} ######################################## ## Config chaining hierarchy ######################################## # 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.client.example.properties, file:c:/something/myconfig.properties # {valueType: "string", required: true, multiple: true} grouperClient.config.hierarchy = classpath:grouper.client.base.properties, classpath:grouper.client.properties, database:grouper # seconds between checking to see if the config files are updated # {valueType: "integer", required: true} grouperClient.config.secondsBetweenUpdateChecks = 600 # connection provider for configuration, the only real option here at this point is edu.internet2.middleware.grouper.subj.GrouperJdbcConnectionProvider # which will pull configuration from grouper's default database connection pool # {valueType: "class", required: true, mustImplementInterface: "edu.internet2.middleware.grouperClient.jdbc.GcJdbcConnectionProvider"} grouperClient.config.databaseConnectionProvider = edu.internet2.middleware.grouper.subj.GrouperJdbcConnectionProvider ######################################## ## Encryption configuration ######################################## # Put a random alphanumeric string (Case sensitive) for the password encryption. e.g. fh43IRJ4Nf5jn4Qp9k2 # or put a filename where the random alphanumeric string is. e.g. c:/whatever/key.txt # use encrypt.key.elConfig instead if the config has an expression language scriptlet encrypt.key = # set this to true if you have slashes in your passwords and dont want to look in external files or unencrypt encrypt.disableExternalFileLookup = false ######################################## ## Misc settings ######################################## # path of a writable directory where files can be created or stored # for example, cache of discovery configuration, or failover state # dot is the current directory... note, this directory must exist # or it will be created (attempted) # if this is blank, none of these features will be used, and # no files will be saved # {valueType: "string"} grouperClient.cacheDirectory = . ######################################## ## Logging ######################################## # For java.util.logging, only for the grouperClient package (not below) # from java java.util.logging.Level class: ALL, CONFIG, FINE, FINER, FINEST, OFF, SEVERE, WARNING # {valueType: "string"} grouperClient.logging.grouperClientOnly.logLevel = WARNING # If you are not using log4j (will use java.util.logging, you can turn logging on which will go to stderr # (if no file specified below). This is default log level # from java java.util.logging.Level class: ALL, CONFIG, FINE, FINER, FINEST, OFF, SEVERE, WARNING # {valueType: "string"} grouperClient.logging.logLevel = WARNING # If you dont want the logging to go to stderr, then put a log file location here: e.g. f:/temp/grouperClient.log # {valueType: "string"} grouperClient.logging.logFile = # if you want ws requests and responses being logged to files, put the directory here. # The grouper client will create subdirs # {valueType: "string"} grouperClient.logging.webService.documentDir = # try to indent the xml. If this fails for some reason, or you want the raw xml, # set to false # {valueType: "boolean", required: true} grouperClient.logging.webService.indent = true # if the masked password should be logged (if false, dont log anything about password) # the masked password will show how many chars the password is (helpful for diagnosing # password encryption issues) # {valueType: "boolean", required: true} grouperClient.logging.logMaskedPassword = false # this is verbose, but might be needed # {valueType: "boolean", required: true} grouperClient.logging.printDebugLogWhenDebugFlag = false ######################################## ## Service discovery settings ######################################## # number of minutes to remember that a connection had errors # {valueType: "integer"} grouperClient.minutesToKeepErrors = 2 # if you are using a discovery service, but a discovery properties # at a URL (preferably SSL with valid certificate) # you should have multiple discovery URLs hosted at independent locations # to add more, increment the integer # {valueType: "string", regex: "^grouperClient\\.urlOfDiscovery\\.([0-9]+)$"} grouperClient.urlOfDiscovery.0 = # if you are using a discovery service, but a discovery properties # at a URL (preferably SSL with valid certificate) # you should have multiple discovery URLs hosted at independent locations # to add more, increment the integer # {valueType: "string", regex: "^grouperClient\\.urlOfDiscovery\\.([0-9]+)$"} grouperClient.urlOfDiscovery.1 = # if your app has a slow startup time, and the initial connections are timing out # esp if you arent just using the command line client (e.g. if using it as a jar), # then add more time here # {valueType: "integer", required: true} grouperClient.secondsForClassesToLoad = 20 # this will save the failover state to a file so if the JVM is stopped, it # will be there when it starts again. # Set to 0 to store on every use (recommended if used command line) # or set to -1 to not store or read ever # grouperClient.cacheDirectory must be set # {valueType: "integer", required: true} grouperClient.saveFailoverStateEverySeconds = 60 # if the failover client should use threads. If it doesnt then you cant detect timeouts # {valueType: "boolean", required: true} grouperClient.failoverClientUseThreads = true # this will cache the discovery properties in memory or on disk # if you want to cache the discovery properties locally, put a directory here: # this is recommended especially if you are using the grouper client as a command # line application and the process is constantly restarting # note, this will be used for a failsafe cache if all discovery servers are unavailable # grouperClient.cacheDirectory must be set # set to 0 or -1 to not cache # {valueType: "integer", required: true} grouperClient.cacheDiscoveryPropertiesForSeconds = 120 # this is the path in the discovery server there the grouper.client.discovery.properties is # {valueType: "string"} grouperClient.discoveryGrouperClientPropertiesDirectory = ######################################## ## Service discovery settings in institution ## Below here are default values and override values for the discovery ## properties at your institution. Note: if the override keys are there ## with no value then it will blank out the discovery service value ######################################## # default urls of directory, including the base DN (distinguished name) # add more properties and increment the integer (.1, .2, etc) # e.g. ldap://server.school.edu/dc=school,dc=edu # e.g. ldaps://server.school.edu/dc=school,dc=edu # {valueType: "string", regex: "^grouperClient\\.discoveryDefault\\.ldap\\.([0-9]+)\\.url$"} grouperClient.discoveryDefault.ldap.0.url = # default active/active or active/standby # active/active will pick a server randomly, # and will stick with it for as long as the affinity is set # active/standby will always use the first connection # if no errors, then try the second one etc. # if a connection has more errors and has a higher priority, # then it will not be tried again until the # takeConnectionOutOfPoolOnErrorForSeconds timeout # passes # {valueType: "string"} grouperClient.discoveryDefault.ldap.loadBalancing = active/active # if we are active/active, then the same connection will # be used for a certain number of seconds. If this is -1, then # always keep the same server (unless errors) # {valueType: "integer", required: true} grouperClient.discoveryDefault.ldap.affinitySeconds = 28800 # if a connection has more errors than another, it will not be # used until this error timeout passes (unless the other is throwing errors # too) # {valueType: "integer", required: true} grouperClient.discoveryDefault.ldap.lowerConnectionPriorityOnErrorForMinutes = 3 # when a connection is attempted, this is the timeout that it will use before trying # another connection # {valueType: "integer", required: true} grouperClient.discoveryDefault.ldap.timeoutSeconds = 30 # after all connections have been attempted, it will wait for this long # to see if any finish # {valueType: "integer", required: true} grouperClient.discoveryDefault.ldap.extraTimeoutSeconds = 15 # urls of web service, should include everything up to the first resource to access # this is for read or write operations # add more properties and increment the integer (.1, .2, etc) # e.g. http://groups.school.edu:8090/grouper-ws/servicesRest # e.g. https://groups.school.edu/grouper-ws/servicesRest # {valueType: "string", regex: "^grouperClient\\.discoveryDefault\\.webService\\.readWrite\\.([0-9]+)\\.url$"} grouperClient.discoveryDefault.webService.readWrite.0.url = # url of web service, should include everything up to the first resource to access # this is for only read operations # add more properties and increment the integer (.1, .2, etc) # e.g. http://groups.school.edu:8090/grouper-ws/servicesRest # e.g. https://groups.school.edu/grouper-ws/servicesRest # {valueType: "string", regex: "^grouperClient\\.discoveryDefault\\.webService\\.readOnly\\.([0-9]+)\\.url$"} grouperClient.discoveryDefault.webService.readOnly.0.url = # active/active or active/standby # active/active will pick a server randomly, # and will stick with it for as long as the affinity is set # active/standby will always use the first connection # if no errors, then try the second one etc. # if a connection has more errors and has a higher priority, # then it will not be tried again until the # takeConnectionOutOfPoolOnErrorForSeconds timeout # passes # {valueType: "string"} grouperClient.discoveryDefault.webService.loadBalancing = active/active # if you want to always try read/write before readOnly (i.e. if you are # worried about if you make a write and read right after each other) # {valueType: "boolean", required: true} grouperClient.discoveryDefault.webService.preferReadWrite = true # if we are active/active, then the same connection will # be used for a certain number of seconds. If this is -1, then # always keep the same server (unless errors) # {valueType: "integer", required: true} grouperClient.discoveryDefault.webService.affinitySeconds = 28800 # if a connection has more errors than another, it will not be # used until this error timeout passes (unless the other is throwing errors # too) # {valueType: "integer", required: true} grouperClient.discoveryDefault.webService.lowerConnectionPriorityOnErrorForMinutes = 3 # when a connection is attempted, this is the timeout that it will use before trying # another connection # {valueType: "integer", required: true} grouperClient.discoveryDefault.webService.timeoutSeconds = 60 # after all connections have been attempted, it will wait for this long # to see if any finish # {valueType: "integer", required: true} grouperClient.discoveryDefault.webService.extraTimeoutSeconds = 30 ####################################### ## Advanced settings - output templates ####################################### # add member output # {valueType: "string", required: true} webService.addMember.output = Index ${index}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsSubject.id}$newline$ # get members output # {valueType: "string", required: true} webService.getMembers.output = GroupIndex ${groupIndex}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: group: ${wsGroup.name}: subjectIndex: ${subjectIndex}: ${wsSubject.id}$newline$ # delete member output # {valueType: "string", required: true} webService.deleteMember.output = Index ${index}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsSubject.id}$newline$ # has member output # {valueType: "string", required: true} webService.hasMember.output = Index ${index}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsSubject.id}: ${hasMember}$newline$ # get grouper output # {valueType: "string", required: true} webService.getGroups.output = SubjectIndex ${subjectIndex}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: subject: ${wsSubject.id}: groupIndex: ${groupIndex}: ${wsGroup.name}$newline$ # group save output # {valueType: "string", required: true} webService.groupSave.output = Success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsGroup.name}$newline$ # external subject save output # {valueType: "string", required: true} webService.externalSubjectSave.output = Success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: identifier: ${wsExternalSubject.identifier}: name: ${wsExternalSubject.name}$newline$ # stem save output # {valueType: "string", required: true} webService.stemSave.output = Success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsStem.name}$newline$ # group delete output # {valueType: "string", required: true} webService.groupDelete.output = Index ${index}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsGroup.name}$newline$ # external subject delete # {valueType: "string", required: true} webService.externalSubjectDelete.output = Index ${index}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: identifier: ${wsExternalSubject.identifier}: name: ${wsExternalSubject.name}$newline$ # stem delete # {valueType: "string", required: true} webService.stemDelete.output = Index ${index}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsStem.name}$newline$ # get grouper privileges lite output # {valueType: "string", required: true} webService.getGrouperPrivilegesLite.output = Index ${index}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${objectType}: ${objectName}: subject: ${wsSubject.id}: ${wsGrouperPrivilegeResult.privilegeType}: ${wsGrouperPrivilegeResult.privilegeName}$newline$ # assign grouper privileges output # {valueType: "string", required: true} webService.assignGrouperPrivileges.output = Index: ${index}, success: ${resultMetadata.success}, code: ${resultMetadata.resultCode}, ${objectType}: ${objectName}, subject: ${wsSubject.id}, ${wsAssignGrouperPrivilegesResult.privilegeType}: ${wsAssignGrouperPrivilegesResult.privilegeName}$newline$ # assign grouper privs lite output # {valueType: "string", required: true} webService.assignGrouperPrivilegesLite.output = Success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${objectType}: ${objectName}: subject: ${wsSubject.id}: ${wsAssignGrouperPrivilegesLiteResult.privilegeType}: ${wsAssignGrouperPrivilegesLiteResult.privilegeName}$newline$ # find groups output # {valueType: "string", required: true} webService.findGroups.output = Index ${index}: name: ${wsGroup.name}, displayName: ${wsGroup.displayName}$newline$ # find external subjects output # {valueType: "string", required: true} webService.findExternalSubjects.output = Index ${index}: identifier: ${wsExternalSubject.identifier}: name: ${wsExternalSubject.name}$newline$ # find stems output # {valueType: "string", required: true} webService.findStems.output = Index ${index}: name: ${wsStem.name}, displayName: ${wsStem.displayName}$newline$ # memberChangeSubject output # {valueType: "string", required: true} webService.memberChangeSubject.output = Success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: oldSubject: ${wsSubjectOld.id}, newSubject: ${wsSubjectNew.id}$newline$ # output # {valueType: "string", required: true} webService.getMemberships.output = Index: ${index}: ${type}: ${ownerName}, subject: ${wsSubject.id}, list: ${wsMembership.listName}, type: ${wsMembership.membershipType}, enabled: ${wsMembership.enabled}$newline$ # getMemberships output # {valueType: "string", required: true} webService.getSubjects.output = Index: ${index}: success: ${success}, code: ${wsSubject.resultCode}, subject: ${wsSubject.id}$newline$ # getAttributeAssignments output # {valueType: "string", required: true} webService.getAttributeAssignments.output = Index: ${index}: attributeAssignType: ${wsAttributeAssign.attributeAssignType}, owner: ${ownerName}, attributeDefNameName: ${wsAttributeDefName.name}, action: ${wsAttributeAssign.attributeAssignActionName}, values: ${valuesString}, enabled: ${wsAttributeAssign.enabled}, id: ${wsAttributeAssign.id}$newline$ # getAttributeAssignActions output # {valueType: "string", required: true} webService.getAttributeAssignActions.output = Index: ${index}: nameOfAttributeDef: ${wsAttributeAssignActionTuple.nameOfAttributeDef}, action: ${wsAttributeAssignActionTuple.action}$newline$ # assignAttributes output # {valueType: "string", required: true} webService.assignAttributes.output = Index: ${index}: attributeAssignType: ${wsAttributeAssign.attributeAssignType}, owner: ${ownerName}, attributeDefNameName: ${wsAttributeDefName.name}, action: ${wsAttributeAssign.attributeAssignActionName}, values: ${valuesString}, enabled: ${wsAttributeAssign.enabled}, id: ${wsAttributeAssign.id}, changed: ${wsAssignAttributeResult.changed}, deleted: ${wsAssignAttributeResult.deleted}, valuesChanged: ${wsAssignAttributeResult.valuesChanged}$newline$ # assignAttributesBatch output # {valueType: "string", required: true} webService.assignAttributesBatch.output = Index: ${assignIndex}, itemIndex: ${assignItemIndex}: attributeAssignType: ${wsAttributeAssign.attributeAssignType}, owner: ${ownerName}, attributeDefNameName: ${wsAttributeDefName.name}, action: ${wsAttributeAssign.attributeAssignActionName}, values: ${valuesString}, enabled: ${wsAttributeAssign.enabled}, id: ${wsAttributeAssign.id}, changed: ${wsAssignAttributeBatchResult.changed}, deleted: ${wsAssignAttributeBatchResult.deleted}, valuesChanged: ${wsAssignAttributeBatchResult.valuesChanged}$newline$ # getPermissionAssignments output # {valueType: "string", required: true} webService.getPermissionAssignments.output = Index: ${index}: permissionType: ${wsPermissionAssign.permissionType}, role: ${wsPermissionAssign.roleName}, subject: ${wsPermissionAssign.sourceId} - ${wsPermissionAssign.subjectId}, attributeDefNameName: ${wsPermissionAssign.attributeDefNameName}, action: ${wsPermissionAssign.action}, allowedOverall: ${wsPermissionAssign.allowedOverall}, enabled: ${wsPermissionAssign.enabled}$newline$ # assignPermissions output # {valueType: "string", required: true} webService.assignPermissions.output = Index: ${index}: permissionType: ${permissionType}, owner: ${ownerName}, permissionDefNameName: ${wsAttributeDefName.name}, action: ${wsAttributeAssign.attributeAssignActionName}, disallowed: ${wsAttributeAssign.disallowed}, enabled: ${wsAttributeAssign.enabled}, attributeAssignId: ${wsAttributeAssign.id}, changed: ${wsAssignPermissionResult.changed}, deleted: ${wsAssignPermissionResult.deleted}$newline$ # assignAttributeDefNameInheritance output # {valueType: "string", required: true} webService.assignAttributeDefNameInheritance.output = Success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}, message: ${resultMetadata.resultMessage}$newline$ # attributeDefNameSave output # {valueType: "string", required: true} webService.attributeDefNameSave.output = Success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsAttributeDefName.name}$newline$ # attributeDefNameDelete output # {valueType: "string", required: true} webService.attributeDefNameDelete.output = Index ${index}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsAttributeDefName.name}$newline$ # findAttributeDefNames output # {valueType: "string", required: true} webService.findAttributeDefNames.output = Index ${index}: name: ${wsAttributeDefName.name}, displayName: ${wsAttributeDefName.displayName}$newline$ # assignAttributeDefActions output # {valueType: "string", required: true} webService.assignAttributeDefActions.output=Index ${index}: nameOfAttributeDef: ${nameOfAttributeDef}, action: ${actionWithOperation.action}, status: ${actionWithOperation.status}$newline$ # attributeDefSave output # {valueType: "string", required: true} webService.attributeDefSave.output = Success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsAttributeDef.name}$newline$ # attributeDefDelete output # {valueType: "string", required: true} webService.attributeDefDelete.output = Index ${index}: success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: ${wsAttributeDef.name}$newline$ # findAttributeDefs output # {valueType: "string", required: true} webService.findAttributeDefs.output = Index ${index}: name: ${wsAttributeDef.name}, description: ${wsAttributeDef.description}$newline$ # sendMessage output # {valueType: "string", required: true} webService.sendMessage.output = Success: ${resultMetadata.success}, queueOrTopicName: ${wsMessageResults.queueOrTopicName}, numberOfMessages: ${numberOfMessages}$newline$ # receiveMessage output # {valueType: "string", required: true} webService.receiveMessage.output =Index ${index}: success: ${resultMetadata.success}, queueOrTopicName: ${wsMessageResults.queueOrTopicName}, messageBody: ${wsMessage.messageBody} # acknowledgeMessage output # {valueType: "string", required: true} webService.acknowledgeMessage.output = Success: ${resultMetadata.success}, queueOrTopicName: ${wsMessageAcknowledgeResults.queueOrTopicName}, numberOfMessages: ${numberOfMessages}$newline$ # get audit entries output # {valueType: "string", required: true} webService.getAuditEntries.output = Success: ${resultMetadata.success}: code: ${resultMetadata.resultCode}: actionName: ${wsAuditEntry.actionName}: auditCategory: ${wsAuditEntry.auditCategory}$newline$ ####################################### ## Advanced settings - ldap queries ####################################### # optional ldap search scope can be specified. It can be # set to 'one', 'sub', or 'base'. If not specified or is blank # then it defaults to 'one' # e.g: # {valueType: "string", regex: "^ldapSearchAttribute\\.searchScope\\.([0-9]+)$"} #ldapSearchAttribute.searchScope.0 = sub # operation name # {valueType: "string", regex: "^ldapSearchAttribute\\.operationName\\.([0-9]+)$"} ldapSearchAttribute.operationName.0 = pennnameToPennid # ldap dn # {valueType: "string", regex: "^ldapSearchAttribute\\.ldapName\\.([0-9]+)$"} ldapSearchAttribute.ldapName.0 = ou=pennnames # attribute to match # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.matchingAttributes\\.([0-9]+)$"} ldapSearchAttribute.matchingAttributes.0 = pennname # label from input # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.matchingAttributeLabels\\.([0-9]+)$"} ldapSearchAttribute.matchingAttributeLabels.0 = pennnameToDecode # attribute to get back # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.returningAttributes\\.([0-9]+)$"} ldapSearchAttribute.returningAttributes.0 = pennid # template to display # {valueType: "string", regex: "^ldapSearchAttribute\\.outputTemplate\\.([0-9]+)$"} ldapSearchAttribute.outputTemplate.0 = pennid: ${pennid} # type of data # {valueType: "string", regex: "^ldapSearchAttribute\\.resultType\\.([0-9]+)$"} ldapSearchAttribute.resultType.0 = STRING # operation name # {valueType: "string", regex: "^ldapSearchAttribute\\.operationName\\.([0-9]+)$"} ldapSearchAttribute.operationName.1 = pennidToPennname # ldap dn # {valueType: "string", regex: "^ldapSearchAttribute\\.ldapName\\.([0-9]+)$"} ldapSearchAttribute.ldapName.1 = ou=pennnames # attribute to match # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.matchingAttributes\\.([0-9]+)$"} ldapSearchAttribute.matchingAttributes.1 = pennid # label from input # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.matchingAttributeLabels\\.([0-9]+)$"} ldapSearchAttribute.matchingAttributeLabels.1 = pennidToDecode # attribute to get back # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.returningAttributes\\.([0-9]+)$"} ldapSearchAttribute.returningAttributes.1 = pennname # template to display # {valueType: "string", regex: "^ldapSearchAttribute\\.outputTemplate\\.([0-9]+)$"} ldapSearchAttribute.outputTemplate.1 = pennname: ${pennname} # type of data # {valueType: "string", regex: "^ldapSearchAttribute\\.resultType\\.([0-9]+)$"} ldapSearchAttribute.resultType.1 = STRING # operation name # {valueType: "string", regex: "^ldapSearchAttribute\\.operationName\\.([0-9]+)$"} ldapSearchAttribute.operationName.2 = hasMemberLdap # ldap dn # {valueType: "string", regex: "^ldapSearchAttribute\\.ldapName\\.([0-9]+)$"} ldapSearchAttribute.ldapName.2 = ou=groups # attribute to match # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.matchingAttributes\\.([0-9]+)$"} ldapSearchAttribute.matchingAttributes.2 = cn, hasMember # label from input # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.matchingAttributeLabels\\.([0-9]+)$"} ldapSearchAttribute.matchingAttributeLabels.2 = groupName, pennnameToCheck # attribute to get back # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.returningAttributes\\.([0-9]+)$"} ldapSearchAttribute.returningAttributes.2 = cn # template to display # {valueType: "string", regex: "^ldapSearchAttribute\\.outputTemplate\\.([0-9]+)$"} ldapSearchAttribute.outputTemplate.2 = hasMember: ${resultBoolean} # type of data # {valueType: "string", regex: "^ldapSearchAttribute\\.resultType\\.([0-9]+)$"} ldapSearchAttribute.resultType.2 = BOOLEAN # operation name # {valueType: "string", regex: "^ldapSearchAttribute\\.operationName\\.([0-9]+)$"} ldapSearchAttribute.operationName.3 = getMembersLdap # ldap dn # {valueType: "string", regex: "^ldapSearchAttribute\\.ldapName\\.([0-9]+)$"} ldapSearchAttribute.ldapName.3 = ou=groups # attribute to match # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.matchingAttributes\\.([0-9]+)$"} ldapSearchAttribute.matchingAttributes.3 = cn # label from input # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.matchingAttributeLabels\\.([0-9]+)$"} ldapSearchAttribute.matchingAttributeLabels.3 = groupName # attribute to get back # {valueType: "string", multiple: true, regex: "^ldapSearchAttribute\\.returningAttributes\\.([0-9]+)$"} ldapSearchAttribute.returningAttributes.3 = hasMember # template to display # {valueType: "string", regex: "^ldapSearchAttribute\\.outputTemplate\\.([0-9]+)$"} ldapSearchAttribute.outputTemplate.3 = ${resultString}$newline$ # type of data # {valueType: "string", regex: "^ldapSearchAttribute\\.resultType\\.([0-9]+)$"} ldapSearchAttribute.resultType.3 = STRING_LIST ######################################## ## Advanced settings - Custom operations ## Implement the interface ClientOperation, put it in the jar ## Increment the int index for multiples (must be in order) ######################################## # custom operation name # {valueType: "string", regex: "^customOperation\\.name\\.([0-9]+)$"} #customOperation.name.0 = cosignLikeWebsec # custom class # {valueType: "class", mustImplementInterface: "edu.internet2.middleware.grouperClient.ClientOperation", regex: "^customOperation\\.name\\.([0-9]+)$"} #customOperation.class.0 = edu.upenn.isc.grouperClient.CosignLikeWebsecOperation ######################################## ## Advanced settings - authentication settings ######################################## # user prefix # {valueType: "string"} grouperClient.ldap.user.prefix = uid= # user suffix # {valueType: "string"} grouperClient.ldap.user.suffix = ,ou=entities,dc=upenn,dc=edu # config name for the ldap user name between prefix and suffix # {valueType: "string"} grouperClient.ldap.user.label = login # config name for the webService user name between prefix and suffix # {valueType: "string"} grouperClient.webService.user.label = login ######################################## ## Advanced settings - web service settings ######################################## # socket timeout # {valueType: "integer", required: true} grouperClient.webService.httpSocketTimeoutMillis = 90000 # connection manager timeout # {valueType: "integer", required: true} grouperClient.webService.httpConnectionManagerTimeoutMillis = 90000 # ignore extraneous xml fields from server (e.g. on server upgrade, when the client isnt upgraded) # if you dont ignore, and there is an extraneous field which is not omitted (below), then an exception # will be thrown # {valueType: "boolean", required: true} grouperClient.webService.ignoreExtraneousXmlFields = true # register fields to be ignored with xstream. this is useful if you are not # ignoring extraneous fields (above), but know that there are a few to be ignored # place them here with fully qualified classname dont property name, comma separated # e.g. edu.internet2.middleware.grouperClient.ws.beans.WsResponseMeta.millis, edu.internet2.middleware.grouperClient.ws.beans.WsResponseMeta.millis2 # {valueType: "string", multiple: true} grouper.webService.omitXmlProperties = ######################################## ## Advanced settings - misc ######################################## # if there are extra command line args, should we fail or just log? # {valueType: "boolean", required: true} grouperClient.failOnExtraCommandLineArgs = true # you can have aliases for subjectId and subjectIdentifer in command line args # (though subjectId will still be allowed, but you cant pass both) # if this value is pennIds, then e.g. for addMemberWs, you can use --pennIds=123,234 # instead of --subjectIds=123,345 # {valueType: "string", multiple: true} grouperClient.alias.subjectIds = # if this value is pennKeys, then e.g. for addMemberWs, you can use --pennKeys=abc,bcd # instead of --subjectIdentifiers=abc,bcd # {valueType: "string", multiple: true} grouperClient.alias.subjectIdentifiers = # if this value is pennId, then e.g. for getGrouperPrivilegesLite, you can use --pennId=123 # instead of --subjectId=123 # {valueType: "string"} grouperClient.alias.subjectId = # if this value is pennKey, then e.g. for getGrouperPrivilegesLite, you can use --pennKey=abc # instead of --subjectIdentifiers=abc # {valueType: "string"} grouperClient.alias.subjectIdentifier = # if this value is PennId, then e.g. for addMemberWs, you can use --actAsPennId=123 # instead of --actAsSubjectId=abc,bcd # {valueType: "string"} grouperClient.alias.SubjectId = # if this value is PennKey, then e.g. for addMemberWs, you can use --actAsPennKey=abc # instead of --actAsSubjectIdentifier=abc # {valueType: "string"} grouperClient.alias.SubjectIdentifier = # the encoding used to read config files # {valueType: "string"} grouperClient.config.encoding = UTF-8 # this should probably be changed to UTF-8 for international charsets... for US it can be: ISO-8859-1 # {valueType: "string"} grouperClient.default.fileEncoding = UTF-8 # to not require valid SSL, use: edu.internet2.middleware.grouperClient.ssl.EasySslSocketFactory # {valueType: "class", mustImplementInterface: "edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory"} grouperClient.https.customSocketFactory = # to not require valid SSL, use: edu.internet2.middleware.grouperClient.ssl.BlindSslSocketFactory # {valueType: "class", mustImplementInterface: "edu.internet2.middleware.grouperClientExt.org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory"} grouperClient.ldaps.customSocketFactory = ############################## ## Advanced settings - Kuali Identity settings ############################## # kuali source # {valueType: "string", regex: "^kuali\\.identity\\.source\\.([0-9]+)$"} kuali.identity.source.0 = jdbc # kuali name attribute # {valueType: "string", regex: "^kuali\\.identity\\.nameAttribute\\.([0-9]+)$"} kuali.identity.nameAttribute.0 = name # kuali identifier attribute # {valueType: "string", regex: "^kuali\\.identity\\.identifierAttribute\\.([0-9]+)$"} kuali.identity.identifierAttribute.0 = loginid # separate a sourceId from a subjectId or sourceId # {valueType: "string"} kuali.identity.sourceSeparator = :::: ######################################## ## Advanced settings - JDBC settings ######################################## # default database connection name. grouper is a variable that means the grouper database. put a different label here to have # a different default # {valueType: "string"} grouperClient.jdbc.defaultName = grouper # the part between jdbc. and the last . is the name of the connection, in this case "default" # e.g. mysql: com.mysql.jdbc.Driver # e.g. p6spy (log sql): com.p6spy.engine.spy.P6SpyDriver # for p6spy, put the underlying driver in spy.properties # e.g. oracle: oracle.jdbc.driver.OracleDriver # e.g. hsqldb: org.hsqldb.jdbcDriver # e.g. postgres: org.postgresql.Driver # e.g. mssql: com.microsoft.sqlserver.jdbc.SQLServerDriver # {valueType: "string", regex: "^grouperClient\\.jdbc\\.([^.]+)\\.driver$"} #grouperClient.jdbc.someLabel.driver = oracle.jdbc.driver.OracleDriver # e.g. mysql: jdbc:mysql://localhost:3306/grouper # e.g. p6spy (log sql): [use the URL that your DB requires] # e.g. oracle: jdbc:oracle:thin:@server.school.edu:1521:sid # e.g. hsqldb (a): jdbc:hsqldb:dist/run/grouper;create=true # e.g. hsqldb (b): jdbc:hsqldb:hsql://localhost:9001/grouper # e.g. postgres (a): jdbc:postgresql://localhost:5432/database # e.g. postgres (b): jdbc:postgresql://localhost:5432/database?currentSchema=mySchema # e.g. mssql: jdbc:sqlserver://localhost:3280 # {valueType: "string", regex: "^grouperClient\\.jdbc\\.([^.]+)\\.url$"} # grouperClient.jdbc.someLabel.url = jdbc:oracle:thin:@server.school.edu:1521:sid # user # {valueType: "string", regex: "^grouperClient\\.jdbc\\.([^.]+)\\.user$"} # grouperClient.jdbc.someLabel.user = some_schema # pass # {valueType: "password", sensitive: true, regex: "^grouperClient\\.jdbc\\.([^.]+)\\.pass$"} # grouperClient.jdbc.default.pass = abc123 ################################ ## Advanced settings - AWS settings ################################ # sqs settings # {valueType: "password", sensitive: true} grouperClient.awsAccessKey = ABC123 # sqs settings # {valueType: "password", sensitive: true} grouperClient.awsSecretKey = xyz789 # sqs url # {valueType: "string"} grouperClient.awsSqsQueueUrl = https://sqs.region.amazonaws.com/1234/queue_name ################################ ## Advanced settings - ESB settings ################################ # if you want to encrypt messages, set this to an implementation of edu.internet2.middleware.grouperClient.encryption.GcEncryptionInterface # {valueType: "class", mustImplementInterface: "edu.internet2.middleware.grouperClient.encryption.GcEncryptionInterface"} esb.consumer.encryptionImplementation = edu.internet2.middleware.grouperClient.encryption.GcSymmetricEncryptAesCbcPkcs5Padding # this is a key or could be encrypted in a file as well like other passwords # generate a key with: java -cp grouperClient.jar edu.internet2.middleware.grouperClient.encryption.GcGenerateKey # number these if there are multiple # {valueType: "password", sensitive: true} #esb.consumer.encryptionKey.0 = abc123 ################################ ## Advanced settings - XMPP client settings ## Note: you need the smack.jar in your classpath, see the grouper xmpp wiki for usage ## https://spaces.internet2.edu/display/Grouper/Grouper+XMPP+notifications+v1.6.0 ################################ # general xmpp configuration - host # {valueType: "string"} grouperClient.xmpp.server.host = jabber.school.edu # xmpp port # {valueType: "integer", required: true} grouperClient.xmpp.server.port = 5222 # xmpp user # {valueType: "string"} grouperClient.xmpp.user = username # note, pass can be in an external file with morphstring # {valueType: "password", sensitive: true} grouperClient.xmpp.pass = # xmpp resource # {valueType: "string"} grouperClient.xmpp.resource = grouperClient # note, you need the exact id and resource here or it wont match # {valueType: "string", multiple: true} grouperClient.xmpp.trustedMessagesFromJabberIds = user@school.edu/resource, user2@school.edu/resource2 # if true, then each quartz trigger name will be unique # do this for atlassian since it doesnt do quartz right, and wont delete or reuse old triggers # {valueType: "boolean"} grouperClient.xmpp.uniqueQuartzTriggerNames = false # if true, send this to smack, if we should debug. not sure if it does anything # {valueType: "boolean", required: true} grouperClient.xmpp.debuggerEnabled = false grouperClient.xmpp.job.myJobName.groupNames = test:xmppGroups:test1 # allow incrementals not in group list # {valueType: "boolean", required: true} grouperClient.xmpp.job.myJobName.allowIncrementalNotInGroupNamesList = false # handler class # {valueType: "class", mustImplementInterface: "edu.internet2.middleware.grouperClientExt.xmpp.GrouperClientXmppHandler"} grouperClient.xmpp.job.myJobName.handlerClass = edu.internet2.middleware.grouperClientExt.xmpp.GrouperClientXmppFileHandler # set this to reload_group or incremental if not reload on each event # {valueType: "string"} grouperClient.xmpp.job.myJobName.eventAction = incremental # how often a full refresh should occur regardless of events # {valueType: "string"} grouperClient.xmpp.job.myJobName.fullRefreshQuartzCronString = 0 0 5 * * ? # target file # {valueType: "string"} grouperClient.xmpp.job.myJobName.fileHandler.targetFile = c:/temp/targetFile.txt # file prefix # {valueType: "string"} grouperClient.xmpp.job.myJobName.fileHandler.filePrefix = c:/temp/filePrefix.txt # iterator el # {valueType: "string"} grouperClient.xmpp.job.myJobName.fileHandler.iteratorEl = ${subject.attribute['pennname']}$space$ # file suffix # {valueType: "string"} grouperClient.xmpp.job.myJobName.fileHandler.fileSuffix = c:/temp/fileSuffix.txt # subject attribute names # {valueType: "string", multiple: true} grouperClient.xmpp.job.myJobName.subjectAttributeNames = pennname # subjects wont notify in not in these sources, comma separated, or blank for all # {valueType: "string", multiple: true} grouperClient.xmpp.job.myJobName.requireSources = pennperson # subjects wont notify if they dont have a non blank value for these attributes, or blank for all # {valueType: "string", multiple: true} grouperClient.xmpp.job.myJobName.requireAttributes = pennname ################################ ## Advanced settings - Grouper Messaging System ################################ # name of messaging system which is the default # {valueType: "string"} grouper.messaging.default.name.of.messaging.system = grouperBuiltinMessaging # name of a messaging system. note, "grouperBuiltinMessaging" can be arbitrary # {valueType: "string", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.name$"} grouper.messaging.system.grouperBuiltinMessaging.name = grouperBuiltinMessaging # class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem # {valueType: "string", mustImplementInterface: "edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.class$"} grouper.messaging.system.grouperBuiltinMessaging.class = edu.internet2.middleware.grouper.messaging.GrouperBuiltinMessagingSystem # name of the rabbitMq messaging system # {valueType: "string", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.name$"} # grouper.messaging.system.rabbitmqSystem.name = rabbitmqSystem # class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem # {valueType: "string", mustImplementInterface: "edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.class$"} # grouper.messaging.system.rabbitmqSystem.class = edu.internet2.middleware.grouperMessagingRabbitmq.GrouperMessagingRabbitmqSystem # name of the aws messaging system # {valueType: "string", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.name$"} # grouper.messaging.system.awsMessaging.name = awsSystem # class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem # {valueType: "string", mustImplementInterface: "edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.class$"} # grouper.messaging.system.awsMessaging.class = edu.internet2.middleware.grouperMessagingAWS.GrouperMessagingSqsSystem # name of the activemq messaging system # {valueType: "string", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.name$"} # grouper.messaging.system.activeMqMessaging.name = activeMqMessaging # class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem # {valueType: "string", mustImplementInterface: "edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.class$"} # grouper.messaging.system.activeMqMessaging.class = edu.internet2.middleware.grouperMessagingActiveMQ.GrouperMessagingActiveMQSystem # name of a messaging system. note, "myAwsMessagingSystem" can be arbitrary # {valueType: "string", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.name$"} # grouper.messaging.system.myAwsMessagingSystem.name = aws # class that implements edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem # {valueType: "string", mustImplementInterface: "edu.internet2.middleware.grouperClient.messaging.GrouperMessagingSystem", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.class$"} # grouper.messaging.system.myAwsMessagingSystem.class = # default system name: settings to this messaging system, note, there is only one level of inheritance # {valueType: "string", regex: "^grouper\\.messaging\\.system\\.([^.]+)\\.defaultSystemName$"} # grouper.messaging.system.myAwsMessagingSystem.defaultSystemName = ################################ ## Sync database table settings ################################ # the grouping column is what is uniquely selected, and then batched through to get data, default across all sql jobs # {valueType: "integer"} # grouperClient.syncTableDefault.groupingSize = 10000 # size of jdbc batches, default across all sql jobs # {valueType: "integer"} # grouperClient.syncTableDefault.batchSize = 800 # number of bind vars in select, default across all sql jobs # {valueType: "integer"} # grouperClient.syncTableDefault.maxBindVarsInSelect = 900 # default database for all sql jobs for status tabls (e.g. grouper_sync*) # {valueType: "string"} # grouperClient.syncTableDefault.statusDatabase = grouper # the grouping column is what is uniquely selected, and then batched through to get data, default across all sql jobs # {valueType: "integer"} # grouperClient.syncTableDefault.groupingSize = 10000 # default switch from incremental to full if the number of incrementals is over this threshold # {valueType: "integer"} # grouperClient.syncTableDefault.switchFromIncrementalToFullIfOverRecords = 300000 # switch from incremental to full if the number of incrementals is over the threshold, this is full sync to switch to # fullSyncChangeFlag, fullSyncFull, fullSyncGroups # {valueType: "string"} # grouperClient.syncTableDefault.switchFromIncrementalToFullSubtype = fullSyncFull # switch from incremental to group (if theres a grouping col) if the number of incrementals for a certain group # {valueType: "integer"} # grouperClient.syncTableDefault.switchFromIncrementalToGroupIfOverRecordsInGroup = 50000 # switch from incremental to full if the number of groups (and records over threshold) is over this threshold # i.e. needs to be over 100 groups and over 300000 records # {valueType: "integer"} # grouperClient.syncTableDefault.switchFromIncrementalToFullIfOverGroupCount = 100 # grouper client or loader database key where copying data from # the 3rd part is the sync_id. in this case "personSource". Defaults to "grouper" # {valueType: "string"} #grouperClient.syncTable.personSource.databaseFrom = # table or view where copying data from, include the schema if needed # {valueType: "string"} #grouperClient.syncTable.personSource.tableFrom = # grouper client or loader database key where copying data to # {valueType: "string"} #grouperClient.syncTable.personSource.databaseTo = # grouper client or loader database key (readonly) if large queries should be performed against a different database # {valueType: "string"} #grouperClient.syncTable.personSource.databaseToReadonly = # table or view where copying data to, include the schema if needed # {valueType: "string"} #grouperClient.syncTable.personSource.tableTo = PERSON_SOURCE_TEMP # columns must match in from and to tables, you can specify columns or do all with an asterisk # {valueType: "string"} #grouperClient.syncTable.personSource.columns = * # if there is a primary key, list it, else list the composite keys. note, this doesnt # have to literally be the database prmiary key, just need to be a unique col(s) in table # {valueType: "string"} # grouperClient.syncTable.personSource.primaryKeyColumns = penn_id # if doing fullSyncChangeFlag (look for a col that says if the rows are equal, e.g. a timestamp or a checksum) # {valueType: "string"} # grouperClient.syncTable.personSource.changeFlagColumn = check_sum # the grouping column is what is uniquely selected, and then batched through to get data. Optional. # for groups this should be the group uuid # {valueType: "string"} # grouperClient.syncTable.personSource.groupingColumn = penn_id # the grouping column is what is uniquely selected, and then batched through to get data, defaults to global setting # {valueType: "integer"} # grouperClient.syncTable.personSource.groupingSize = 10000 # size of jdbc batches # {valueType: "integer"} # grouperClient.syncTable.personSource.batchSize = 800 # number of bind vars in select # {valueType: "integer"} # grouperClient.syncTable.personSource.maxBindVarsInSelect = 900 # switch from incremental to full if the number of incrementals is over this threshold # if this is less than 0, then it will not switch from incremental to full # {valueType: "integer"} # grouperClient.syncTable.personSource.switchFromIncrementalToFullIfOverRecords = 300000 # switch from incremental to full if the number of incrementals is over the threshold, this is full sync to switch to # fullSyncChangeFlag, fullSyncFull, fullSyncGroups # {valueType: "string"} # grouperClient.syncTable.personSource.switchFromIncrementalToFullSubtype = fullSyncFull # switch from incremental to group (if theres a grouping col) if the number of incrementals for a certain group # if this is less than 0, then it will not switch from incremental to group # {valueType: "integer"} # grouperClient.syncTable.personSource.switchFromIncrementalToGroupIfOverRecordsInGroup = 50000 # switch from incremental to full if the number of groups (and records over threshold) is over this threshold # i.e. needs to be over 100 groups and over 300000 records # {valueType: "integer"} # grouperClient.syncTable.personSource.switchFromIncrementalToFullIfOverGroupCount = 100 # if querying a real time table, this is the table, needs to have primary key columns. # each record will check the source and destination and see what to do # {valueType: "string"} # grouperClient.syncTable.personSource.incrementalPrimaryKeyTable = real_time_table # name of a column that has a sequence or last updated date. # must be in the incrementalPrimaryKeyTable if incremental primary key sync # {valueType: "string"} # grouperClient.syncTable.personSource.incrementalProgressColumn = last_updated # name of a column that has a sequence or last updated date. # must be in the main data table if incremental all columns # {valueType: "string"} # grouperClient.syncTable.personSource.incrementalAllColumnsColumn = last_updated # database where status table is. defaults to "grouper" # {valueType: "string"} # grouperClient.syncTable.personSource.statusDatabase = grouper # grouper client or loader database key where copying data from # the 3rd part is the sync_id. in this case "personSource". Defaults to "grouper" # {valueType: "string"} grouperClient.syncTable.recentMembershipsConf.databaseFrom = grouper # table or view where copying data from, include the schema if needed # {valueType: "string"} grouperClient.syncTable.recentMembershipsConf.tableFrom = grouper_recent_mships_conf_v # grouper client or loader database key where copying data to # {valueType: "string"} grouperClient.syncTable.recentMembershipsConf.databaseTo = grouper # table or view where copying data to, include the schema if needed # {valueType: "string"} grouperClient.syncTable.recentMembershipsConf.tableTo = grouper_recent_mships_conf # columns must match in from and to tables, you can specify columns or do all with an asterisk # {valueType: "string"} grouperClient.syncTable.recentMembershipsConf.columns = * # if there is a primary key, list it, else list the composite keys. note, this doesnt # have to literally be the database prmiary key, just need to be a unique col(s) in table # {valueType: "string"} grouperClient.syncTable.recentMembershipsConf.primaryKeyColumns = group_uuid_to ############################################ ## Box connector ############################################ # private key contents, can use multiple 0, 1, 2 # {valueType: "password", required: true, regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.privateKeyContents_[0-9]+$"} # grouperClient.boxConnector.myConnector.privateKeyContents_0 = # if not putting pem in database, you can put it on the filesystem, list the filename # {valueType: "string", required: true, regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.privateKeyFileName$"} # grouperClient.boxConnector.myConnector.privateKeyFileName = # private key password # {valueType: "string", required: true, regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.privateKeyPass$"} # grouperClient.boxConnector.myConnector.privateKeyPass = # public key id # {valueType: "string", required: true, regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.publicKeyId$"} # grouperClient.boxConnector.myConnector.publicKeyId = # enterprise ID # {valueType: "string", required: true, regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.enterpriseId$"} # grouperClient.boxConnector.myConnector.enterpriseId = # client ID # {valueType: "string", required: true, regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.clientId$"} # grouperClient.boxConnector.myConnector.clientId = # client secret # {valueType: "password", required: true, regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.clientSecret$"} # grouperClient.boxConnector.myConnector.clientSecret = # proxy host # {valueType: "string", required: true, regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.proxyHost$"} # grouperClient.boxConnector.myConnector.proxyHost = # proxy port # {valueType: "integer", required: true, regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.proxyPort$"} # grouperClient.boxConnector.myConnector.proxyPort = # if this box connector is enabled # {valueType: "boolean", regex: "^grouperClient\\.boxConnector\\.([^.]+)\\.enabled$", defaultValue: "true"} # grouperClient.boxConnector.myConnector.enabled =