# # 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. # # # Subject configuration # $Id: subject.base.properties,v 1.24 2009-12-30 04:23:02 mchyzer Exp $ # ######################################## ## Config chaining hierarchy ## The subject proprties uses Grouper Configuration Overlays (documented on wiki) ## By default the configuration is read from subject.base.properties ## (which should not be edited), and the subject.properties overlays ## the base settings. See the subject.base.properties for the possible ## settings that can be applied to the subject.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:subject.example.properties, file:c:/something/myconfig.properties # {valueType: "string", required: true, multiple: true} subject.config.hierarchy = classpath:subject.base.properties, classpath:subject.properties, database:grouper # seconds between checking to see if the config files are updated # {valueType: "integer", required: true} subject.config.secondsBetweenUpdateChecks = 60 ######################################## ## Subject caching ######################################## # There are various caches for subjects. # This cache will alleviate calls to databases and ldaps. # {valueType: "string"} subject.cache.enable = true # implementation of a serializer for the cache # {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouper.subj.cache.SubjectSourceSerializer"} subject.cache.serializer = edu.internet2.middleware.grouper.subj.cache.SubjectSourceSerializerFile # if we are serializing to a file, enter a directory, else it is not used # {valueType: "string"} subject.cache.serializer.directory = # max subjects in cache # {valueType: "integer"} subject.cache.maxElementsInMemory = 200000 # if the cache should auto refresh in background # {valueType: "boolean"} subject.cache.autoRefresh = true # Sets the time to live cycle for an element before it expires or gets refreshed. Default 1 hour # {valueType: "integer", required: true} subject.cache.timeToLiveSeconds = 3600 # Resolve subjects again if necessary, after this percent of time to live # {valueType: "integer", required: true} subject.cache.timeToLivePercentageToResolveSubjectsIfNecessary = 90 # Sets the time to live cycle for an element which is not found before it expires or gets refreshed. Default 3 minute # {valueType: "integer", required: true} subject.cache.timeToLiveNotFoundSeconds = 180 # Resolve subjects again if necessary, after this percent of time to live for not found subjects. # note if the time to live for not found subjects is low, this has to be low too so there is time to resolve... # {valueType: "integer", required: true} subject.cache.timeToLiveNotFoundPercentageToResolveSubjectsIfNecessary = 50 # if the subject has been used at least this many times in the last cycle then auto refresh the subject # or else just remove the subject. in other words if the subject is used once (default) in the time to live (default is 1 hour), # then dont remove from cache. This will make room for new subjects in cache # set to 0 to refresh all # {valueType: "integer", required: true} subject.cache.minUseInCycleToAutoRefresh = 1 # if the subject has been used at least this many times in the last cycle then dont delete unless needed. # If the cache is 90% full, and all subjects that havent been used once have been deleted, then in the second # level delete all subjects that were used less than 3 times, to make room for new subjects in cache # {valueType: "integer", required: true} subject.cache.minUseLevel2ToNotDelete = 3 # if the subject has been used at least this many times in the last cycle then dont delete unless needed. # if the cache is 90% full, and the level 1 pass and level 2 pass have been completed, and the cache is still # 90% full, then delete subjects that were used less than 6 times, to make room for new subjects. # {valueType: "integer", required: true} subject.cache.minUseLevel3ToNotDelete = 6 # will log stats of the cache to WARN from edu.internet2.middleware.grouper.subj.cache.SubjectSourceCache # -1 to not log. Might want to write daily: 86400 # {valueType: "integer"} subject.cache.logStatsSeconds = 86400 # exclude these sourceIds from cache, comma separated # {valueType: "string", multiple: true} subject.cache.excludeSourceIds = $$subjectApi.source.g_gsa.id$$,$$subjectApi.source.grouperEntities.id$$ # this helps configure the subject source correctly. if a subject is found by identifier, and that attribute is # not mapped in the subject source, log at warn level so the admin can change the subject source so grouper knows the attribute is an identifier. # {valueType: "boolean"} subject.cache.logWarnIfIdentiferNotConfigured = true # sleep this many seconds in between looking for items to delete (if cache is full). wont run more than once per minute # {valueType: "integer", required: true} subject.cache.waitSecondsBetweenSweepforDeletes = 60 # dont sweep cache unless the cache is this percent full. note this operation is quick but dont overdo it # sweeping will delete items in cache which are expired and not used often, or if that doesnt help, then if they are expired # {valueType: "integer"} subject.cache.dontSweepCacheForDeletesUnlessCacheIsThisPercentFull = 90 # store a copy to external storage after this many seconds # {valueType: "integer"} subject.cache.storeToStorageAfterThisManySeconds = 1800 # rebuild cache to make consistent after this many seconds. this does not resolve all subjects, just internal # {valueType: "integer"} subject.cache.rebuildCacheAfterThisManySeconds = 86400 # clone subjects out of cache in case they are edited # {valueType: "boolean"} subject.cache.cloneSubjectsOnReturn = true # sleep this many seconds in between thread runs (which checks for delete, resolved, file store, etc) # {valueType: "integer"} subject.cache.sleepSecondsInBetweenThreadRuns = 120 ######################################## ## Legacy config ######################################## # enter the location of the sources.xml. Must start with classpath: or file: # blank means dont use sources.xml, use subject.properties # default is: classpath:sources.xml # e.g. file:/dir1/dir2/sources.xml # {valueType: "string"} subject.sources.xml.location = classpath:sources.xml ######################################### ## Configuration for source id: g:isa ## Source configName: g_isa ########################################## # source id # {valueType: "string", required: true} subjectApi.source.g_isa.id = g:isa # this is a friendly name for the source # {valueType: "string", required: true} subjectApi.source.g_isa.name = Grouper: Internal Source Adapter # type is not used all that much. Can have multiple types, comma separate. Can be person, group, application # {valueType: "string", required: true, multiple: true} subjectApi.source.g_isa.types = application # the adapter class implements the interface: edu.internet2.middleware.subject.Source # adapter class must extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2 : if doing JDBC this should be used if possible. All subject data in one table/view. # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter : oldest JDBC source. Put freeform queries in here # edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter : used for LDAP # edu.internet2.middleware.subject.provider.NullSourceAdapter : returns not found. You can use if you phase out a subject source # {valueType: "class", mustExtendClass: "edu.internet2.middleware.subject.provider.BaseSourceAdapter"} subjectApi.source.g_isa.adapterClass = edu.internet2.middleware.grouper.subj.InternalSourceAdapter ######################################### ## Configuration for source id: g:gsa ## Source configName: g_gsa ########################################## # source id # {valueType: "string", required: true} subjectApi.source.g_gsa.id = g:gsa # this is a friendly name for the source # {valueType: "string", required: true} subjectApi.source.g_gsa.name = Grouper: Group Source Adapter # type is not used all that much. Can have multiple types, comma separate. Can be person, group, application # {valueType: "string", required: true, multiple: true} subjectApi.source.g_gsa.types = group # the adapter class implements the interface: edu.internet2.middleware.subject.Source # adapter class must extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2 : if doing JDBC this should be used if possible. All subject data in one table/view. # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter : oldest JDBC source. Put freeform queries in here # edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter : used for LDAP # edu.internet2.middleware.subject.provider.NullSourceAdapter : returns not found. You can use if you phase out a subject source # {valueType: "class", mustExtendClass: "edu.internet2.middleware.subject.provider.BaseSourceAdapter"} subjectApi.source.g_gsa.adapterClass = edu.internet2.middleware.grouper.GrouperSourceAdapter # This virtual attribute index 0 is accessible via: subject.getAttributeValue("searchAttribute0"); # {valueType: "string", required: true, regex: "^subjectApi\\.source\\.g_gsa\\.param\\.subjectVirtualAttribute_([0-9]+)_([^.]+)\\.value$"} subjectApi.source.g_gsa.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subject.getAttributeValue('name')},${subject.getAttributeValue('displayName')},${subject.getAttributeValue('alternateName')} # the nth sort attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 sort attributes # {valueType: "string", required: true, regex: "^subjectApi\\.source\\.g_gsa\\.param\\.sortAttribute([0-9]+)\\.value$"} subjectApi.source.g_gsa.param.sortAttribute0.value = displayExtension # the 1st search attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 search attributes # {valueType: "string", required: true, regex: "^subjectApi\\.source\\.g_gsa\\.param\\.searchAttribute([0-9]+)\\.value$"} subjectApi.source.g_gsa.param.searchAttribute0.value = searchAttribute0 # max page size # {valueType: "integer", required: true, regex: "^subjectApi\\.source\\.g_gsa\\.param\\.maxPageSize\\.value$"} subjectApi.source.g_gsa.param.maxPageSize.value = 100 # internal attributes are used by grouper only not exposed to code that uses subjects. comma separated # {valueType: "string", regex: "^subjectApi\\.source\\.g_gsa\\.internalAttributes$"} subjectApi.source.g_gsa.internalAttributes = searchAttribute0 ######################################### ## Configuration for source id: grouperEntities ## Source configName: grouperEntities ########################################## # source id # {valueType: "string", required: true} subjectApi.source.grouperEntities.id = grouperEntities # this is a friendly name for the source # {valueType: "string", required: true} subjectApi.source.grouperEntities.name = Grouper: Entity Source Adapter # type is not used all that much. Can have multiple types, comma separate. Can be person, group, application # {valueType: "string", required: true, multiple: true} subjectApi.source.grouperEntities.types = application # the adapter class implements the interface: edu.internet2.middleware.subject.Source # adapter class must extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2 : if doing JDBC this should be used if possible. All subject data in one table/view. # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter : oldest JDBC source. Put freeform queries in here # edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter : used for LDAP # edu.internet2.middleware.subject.provider.NullSourceAdapter : returns not found. You can use if you phase out a subject source # {valueType: "class", mustExtendClass: "edu.internet2.middleware.subject.provider.BaseSourceAdapter"} subjectApi.source.grouperEntities.adapterClass = edu.internet2.middleware.grouper.entity.EntitySourceAdapter # This virtual attribute index 0 is accessible via: subject.getAttributeValue("searchAttribute0"); # {valueType: "string", required: true, regex: "^subjectApi\\.source\\.grouperEntities\\.param\\.subjectVirtualAttribute_([0-9]+)_([^.]+)\\.value$"} subjectApi.source.grouperEntities.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subject.getAttributeValue('name')},${subject.getAttributeValue('displayName')},${subject.getAttributeValue('alternateName')} # the 1st sort attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 sort attributes # {valueType: "string", required: true, regex: "^subjectApi\\.source\\.grouperEntities\\.param\\.sortAttribute([0-9]+)\\.value$"} subjectApi.source.grouperEntities.param.sortAttribute0.value = displayextension # the 1st search attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 search attributes # {valueType: "string", required: true, regex: "^subjectApi\\.source\\.grouperEntities\\.param\\.searchAttribute([0-9]+)\\.value$"} subjectApi.source.grouperEntities.param.searchAttribute0.value = searchAttribute0 # internal attributes are used by grouper only not exposed to code that uses subjects. comma separated # {valueType: "string"} subjectApi.source.grouperEntities.internalAttributes = searchAttribute0 ######################################### ## Configuration for source id: jdbc ## Source configName: jdbc ######################################### # note the config id does not have to be the same as the source id #subjectApi.source.someConfigId.id = someSourceId # ^ # | #subjectApi.source.jdbc.id = jdbc # this is a friendly name for the source #subjectApi.source.jdbc.name = Example JDBC Source Adapter # type is not used all that much. Can have multiple types, comma separate. Can be person, group, application #subjectApi.source.jdbc.types = person # the adapter class implements the interface: edu.internet2.middleware.subject.Source # adapter class must extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2 : if doing JDBC this should be used if possible. All subject data in one table/view. # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter : oldest JDBC source. Put freeform queries in here # edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter : used for LDAP # edu.internet2.middleware.subject.provider.NullSourceAdapter : returns not found. You can use if you phase out a subject source #subjectApi.source.jdbc.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter #subjectApi.source.jdbc.param.jdbcConnectionProvider.value = edu.internet2.middleware.grouper.subj.GrouperJdbcConnectionProvider #subjectApi.source.jdbc.param.emailAttributeName.value = email # maximum number of results from a search, generally no need to get more than 1000 #subjectApi.source.jdbc.param.maxResults.value = 1000 #subjectApi.source.jdbc.param.errorOnMaxResults.value = true #subjectApi.source.jdbc.param.maxPageSize.value = 100 #subjectApi.source.jdbc.param.maxActive.value = 16 #subjectApi.source.jdbc.param.maxIdle.value = 16 #subjectApi.source.jdbc.param.maxWait.value = -1 # 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 #subjectApi.source.jdbc.param.dbDriver.value = org.hsqldb.jdbcDriver # 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 # e.g. postgres: jdbc:postgresql:grouper #subjectApi.source.jdbc.param.dbUrl.value = jdbc:hsqldb:C:/projects/GrouperI2MI_1-2/grouper/dist/run/grouper # username when connecting to the database #subjectApi.source.jdbc.param.dbUser.value = sa # password when connecting to the database (or file with encrypted password inside) #subjectApi.source.jdbc.param.dbPwd.value = # ldap attribute which is the subject id. e.g. exampleEduRegID Each subject has one and only one subject id. Generally it is opaque and permanent. #subjectApi.source.jdbc.param.SubjectID_AttributeType.value = id # attribute which is the subject name #subjectApi.source.jdbc.param.Name_AttributeType.value = name # attribute which is the subject description #subjectApi.source.jdbc.param.Description_AttributeType.value = description # This virtual attribute index 0 is accessible via: subject.getAttributeValue("searchAttribute0"); #subjectApi.source.jdbc.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subject.name},${subjectUtils.defaultIfBlank(subject.getAttributeValue('LFNAME'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValue('LOGINID'), "")},${subjectUtils.defaultIfBlank(subject.description, "")},${subjectUtils.defaultIfBlank(subject.getAttributeValue('EMAIL'), "")} # the 1st sort attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 sort attributes #subjectApi.source.jdbc.param.sortAttribute0.value = LFNAME # the 2nd sort attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 sort attributes #subjectApi.source.jdbc.param.sortAttribute1.value = LOGINID # the 1st search attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 search attributes #subjectApi.source.jdbc.param.searchAttribute0.value = searchAttribute0 #subjectApi.source.jdbc.param.useInClauseForIdAndIdentifier.value = true #subjectApi.source.jdbc.param.identifierAttributes.value = LOGINID # subject identifier to store in grouper's member table. this is used to increase speed of loader and perhaps for provisioning # you can have up to max 1 subject identifier #subjectApi.source.jdbc.param.subjectIdentifierAttribute0.value = LOGINID #searchSubject: find a subject by ID. ID is generally an opaque and permanent identifier, e.g. 12345678. # Each subject has one and only on ID. Returns one result when searching for one ID. # sql is the sql to search for the subject by id should use an {inclause} #subjectApi.source.jdbc.search.searchSubject.param.sql.value = select s.subjectid as id, s.name as name, (select sa2.value from subjectattribute sa2 where name='name' and sa2.SUBJECTID = s.subjectid) as lfname, (select sa3.value from subjectattribute sa3 where name='loginid' and sa3.SUBJECTID = s.subjectid) as loginid, (select sa4.value from subjectattribute sa4 where name='description' and sa4.SUBJECTID = s.subjectid) as description, (select sa5.value from subjectattribute sa5 where name='email' and sa5.SUBJECTID = s.subjectid) as email from subject s where {inclause} # inclause allows searching by subject for multiple ids or identifiers in one query, must have {inclause} in the sql query, # this will be subsituted to in clause with the following. Should use a question mark ? for bind variable #subjectApi.source.jdbc.search.searchSubject.param.inclause.value = s.subjectid = ? #searchSubjectByIdentifier: find a subject by identifier. Identifier is anything that uniquely # identifies the user, e.g. jsmith or jsmith@institution.edu. # Subjects can have multiple identifiers. Note: it is nice to have if identifiers are unique # even across sources. Returns one result when searching for one identifier. # sql is the sql to search for the subject by identifier should use an {inclause} #subjectApi.source.jdbc.search.searchSubjectByIdentifier.param.sql.value = select s.subjectid as id, s.name as name, (select sa2.value from subjectattribute sa2 where name='name' and sa2.SUBJECTID = s.subjectid) as lfname, (select sa3.value from subjectattribute sa3 where name='loginid' and sa3.SUBJECTID = s.subjectid) as loginid, (select sa4.value from subjectattribute sa4 where name='description' and sa4.SUBJECTID = s.subjectid) as description, (select sa5.value from subjectattribute sa5 where name='email' and sa5.SUBJECTID = s.subjectid) as email from subject s, subjectattribute a where a.name='loginid' and s.subjectid = a.subjectid and {inclause} # inclause allows searching by subject for multiple ids or identifiers in one query, must have {inclause} in the sql query, # this will be subsituted to in clause with the following. Should use a question mark ? for bind variable #subjectApi.source.jdbc.search.searchSubjectByIdentifier.param.inclause.value = a.value = ? # search: find subjects by free form search. Returns multiple results. # sql is the sql to search for the subject free-form search. user question marks for bind variables #subjectApi.source.jdbc.search.search.param.sql.value = select s.subjectid as id, s.name as name, (select sa2.value from subjectattribute sa2 where name='name' and sa2.SUBJECTID = s.subjectid) as lfname, (select sa3.value from subjectattribute sa3 where name='loginid' and sa3.SUBJECTID = s.subjectid) as loginid, (select sa4.value from subjectattribute sa4 where name='description' and sa4.SUBJECTID = s.subjectid) as description, (select sa5.value from subjectattribute sa5 where name='email' and sa5.SUBJECTID = s.subjectid) as email from subject s where s.subjectid in ( select subjectid from subject where lower(name) like concat('%',concat(?,'%')) union select subjectid from subjectattribute where searchvalue like concat('%',concat(?,'%')) ) # internal attributes are used by grouper only not exposed to code that uses subjects. comma separated #subjectApi.source.jdbc.internalAttributes = searchAttribute0 ######################################### ## Configuration for source id: sourceId ## Source configName: sourceId ######################################### # source id # {valueType: "string", required: true, regex: "^subjectApi\\.source\\.([^.]+)\\.id$"} #subjectApi.source.sourceId.id = sourceId # this is a friendly name for the source # {valueType: "string", required: true, regex: "^subjectApi\\.source\\.([^.]+)\\.name$"} #subjectApi.source.sourceId.name = Source name # type is not used all that much. Can have multiple types, comma separate. Can be person, group, application # {valueType: "string", required: true, multiple: true, regex: "^subjectApi\\.source\\.([^.]+)\\.types$"} #subjectApi.source.sourceId.types = person # the adapter class implements the interface: edu.internet2.middleware.subject.Source # adapter class must extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2 : if doing JDBC this should be used if possible. All subject data in one table/view. # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter : oldest JDBC source. Put freeform queries in here # edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter : used for LDAP # edu.internet2.middleware.subject.provider.NullSourceAdapter : returns not found. You can use if you phase out a subject source # {valueType: "class", mustExtendClass: "edu.internet2.middleware.subject.provider.BaseSourceAdapter", regex: "^subjectApi\\.source\\.([^.]+)\\.adapterClass$"} #subjectApi.source.sourceId.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2 # if this is jdbc, this is the provider. use edu.internet2.middleware.grouper.subj.GrouperJdbcConnectionProvider. # if connecting to the grouper database from grouper.hibernate.properties, then it will just work. If not, then se the configId # to use a database from grouper-loader.properties. The legacy value here is edu.internet2.middleware.subject.provider.C3p0JdbcConnectionProvider # where you can enter in a username and password and db url in the subject.properties (legacy) # {valueType: "class", mustExtendClass: "edu.internet2.middleware.grouperClient.jdbc.GcJdbcConnectionProvider", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.jdbcConnectionProvider\\.value$"} #subjectApi.source.sourceId.param.jdbcConnectionProvider.value = edu.internet2.middleware.grouper.subj.GrouperJdbcConnectionProvider # if this is jdbc, and the jdbcConnectionProvider this is the configId which matches a database connnection in the grouper-loader.properties # if this equals "grouper" or blank, then use the grouper.hibernate.properties "grouper" database connection. # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.jdbcConfigId\\.value$"} #subjectApi.source.sourceId.param.jdbcConfigId.value = grouper # maximum number of results from a search, generally no need to get more than 1000 # {valueType: "integer", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.maxResults\\.value$"} #subjectApi.source.sourceId.param.maxResults.value = 1000 # the table or view to query results from. Note, could prefix with a schema name # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.dbTableOrView\\.value$"} #subjectApi.source.sourceId.param.dbTableOrView.value = person_source_v # the column name to get the subjectId from # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.subjectIdCol\\.value$"} #subjectApi.source.sourceId.param.subjectIdCol.value = some_id # the column name to get the name from # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.nameCol\\.value$"} #subjectApi.source.sourceId.param.nameCol.value = name # column name to get description from # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.descriptionCol\\.value$"} #subjectApi.source.sourceId.param.descriptionCol.value = description # search col where general searches take place, lower case # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.lowerSearchCol\\.value$"} #subjectApi.source.sourceId.param.lowerSearchCol.value = description_lower # optional col if you want the search results sorted in the API (note, UI might override) # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.defaultSortCol\\.value$"} #subjectApi.source.sourceId.param.defaultSortCol.value = description # you can count up from 0 to N of columns to search by identifier (which might also include by id) # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.subjectIdentifierCol([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.subjectIdentifierCol0.value = pennname # you can count up from 0 to N of columns to search by identifier (which might also include by id) # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.subjectIdentifierCol([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.subjectIdentifierCol1.value = penn_id # now you can count up from 0 to N of attributes for various cols. The name is how to reference in subject.getAttribute() # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.subjectAttributeCol([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.subjectAttributeCol0.value = pennname # you can count up from 0 to N of attributes for various cols. The name is how to reference in subject.getAttribute() # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.subjectAttributeName([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.subjectAttributeName0.value = PENNNAME # now you can count up from 0 to N of attributes for various cols. The name is how to reference in subject.getAttribute() # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.subjectAttributeCol([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.subjectAttributeCol1.value = description_lower # you can count up from 0 to N of attributes for various cols. The name is how to reference in subject.getAttribute() # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.subjectAttributeName([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.subjectAttributeName1.value = searchAttribute0 # This virtual attribute index 0 is accessible via: subject.getAttributeValue("something"); # {valueType: "string", required: true, regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.subjectVirtualAttribute_([0-9]+)_([^.]+)\\.value$"} #subjectApi.source.sourceId.param.subjectVirtualAttribute_0_something.value = ${subject.name},${subjectUtils.defaultIfBlank(subject.getAttributeValue('PENNNAME'), "")} # the 1st sort attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 sort attributes # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.sortAttribute([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.sortAttribute0.value = description # the 1st search attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 search attributes # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.searchAttribute([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.searchAttribute0.value = searchAttribute0 # STATUS SECTION for searches to filter out inactives and allow # the user to filter by status with e.g. status=all # this is optional, and advanced # # field in database or ldap or endpoint that is the status field # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.statusDatastoreFieldName\\.value$"} #subjectApi.source.sourceId.param.statusDatastoreFieldName.value = status # search string from user which represents the status. e.g. status=active # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.statusLabel\\.value$"} #subjectApi.source.sourceId.param.statusLabel.value = status # available statuses from screen (if not specified, any will be allowed). comma separated list. # Note, this is optional and you probably dont want to configure it, it is mostly necessary # when you have multiple sources with statuses... if someone types an invalid status # and you have this configured, it will not filter by it # {valueType: "string", multiple: true, regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.statusesFromUser\\.value$"} #subjectApi.source.sourceId.param.statusesFromUser.value = Active, Inactive, Pending, All # if no status is specified, this will be used (e.g. for active only). Note, the value should be of the # form the user would type in # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.statusSearchDefault\\.value$"} #subjectApi.source.sourceId.param.statusSearchDefault.value = status=active # translate between screen values of status, and the data store value. Increment the 0 to 1, 2, etc for more translations. # so the user could enter: status=active, and that could translate to status_col=A. The 'user' is what the user types in, # the 'datastore' is what is in the datastore. The user part is not case-sensitive. Note, this could be a many to one # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.statusTranslateUser([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.statusTranslateUser0.value = active # datastore value status # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.statusTranslateDatastore([0-9]+)\\.value$"} #subjectApi.source.sourceId.param.statusTranslateDatastore0.value = A # internal attributes are used by grouper only not exposed to code that uses subjects. comma separated # {valueType: "string", multiple: true, regex: "^subjectApi\\.source\\.([^.]+)\\.internalAttributes$"} #subjectApi.source.sourceId.internalAttributes = searchAttribute0 # attribure that is the email address for the user # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.emailAttributeName\\.value$"} #subjectApi.source.sourceId.param.emailAttributeName.value = email # maximum number of results from a search, generally no need to get more than 1000 # {valueType: "integer", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.emailAttributeName\\.value$"} #subjectApi.source.sourceId.param.maxResults.value = 1000 # if an error should be thrown if the max results is reached # {valueType: "boolean", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.errorOnMaxResults\\.value$"} #subjectApi.source.sourceId.param.errorOnMaxResults.value = true # max page size # {valueType: "integer", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.maxPageSize\\.value$"} #subjectApi.source.sourceId.param.maxPageSize.value = 100 # max active connections # {valueType: "integer", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.maxActive\\.value$"} #subjectApi.source.sourceId.param.maxActive.value = 16 # max idle connections # {valueType: "integer", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.maxIdle\\.value$"} #subjectApi.source.sourceId.param.maxIdle.value = 16 # max wait for connection # {valueType: "integer", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.maxWait\\.value$"} #subjectApi.source.sourceId.param.maxWait.value = -1 # 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 # {valueType: "class", mustImplementInterface: "java.sql.Driver", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.dbDriver\\.value$"} #subjectApi.source.sourceId.param.dbDriver.value = org.hsqldb.jdbcDriver # 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 # e.g. postgres: jdbc:postgresql:grouper # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.dbUrl\\.value$"} #subjectApi.source.sourceId.param.dbUrl.value = jdbc:hsqldb:C:/projects/GrouperI2MI_1-2/grouper/dist/run/grouper # username when connecting to the database # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.dbUser\\.value$"} #subjectApi.source.sourceId.param.dbUser.value = sa # password when connecting to the database (or file with encrypted password inside) # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.dbPwd\\.value$"} #subjectApi.source.sourceId.param.dbPwd.value = # ldap attribute which is the subject id. e.g. exampleEduRegID Each subject has one and only one subject id. Generally it is opaque and permanent. # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.SubjectID_AttributeType\\.value$"} #subjectApi.source.sourceId.param.SubjectID_AttributeType.value = id # attribute which is the subject name # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.Name_AttributeType\\.value$"} #subjectApi.source.sourceId.param.Name_AttributeType.value = name # attribute which is the subject description # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.Description_AttributeType\\.value$"} #subjectApi.source.sourceId.param.Description_AttributeType.value = description # if inclause should be userd for bulk retrieves # {valueType: "string", regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.useInClauseForIdAndIdentifier\\.value$"} #subjectApi.source.sourceId.param.useInClauseForIdAndIdentifier.value = true # attributes used in search by identifier # {valueType: "string", multiple: true, regex: "^subjectApi\\.source\\.([^.]+)\\.param\\.identifierAttributes\\.value$"} #subjectApi.source.sourceId.param.identifierAttributes.value = LOGINID ######################################### ## Configuration for source id: example ## Source configName: example ######################################### #subjectApi.source.example.id = example # this is a friendly name for the source #subjectApi.source.example.name = Example Edu # type is not used all that much. Can have multiple types, comma separate. Can be person, group, application #subjectApi.source.example.types = person # the adapter class implements the interface: edu.internet2.middleware.subject.Source # adapter class must extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2 : if doing JDBC this should be used if possible. All subject data in one table/view. # edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter : oldest JDBC source. Put freeform queries in here # edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter : used for LDAP # edu.internet2.middleware.subject.provider.NullSourceAdapter : returns not found. You can use if you phase out a subject source #subjectApi.source.example.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter # configuration in grouper-loader.properties with the ldap connection information (e.g. url, user, password, pooling, etc) #subjectApi.source.example.param.ldapServerId.value = personLdap # ldap attribute which is the subject id. e.g. exampleEduRegID Each subject has one and only one subject id. Generally it is opaque and permanent. #subjectApi.source.example.param.SubjectID_AttributeType.value = exampleEduRegID # if the subject id should be changed to lower case after reading from datastore. true or false #subjectApi.source.example.param.SubjectID_formatToLowerCase.value = false # attribute which is the subject name #subjectApi.source.example.param.Name_AttributeType.value = cn # attribute which is the subject description #subjectApi.source.example.param.Description_AttributeType.value = description # This virtual attribute index 0 is accessible via: subject.getAttributeValue("searchAttribute0"); #subjectApi.source.example.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('uid'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('cn'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('exampleEduRegId'), "")} # the 1st sort attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 sort attributes #subjectApi.source.example.param.sortAttribute0.value = cn # the 1st search attribute for lists on screen that are derived from member table (e.g. search for member in group) # you can have up to 5 search attributes #subjectApi.source.example.param.searchAttribute0.value = searchAttribute0 # STATUS SECTION for searches to filter out inactives and allow # the user to filter by status with e.g. status=all # this is optional, and advanced # # field in database or ldap or endpoint that is the status field #subjectApi.source.example.param.statusDatastoreFieldName.value = status # search string from user which represents the status. e.g. status=active #subjectApi.source.example.param.statusLabel.value = status # available statuses from screen (if not specified, any will be allowed). comma separated list. # Note, this is optional and you probably dont want to configure it, it is mostly necessary # when you have multiple sources with statuses... if someone types an invalid status # and you have this configured, it will not filter by it #subjectApi.source.example.param.statusesFromUser.value = Active, Inactive, Pending, All # all label from the user #subjectApi.source.example.param.statusAllFromUser.value = All # if no status is specified, this will be used (e.g. for active only). Note, the value should be of the # form the user would type in #subjectApi.source.example.param.statusSearchDefault.value = status=active # translate between screen values of status, and the data store value. Increment the 0 to 1, 2, etc for more translations. # so the user could enter: status=active, and that could translate to status_col=A. The 'user' is what the user types in, # the 'datastore' is what is in the datastore. The user part is not case-sensitive. Note, this could be a many to one #subjectApi.source.example.param.statusTranslateUser0.value = active #subjectApi.source.example.param.statusTranslateDatastore0.value = A # subject identifier to store in grouper's member table. this is used to increase speed of loader and perhaps for provisioning # you can have up to max 1 subject identifier #subjectApi.source.example.param.subjectIdentifierAttribute0.value = uid #searchSubject: find a subject by ID. ID is generally an opaque and permanent identifier, e.g. 12345678. # Each subject has one and only on ID. Returns one result when searching for one ID. # sql is the sql to search for the subject by id. %TERM% will be subsituted by the id searched for #subjectApi.source.example.search.searchSubject.param.filter.value = (& (exampleEduRegId=%TERM%) (objectclass=exampleEduPerson)) # Scope Values can be: OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE #subjectApi.source.example.search.searchSubject.param.scope.value = SUBTREE_SCOPE # base dn to search in - this is relative to the base dn specified in the LDAP url in your grouper-loader.properties configuration # e.g. if your url is ldaps://ldapserver.school.edu:636/dc=school,dc=edu, then you might specify ou=people here # if your url is ldaps://ldapserver.school.edu:636, then you might specify ou=people,dc=school,dc=edu here #subjectApi.source.example.search.searchSubject.param.base.value = ou=people #searchSubjectByIdentifier: find a subject by identifier. Identifier is anything that uniquely # identifies the user, e.g. jsmith or jsmith@institution.edu. # Subjects can have multiple identifiers. Note: it is nice to have if identifiers are unique # even across sources. Returns one result when searching for one identifier. # sql is the sql to search for the subject by identifier. %TERM% will be subsituted by the identifier searched for #subjectApi.source.example.search.searchSubjectByIdentifier.param.filter.value = (& (uid=%TERM%) (objectclass=exampleEduPerson)) # Scope Values can be: OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE #subjectApi.source.example.search.searchSubjectByIdentifier.param.scope.value = SUBTREE_SCOPE # base dn to search in - this is relative to the base dn specified in the LDAP url in your grouper-loader.properties configuration # e.g. if your url is ldaps://ldapserver.school.edu:636/dc=school,dc=edu, then you might specify ou=people here # if your url is ldaps://ldapserver.school.edu:636, then you might specify ou=people,dc=school,dc=edu here #subjectApi.source.example.search.searchSubjectByIdentifier.param.base.value = ou=people # search: find subjects by free form search. Returns multiple results. # sql is the sql to search for the subject by free form search. %TERM% will be subsituted by the text searched for #subjectApi.source.example.search.search.param.filter.value = (& (|(|(uid=%TERM%)(cn=*%TERM%*))(exampleEduRegId=%TERM%))(objectclass=exampleEduPerson)) # Scope Values can be: OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE #subjectApi.source.example.search.search.param.scope.value = SUBTREE_SCOPE # base dn to search in - this is relative to the base dn specified in the LDAP url in your grouper-loader.properties configuration # e.g. if your url is ldaps://ldapserver.school.edu:636/dc=school,dc=edu, then you might specify ou=people here # if your url is ldaps://ldapserver.school.edu:636, then you might specify ou=people,dc=school,dc=edu here #subjectApi.source.example.search.search.param.base.value = ou=people # attributes from ldap object to become subject attributes. comma separated #subjectApi.source.example.attributes = cn, sn, uid, department, exampleEduRegId # internal attributes are used by grouper only not exposed to code that uses subjects. comma separated #subjectApi.source.example.internalAttributes = searchAttribute0 # maximum number of results from a search, generally no need to get more than 1000 #subjectApi.source.example.param.maxResults.value = 1000 # if an error should be thrown if the max results is reached #subjectApi.source.example.param.errorOnMaxResults.value = true # max page size #subjectApi.source.example.param.maxPageSize.value = 100 ####################################### ## common subject source settings ####################################### # subject source id # {valueType: "string", required: true, order: 1000, subSection: "general"} # subjectApi.source.genericSource.id = # subject source name # {valueType: "string", required: true, order: 2000, subSection: "general"} # subjectApi.source.genericSource.name = # enabled or disabled # {valueType: "boolean", defaultValue: "true", order: 3000, subSection: "general"} # subjectApi.source.genericSource.enabled = # person or application # {valueType: "string", required: true, order: 4000, subSection: "general", formElement: "dropdown", optionValues: ["person", "application"]} # subjectApi.source.genericSource.types = # max results to pull # {valueType: "integer", order: 5000, subSection: "general", defaultValue: 100} # subjectApi.source.genericSource.param.maxResults.value = # source attribute names to be retrieved, not listed below # {valueType: "string", order: 6000, subSection: "general"} # subjectApi.source.genericSource.extraAttributesFromSource = # number of attributes # {valueType: "integer", order: 7000, required: true, subSection: "general", 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"] } # subjectApi.source.genericSource.numberOfAttributes = # attribute name # {valueType: "string", subSection: "general", required: true, order: 10000, showEl: "${numberOfAttributes > $i$}", repeatGroup: "attribute", repeatCount: 30} # subjectApi.source.genericSource.attribute.$i$.name = # attribute value format to lower class after reading from source # {valueType: "boolean", order: 12000, showEl: "${numberOfAttributes > $i$}", repeatGroup: "attribute", repeatCount: 30} # subjectApi.source.genericSource.attribute.$i$.formatToLowerCase = # by default, these are simple attribute mapping but set this to true if it's a scriplet # {valueType: "string", order: 13000, showEl: "${numberOfAttributes > $i$}", required: true, formElement: "dropdown", optionValues: ["sourceAttributeSameAsSubjectAttribute", "sourceAttribute", "translation"], repeatGroup: "attribute", repeatCount: 30} # subjectApi.source.genericSource.attribute.$i$.translationType = # name of a sql column or ldap attribute from source to use for this subject attribute. e.g. email_address would be the email_address column # mutually exclusive with translation # {valueType: "string", order: 14000, required: true, showEl: "${numberOfAttributes > $i$ && attribute.$i$.translationType == 'sourceAttribute' }", repeatGroup: "attribute", repeatCount: 30} # subjectApi.source.genericSource.attribute.$i$.sourceAttribute = # we need variables from source, and variables for other subject attributes. suggestion is # ${sourceAttribute__first_name} - gets an attribute from the source query or filter. in this case 'first_name' column # ${subjectField__description} - references a built in subject field, in this case the description field # ${subjectAttribute__emailAddress} - references a previously configured subject attribute. in this case "emailAddress" # {valueType: "string", order: 15000, required: true, showEl: "${numberOfAttributes > $i$ && attribute.$i$.translationType == 'translation'}", repeatGroup: "attribute", repeatCount: 30} # subjectApi.source.genericSource.attribute.$i$.translation = # subject identifier # {valueType: "boolean", order: 17000, showEl: "${numberOfAttributes > $i$ && attribute.$i$.translationType != 'translation'}", defaultValue: "false", repeatGroup: "attribute", repeatCount: 30} # subjectApi.source.genericSource.attribute.$i$.subjectIdentifier = # internal # {valueType: "boolean", order: 18000, showEl: "${numberOfAttributes > $i$}", defaultValue: "false", repeatGroup: "attribute", repeatCount: 30} # subjectApi.source.genericSource.attribute.$i$.internal = # attribute name for subject id # {valueType: "string", subSection: "subjectFieldMapping", required: true, formElement: "dropdown", order: 19100, optionValuesFromClass: "edu.internet2.middleware.grouper.app.subectSource.SubjectAttributeNameOptionValues"} # subjectApi.source.genericSource.param.SubjectID_AttributeType.value = # attribute name for subject name # {valueType: "string", subSection: "subjectFieldMapping", required: true, formElement: "dropdown", order: 19200, optionValuesFromClass: "edu.internet2.middleware.grouper.app.subectSource.SubjectAttributeNameOptionValues"} # subjectApi.source.genericSource.param.Name_AttributeType.value = # attribute name for subject description # {valueType: "string", subSection: "subjectFieldMapping", required: true, formElement: "dropdown", order: 19300, optionValuesFromClass: "edu.internet2.middleware.grouper.app.subectSource.SubjectAttributeNameOptionValues"} # subjectApi.source.genericSource.param.Description_AttributeType.value = # attribute name email attribute # {valueType: "string", subSection: "subjectFieldMapping", formElement: "dropdown", order: 19400, optionValuesFromClass: "edu.internet2.middleware.grouper.app.subectSource.SubjectAttributeNameOptionValues"} # subjectApi.source.genericSource.param.emailAttributeName.value = # attribute name for net id # {valueType: "string", subSection: "subjectFieldMapping", formElement: "dropdown", order: 19500, optionValuesFromClass: "edu.internet2.middleware.grouper.app.subectSource.SubjectAttributeNameOptionValues"} # subjectApi.source.genericSource.param.netId.value = # number of search attributes # {valueType: "integer", order: 20000, required: true, subSection: "searchAttributes", formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5"] } # subjectApi.source.genericSource.searchAttributeCount = # attribute name # {valueType: "string", subSection: "searchAttributes", required: true, formElement: "dropdown", order: 24000, showEl: "${searchAttributeCount > $i$}", repeatGroup: "searchAttribute", repeatCount: 5, optionValuesFromClass: "edu.internet2.middleware.grouper.app.subectSource.SubjectAttributeNameOptionValues"} # subjectApi.source.genericSource.searchAttribute.$i$.attributeName = # number of sort attributes # {valueType: "integer", order: 27000, subSection: "sortAttributes", required: true, formElement: "dropdown", optionValues: ["1", "2", "3", "4", "5"] } # subjectApi.source.genericSource.sortAttributeCount = # attribute name # {valueType: "string", subSection: "sortAttributes", required: true, formElement: "dropdown", order: 31000, showEl: "${sortAttributeCount > $i$}", repeatGroup: "sortAttribute", repeatCount: 5, optionValuesFromClass: "edu.internet2.middleware.grouper.app.subectSource.SubjectAttributeNameOptionValues" } # subjectApi.source.genericSource.sortAttribute.$i$.attributeName = # if this source should do a findById when the status of Grouper is checked e.g. in the status servlet # {valueType: "boolean", order: 44000, subSection: "checkConfigAndDiagnostics", defaultValue: "true"} # subjectApi.source.genericSource.param.findSubjectByIdOnCheckConfig.value = # This is the subjectId to check on status of Grouper. # {valueType: "string", order: 45000, subSection: "checkConfigAndDiagnostics", defaultValue: "grouperTestSubjectByIdOnStartupASDFGHJ", showEl: "${param.findSubjectByIdOnCheckConfig.value}"} # subjectApi.source.genericSource.param.subjectIdToFindOnCheckConfig.value = # if this source should do a findByIdentifier when the status of Grouper is checked e.g. in the status servlet # {valueType: "boolean", order: 46000, subSection: "checkConfigAndDiagnostics", defaultValue: "true"} # subjectApi.source.genericSource.param.findSubjectByIdentifiedOnCheckConfig.value = # This is the subjectIdentifier to check on status of Grouper. # {valueType: "string", order: 47000, subSection: "checkConfigAndDiagnostics", defaultValue: "grouperTestSubjectByIdentifierOnStartupASDFGHJ", showEl: "${param.findSubjectByIdentifiedOnCheckConfig.value}"} # subjectApi.source.genericSource.param.subjectIdentifierToFindOnCheckConfig.value = # if this source should do a findByIdentifier when the status of Grouper is checked e.g. in the status servlet # {valueType: "boolean", order: 48000, subSection: "checkConfigAndDiagnostics", defaultValue: "true"} # subjectApi.source.genericSource.param.findSubjectByStringOnCheckConfig.value = # This is the search string to check on status of Grouper. Shouldn't return too many results for performance reasons. # {valueType: "string", order: 49000, subSection: "checkConfigAndDiagnostics", defaultValue: "grouperTestStringOnStartupASDFGHJ", showEl: "${param.findSubjectByStringOnCheckConfig.value}"} # subjectApi.source.genericSource.param.stringToFindOnCheckConfig.value = # show status settings # {valueType: "boolean", order: 49500, subSection: "statusSettings", defaultValue: "false"} # subjectApi.source.genericSource.showStatusSettings = # Status all from user # {valueType: "string", order: 50000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusAllFromUser.value = # Status datastore field name # {valueType: "string", order: 51000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusDatastoreFieldName.value = # Statuses from user # {valueType: "string", order: 52000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusesFromUser.value = # Status label # {valueType: "string", order: 53000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusLabel.value = # Status search default # {valueType: "string", order: 54000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusSearchDefault.value = # Status translate user 0 # {valueType: "string", order: 55000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateUser0.value = # Status translate user 1 # {valueType: "string", order: 56000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateUser1.value = # Status translate user 2 # {valueType: "string", order: 57000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateUser2.value = # Status translate user 3 # {valueType: "string", order: 58000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateUser3.value = # Status translate user 4 # {valueType: "string", order: 59000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateUser4.value = # Status translate datastore 0 # {valueType: "string", order: 60000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateDatastore0.value = # Status translate datastore 1 # {valueType: "string", order: 61000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateDatastore1.value = # Status translate datastore 2 # {valueType: "string", order: 62000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateDatastore2.value = # Status translate datastore 3 # {valueType: "string", order: 63000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateDatastore3.value = # Status translate datastore 4 # {valueType: "string", order: 64000, subSection: "statusSettings", showEl: "${showStatusSettings}"} # subjectApi.source.genericSource.param.statusTranslateDatastore4.value = ######################################## ## sql subject source ######################################## # sql adapter class # {valueType: "class", required: true, readOnly: true, order: 10} # subjectApi.source.someSqlSource.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2_5 # this is the sql external system config id # {valueType: "string", order: 4500, subSection: "general", required: true, formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.loader.db.DatabaseGrouperExternalSystem"} # subjectApi.source.someSqlSource.param.jdbcConfigId.value = # db table or view # {valueType: "string", order: 32000, subSection: "sqlSettings", required: true} # subjectApi.source.someSqlSource.param.dbTableOrView.value = # search column - lowercase only # {valueType: "string", order: 34000, subSection: "sqlSettings", required: true} # subjectApi.source.someSqlSource.param.lowerSearchCol.value = # default sort column # {valueType: "string", order: 35000, subSection: "sqlSettings"} # subjectApi.source.someSqlSource.param.defaultSortCol.value = ######################################## ## ldap subject source ######################################## # ldap adapter class # {valueType: "class", required: true, readOnly: true, order: 10} # subjectApi.source.someLdapSource.adapterClass = edu.internet2.middleware.grouper.subj.GrouperLdapSourceAdapter2_5 # this is the ldap external system config id # {valueType: "string", required: true, order: 4500, subSection: "general", formElement: "dropdown", optionValuesFromClass: "edu.internet2.middleware.grouper.app.externalSystem.LdapGrouperExternalSystem"} # subjectApi.source.someLdapSource.param.ldapServerId.value = # %TERM% in filter. Note, this can be automatic if blank # {valueType: "string", order: 32000, subSection: "ldapSettings"} # subjectApi.source.someLdapSource.search.searchSubject.param.filter.value = # search subject by id scope # {valueType: "string", subSection: "ldapSettings", defaultValue: "SUBTREE_SCOPE", order: 33000, formElement: "dropdown", optionValues: ["SUBTREE_SCOPE"]} # subjectApi.source.someLdapSource.search.searchSubject.param.scope.value = # search subject by id base dn # {valueType: "string", subSection: "ldapSettings", order: 34000, required: true} # subjectApi.source.someLdapSource.search.searchSubject.param.base.value = # %TERM% in filter. Note, this can be automatic if blank # {valueType: "string", subSection: "ldapSettings", order: 35000} # subjectApi.source.someLdapSource.search.searchSubjectByIdentifier.param.filter.value = # %TERM% in filter. # {valueType: "string", subSection: "ldapSettings", order: 38000, required: true} # subjectApi.source.someLdapSource.search.search.param.filter.value = # multiple results (advance setting, generally leave this to false) # {valueType: "boolean", subSection: "ldapSettings", order: 41000, defaultValue: "false"} # subjectApi.source.someLdapSource.param.Multiple_Results.value = # throw error on find all failure (advance setting, generally leave this to true) # {valueType: "boolean", subSection: "ldapSettings", order: 42000, defaultValue: "true"} # subjectApi.source.someLdapSource.param.throwErrorOnFindAllFailure.value = # max page size # {valueType: "integer", order: 43000, subSection: "ldapSettings"} # subjectApi.source.someLdapSource.param.maxPageSize.value = # error on max results (advance setting, generally leave this to true) # {valueType: "boolean", subSection: "ldapSettings", order: 44000, defaultValue: "true"} # subjectApi.source.someLdapSource.param.errorOnMaxResults.value = # comma separated list of ldap attributes that are multivalued. if it's not multivalued it's easier to use in translation expression. # {valueType: "string", order: 45000, subSection: "ldapSettings"} # subjectApi.source.someLdapSource.multivaluedLdapAttributes =