diff --git a/.gitignore b/.gitignore index f040154..2063705 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ localManualBuild.sh -runContainer +runContainer.sh tmp \ No newline at end of file diff --git a/ex201/data-generator.html b/ex201/data-generator-201.1.html similarity index 100% rename from ex201/data-generator.html rename to ex201/data-generator-201.1.html diff --git a/ex201/ex201.2.1/Dockerfile b/ex201/ex201.2.1/Dockerfile new file mode 100644 index 0000000..09172ed --- /dev/null +++ b/ex201/ex201.2.1/Dockerfile @@ -0,0 +1,26 @@ +FROM tier/grouper-training-env:ex201.1.end + +LABEL author="tier-packaging@internet2.edu " \ + Vendor="TIER" \ + ImageType="Grouper Training" \ + ImageName=$imagename \ + ImageOS=centos7 + +ENV USERTOKEN=ex201.2.1 + +COPY container_files/seed-data/ /seed-data/ +COPY container_files/grouper-loader.properties /opt/grouper/conf/ +COPY container_files/subject.properties /opt/grouper/conf/ + +RUN (/usr/sbin/slapd -h "ldap:/// ldaps:/// ldapi:///" -u ldap &) \ + && while ! curl -s ldap://localhost:389 > /dev/null; do echo waiting for ldap to start; sleep 1; done; \ + (mysqld_safe & ) \ + && while ! curl -s localhost:3306 > /dev/null; do echo waiting for mysqld to start; sleep 3; done; \ + cd /opt/grouper/grouper.apiBinary \ + && ldapadd -x -D cn=root,dc=internet2,dc=edu -w password -f /seed-data/users.ldif \ + && mysql grouper < /seed-data/sisData.sql \ + && bin/gsh /seed-data/bootstrap.gsh \ + && pkill -HUP slapd \ + && while curl -s ldap://localhost:389 > /dev/null; do echo waiting for ldap to stop; sleep 1; done; \ + pkill -u mysql mysqld \ + && while curl -s localhost:3306 > /dev/null; do echo waiting for mysqld to stop; sleep 1; done diff --git a/ex201/ex201.2.1/container_files/grouper-loader.properties b/ex201/ex201.2.1/container_files/grouper-loader.properties new file mode 100644 index 0000000..ae41ed1 --- /dev/null +++ b/ex201/ex201.2.1/container_files/grouper-loader.properties @@ -0,0 +1,73 @@ +#specify the consumers here. specify the consumer name after the changeLog.consumer. part. This example is "psp" +#but it could be changeLog.consumer.myConsumerName.class +#the class must extend edu.internet2.middleware.grouper.changeLog.ChangeLogConsumerBase +#changeLog.consumer.psp.class = edu.internet2.middleware.psp.grouper.PspChangeLogConsumer + +#the quartz cron is a cron-like string. it defaults to every minute on the minute (since the temp to change log job runs +#at 10 seconds to each minute). it defaults to this: 0 * * * * ? +#though it will stagger each one by 2 seconds +# http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger +#changeLog.consumer.psp.quartzCron = 0 * * * * ? + +# To retry processing a change log entry if an error occurs, set retryOnError to true. Defaults to false. +#changeLog.consumer.psp.retryOnError = false + +# To run full provisioning synchronizations periodically, provide the class name which provides a 'public void fullSync()' method. +#changeLog.psp.fullSync.class = edu.internet2.middleware.psp.grouper.PspChangeLogConsumer + +# Schedule full synchronizations. Defaults to 5 am : 0 0 5 * * ?. +#changeLog.psp.fullSync.quartzCron = 0 0 5 * * ? + +# Run a full synchronization job at startup. Defaults to false. +#changeLog.psp.fullSync.runAtStartup = false + +# Omit diff responses from bulk response to conserve memory. +#changeLog.psp.fullSync.omitDiffResponses = true + +# Omit sync responses from bulk response to conserve memory. +#changeLog.psp.fullSync.omitSyncResponses = true + +################################# +## LDAP connections +################################# +# specify the ldap connection with user, pass, url +# the string after "ldap." is the ID of the connection, and it should not have +# spaces or other special chars in it. In this case is it "personLdap" + +#note the URL should start with ldap: or ldaps: if it is SSL. +#It should contain the server and port (optional if not default), and baseDn, +#e.g. ldaps://ldapserver.school.edu:636/dc=school,dc=edu +ldap.demo.url = ldap://localhost:389/ + +#optional, if authenticated +ldap.demo.user = cn=root,dc=internet2,dc=edu + +#optional, if authenticated note the password can be stored encrypted in an external file +ldap.demo.pass = password + +#optional, if you are using tls, set this to true. Generally you will not be using an SSL URL to use TLS... +ldap.demo.tls = false + +#optional, if using sasl +#ldap.personLdap.saslAuthorizationId = +#ldap.personLdap.saslRealm = + +#optional (note, time limit is for search operations, timeout is for connection timeouts), +#most of these default to vt-ldap defaults. times are in millis +#validateOnCheckout defaults to true if all other validate methods are false +#ldap.personLdap.batchSize = +#ldap.personLdap.countLimit = +#ldap.personLdap.timeLimit = +#ldap.personLdap.timeout = +#ldap.personLdap.minPoolSize = +#ldap.personLdap.maxPoolSize = +#ldap.personLdap.validateOnCheckIn = +#ldap.personLdap.validateOnCheckOut = +#ldap.personLdap.validatePeriodically = +#ldap.personLdap.validateTimerPeriod = +#ldap.personLdap.pruneTimerPeriod = +#if connections expire after a certain amount of time, this is it, in millis, defaults to 300000 (5 minutes) +#ldap.personLdap.expirationTime = + +#make the paths fully qualified and not relative to the loader group. +loader.ldap.requireTopStemAsStemFromConfigGroup=false diff --git a/ex201/ex201.2.1/container_files/seed-data/bootstrap.gsh b/ex201/ex201.2.1/container_files/seed-data/bootstrap.gsh new file mode 100644 index 0000000..09c2f80 --- /dev/null +++ b/ex201/ex201.2.1/container_files/seed-data/bootstrap.gsh @@ -0,0 +1,9 @@ + +gs = GrouperSession.startRootSession() + +addStem("app", "vpn", "vpn") +addGroup("app:vpn", "vpn_authorized", "vpn_authorized") +addGroup("app:vpn", "vpn_allow", "vpn_allow") +addGroup("app:vpn", "vpn_deny", "vpn_deny") + +addComposite("app:vpn:vpn_authorized", CompositeType.COMPLEMENT, "app:vpn:vpn_allow", "app:vpn:vpn_deny") \ No newline at end of file diff --git a/ex201/ex201.2.1/container_files/seed-data/sisData.sql b/ex201/ex201.2.1/container_files/seed-data/sisData.sql new file mode 100644 index 0000000..e69de29 diff --git a/ex201/ex201.2.1/container_files/seed-data/users.ldif b/ex201/ex201.2.1/container_files/seed-data/users.ldif new file mode 100644 index 0000000..e69de29 diff --git a/ex201/ex201.2.1/container_files/subject.properties b/ex201/ex201.2.1/container_files/subject.properties new file mode 100644 index 0000000..b55a10a --- /dev/null +++ b/ex201/ex201.2.1/container_files/subject.properties @@ -0,0 +1,76 @@ +subjectApi.source.ldap.id = ldap +subjectApi.source.ldap.name = EDU Ldap +subjectApi.source.ldap.types = person +subjectApi.source.ldap.adapterClass = edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter +subjectApi.source.ldap.param.ldapServerId.value = demo +subjectApi.source.ldap.param.SubjectID_AttributeType.value = uid +subjectApi.source.ldap.param.SubjectID_formatToLowerCase.value = false +subjectApi.source.ldap.param.Name_AttributeType.value = cn +subjectApi.source.ldap.param.Description_AttributeType.value = cn +subjectApi.source.ldap.param.VTLDAP_VALIDATOR.value = ConnectLdapValidator + +subjectApi.source.ldap.param.SubjectID_AttributeType.value = uid +subjectApi.source.ldap.param.SubjectID_formatToLowerCase.value = false +subjectApi.source.ldap.param.Name_AttributeType.value = displayName +subjectApi.source.ldap.param.Description_AttributeType.value = displayName +subjectApi.source.ldap.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('uid'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('cn'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('exampleEduRegId'), "")} +subjectApi.source.ldap.param.sortAttribute0.value = cn +subjectApi.source.ldap.param.searchAttribute0.value = searchAttribute0 +subjectApi.source.ldap.param.subjectVirtualAttribute_0_searchAttribute0.value = ${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('uid'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('cn'), "")},${subjectUtils.defaultIfBlank(subject.getAttributeValueOrCommaSeparated('employeeNumber'), "")} +subjectApi.source.ldap.param.subjectVirtualAttribute_1_displayName.value = ${subject.getAttributeValueOrCommaSeparated('cn') + ' (' + subject.getAttributeValueOrCommaSeparated('uid') + ', ' + subject.getAttributeValueOrCommaSeparated('title') + ')'} + +# 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.ldap.param.subjectIdentifierAttribute0.value = employeeNumber + +#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. +subjectApi.source.ldap.search.searchSubject.param.filter.value = (&(uid=%TERM%)(objectclass=person)) +subjectApi.source.ldap.search.searchSubject.param.scope.value = SUBTREE_SCOPE +subjectApi.source.ldap.search.searchSubject.param.base.value = ou=people,dc=internet2,dc=edu + +#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. +subjectApi.source.ldap.search.searchSubjectByIdentifier.param.filter.value = (&(employeeNumber=%TERM%)(objectclass=person)) +subjectApi.source.ldap.search.searchSubjectByIdentifier.param.scope.value = SUBTREE_SCOPE +subjectApi.source.ldap.search.searchSubjectByIdentifier.param.base.value = ou=people,dc=internet2,dc=edu + +# search: find subjects by free form search. Returns multiple results. + +subjectApi.source.ldap.search.search.param.filter.value = (&(|(|(uid=%TERM%)(cn=*%TERM%*))(uid=%TERM%*))(objectclass=person)) +subjectApi.source.ldap.search.search.param.scope.value = SUBTREE_SCOPE +subjectApi.source.ldap.search.search.param.base.value = ou=people,dc=internet2,dc=edu + +subjectApi.source.ldap.attributes = givenName, sn, cn, uid, mail, employeeNumber, title +subjectApi.source.ldap.internalAttributes = searchAttribute0 diff --git a/ex201/ex201.2.end/Dockerfile b/ex201/ex201.2.end/Dockerfile new file mode 100644 index 0000000..efb88df --- /dev/null +++ b/ex201/ex201.2.end/Dockerfile @@ -0,0 +1,24 @@ +FROM tier/grouper-training-env:ex201.2.1 + +LABEL author="tier-packaging@internet2.edu " \ + Vendor="TIER" \ + ImageType="Grouper Training" \ + ImageName=$imagename \ + ImageOS=centos7 + +ENV USERTOKEN=ex201.2.end + +COPY container_files/seed-data/ /seed-data/ + +RUN (/usr/sbin/slapd -h "ldap:/// ldaps:/// ldapi:///" -u ldap &) \ + && while ! curl -s ldap://localhost:389 > /dev/null; do echo waiting for ldap to start; sleep 1; done; \ + (mysqld_safe & ) \ + && while ! curl -s localhost:3306 > /dev/null; do echo waiting for mysqld to start; sleep 3; done; \ + cd /opt/grouper/grouper.apiBinary \ + && ldapadd -x -D cn=root,dc=internet2,dc=edu -w password -f /seed-data/users.ldif \ + && mysql grouper < /seed-data/sisData.sql \ + && bin/gsh /seed-data/bootstrap.gsh \ + && pkill -HUP slapd \ + && while curl -s ldap://localhost:389 > /dev/null; do echo waiting for ldap to stop; sleep 1; done; \ + pkill -u mysql mysqld \ + && while curl -s localhost:3306 > /dev/null; do echo waiting for mysqld to stop; sleep 1; done diff --git a/ex201/ex201.2.end/container_files/seed-data/bootstrap.gsh b/ex201/ex201.2.end/container_files/seed-data/bootstrap.gsh new file mode 100644 index 0000000..e69de29 diff --git a/ex201/ex201.2.end/container_files/seed-data/sisData.sql b/ex201/ex201.2.end/container_files/seed-data/sisData.sql new file mode 100644 index 0000000..e69de29 diff --git a/ex201/ex201.2.end/container_files/seed-data/users.ldif b/ex201/ex201.2.end/container_files/seed-data/users.ldif new file mode 100644 index 0000000..e69de29