Grouper will soon be able to sync a folder of groups with groups at box.com
Why use this?
You might want to share resources at box with departments or other groups in Grouper
Architecture
Box groups must be directly in a designated folder
The box API WS has the power to do a lot, so your box support team might want to run that on their servers, not the central grouper machines.
Only MEMBER roles are managed in box, not ADMIN roles (note, you dont need ADMIN roles in box)
The Grouper box process is a handful of jars including the grouper client which runs as a unix process
Notes
If you grant a person to be a Box group admin, they can edit users too, generally this is not a good idea, but this integration protects you from that.
If you provision users just in time, you might want to run a SAML attribute assertion that puts people in groups just in time.
Setup integration (from README.txt)
Make a messaging queue, grant access to the box user (in this case keep it simple and use GrouperSystem, though you would make your own user and not user GrouperSystem
GrouperSession grouperSession = GrouperSession.startRootSession(); GrouperBuiltinMessagingSystem.createQueue("box_queue"); Subject subject = SubjectFinder.findById("GrouperSystem"); GrouperBuiltinMessagingSystem.allowSendToQueue("box_queue", subject); GrouperBuiltinMessagingSystem.allowReceiveFromQueue("box_queue", subject);
Configure a change log consumer to send messages to the box process in grouper-loader.properties
changeLog.consumer.boxEsb.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbConsumer changeLog.consumer.boxEsb.quartzCron = 0 * * * * ? changeLog.consumer.boxEsb.elfilter = event.groupName =~ '^box\\:groups\\:.*$' && (event.eventType eq 'GROUP_DELETE' || event.eventType eq 'GROUP_ADD' || event.eventType eq 'MEMBERSHIP_DELETE' || event.eventType eq 'MEMBERSHIP_ADD') changeLog.consumer.boxEsb.publisher.class = edu.internet2.middleware.grouper.changeLog.esb.consumer.EsbMessagingPublisher changeLog.consumer.boxEsb.publisher.messagingSystemName = grouperBuiltinMessaging # queue or topic changeLog.consumer.boxEsb.publisher.messageQueueType = queue changeLog.consumer.boxEsb.publisher.queueOrTopicName = box_queue
Test with add a member GSH script
GrouperSession grouperSession = GrouperSession.startRootSession(); Group group = new GroupSave(grouperSession).assignName("box:groups:someGroup").save(); Subject subject = SubjectFinder.findById("GrouperSystem"); group.addMember(subject, false); GrouperLoader.runOnceByJobName(grouperSession, "CHANGE_LOG_changeLogTempToChangeLog"); GrouperLoader.runOnceByJobName(grouperSession, "CHANGE_LOG_consumer_boxEsb");
Test with delete a member GSH script
GrouperSession grouperSession = GrouperSession.startRootSession(); Group group = new GroupSave(grouperSession).assignName("box:groups:someGroup").save(); Subject subject = SubjectFinder.findById("GrouperSystem"); group.deleteMember(subject, false); GrouperLoader.runOnceByJobName(grouperSession, "CHANGE_LOG_changeLogTempToChangeLog"); GrouperLoader.runOnceByJobName(grouperSession, "CHANGE_LOG_consumer_boxEsb");
Setup box authn token (public key web service security)
https://docs.box.com/docs/getting-started-box-platform Chriss-MacBook-Air:box mchyzer$ openssl genrsa -aes256 -out private_key.pem 2048 Chriss-MacBook-Air:box mchyzer$ openssl rsa -pubout -in private_key.pem -out public_key.pem sign up for two step authn in box if not SSO make application in box: https://app.box.com/developers/services 1. authentication type: server 2. user access: all users 3. scopes: manage users, manage app users, manage groups 4. advanced features: none 5. note client_id 6. note client_secret 7. redirect uri: https://localhost 8. under apps in admin console copy the API key from the app page ad paste in
Configure
grouper.client.properties
# these are properties to add to grouperClient.properties # put groups in here which go to box, the name in box will be the extension here grouperBox.folder.name.withBoxGroups = a:b:c # put the comma separated list of sources to send to box grouperBox.sourcesForSubjects = someSource # either have id for subject id or an attribute for the box username (e.g. netId) grouperBox.subjectAttributeForBoxUsername = id # is grouper the true system of record, delete box groups which dont exist in grouper grouperBox.deleteGroupsInBoxWhichArentInGrouper = true #the quartz cron is a cron-like string. # http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger grouperBox.fullSync.quartzCron = 0 0 5 * * ? # authentication settings for WS grouperBox.privateKeyFileName = grouperBox.privateKeyPass = grouperBox.publicKeyId = grouperBox.enterpriseId = grouperBox.clientId = grouperBox.clientSecret = # if using include/exclude in grouper then exclude these groups in box grouperBox.ignoreGroupSuffixes = _systemOfRecord, _includes, _excludes, _systemOfRecordAndIncludes, _includesMinusExcludes # if there is a suffix... grouperBox.subjectIdSuffix = @upenn.edu # if require... grouperBox.requireGroupInGrouper = community:active # if delete groups which arent in grouper (will lose permissions if assigned) grouperBox.deleteGroupsInBoxWhichArentInGrouper = false # remove memberships in box in groups which arent in grouper # note if not all groups in box are managed in grouper, this should be false grouperBox.removeMembershipsInBoxWhenGroupsArentInGrouper = true # delete groups incremental when groups removed in grouper grouperBox.deleteGroupWhenGroupDeletedInGrouper = false
Install
This runs in the loader. Get the grouper-misc/grouper-duo project. Build (or download 2.1.5, 2.2.2) the jar for the grouper duo source. Add in the duo client jars (4 of them). Configure the grouper-loader.properties. Note, the Duo client runs in Java7+.