Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Poll official firecloud google groups for admins DSDEEPB-1388
Firecloud is containting their official list of admins in google groups for each environment. If such a group is defined in config, poll for it's members, and synchronize our admin-user statuses with this list
- Loading branch information
bradtaylor
committed
Nov 13, 2015
1 parent
21f6c42
commit 5fab89d
Showing
11 changed files
with
243 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
.../org/broadinstitute/dsde/agora/server/dataaccess/permissions/AdminPermissionsClient.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package org.broadinstitute.dsde.agora.server.dataaccess.permissions | ||
|
||
import org.broadinstitute.dsde.agora.server.model.AgoraEntity | ||
|
||
object AdminPermissionsClient extends PermissionsClient { | ||
|
||
def listAdminUsers = listAdmins | ||
|
||
def alias(entity: AgoraEntity) = | ||
entity.namespace.get + "." + entity.name.get + "." + entity.snapshotId.get | ||
} |
60 changes: 60 additions & 0 deletions
60
...main/scala/org/broadinstitute/dsde/agora/server/dataaccess/permissions/AdminSweeper.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package org.broadinstitute.dsde.agora.server.dataaccess.permissions | ||
|
||
import akka.actor.{Actor, Props} | ||
import org.broadinstitute.dsde.agora.server.AgoraConfig | ||
import org.broadinstitute.dsde.agora.server.webservice.util.GoogleApiUtils | ||
import com.google.api.services.admin.directory.model.Member | ||
import scala.collection.JavaConversions._ | ||
|
||
object AdminSweeper { | ||
def props(pollFunction: () => List[String]): Props = Props(classOf[AdminSweeper], pollFunction) | ||
|
||
case class Sweep() | ||
|
||
/** | ||
* Function to poll for the member-emails of a config-defined google group. | ||
* Google group is assumed to contain an up-to-date list of admins as members. | ||
*/ | ||
val adminsGoogleGroupPoller: () => List[String] = { () => | ||
GoogleApiUtils.getGroupDirectory | ||
.members | ||
.list(AgoraConfig.adminGoogleGroup.get) | ||
.execute | ||
.getMembers | ||
.toList | ||
.map(_.getEmail) | ||
} | ||
} | ||
|
||
/** | ||
* Poll for an updated list of admins, and update our user table to reflect this list. | ||
* Intended to be run via a scheduler from the parent actor | ||
* TODO- Implement bulk transactions for better scalability. Currently runs a DB transaction for each user whose admin status needs changing. | ||
*/ | ||
class AdminSweeper(pollAdmins: () => List[String]) extends Actor { | ||
import AdminSweeper.Sweep | ||
def receive = { | ||
case Sweep => synchronizeAdmins | ||
} | ||
def synchronizeAdmins: Unit = { | ||
// get expected and observed admins lists | ||
val trueAdmins: List[String] = pollAdmins() | ||
val currentAdmins = AdminPermissionsClient.listAdminUsers | ||
|
||
// Difference the lists | ||
val newAdmins = trueAdmins.filterNot(currentAdmins.toSet) | ||
val adminsToDelete = currentAdmins.filterNot(trueAdmins.toSet) | ||
|
||
// Update our user table to reflect list differences | ||
for (newAdmin <- newAdmins) { | ||
println(newAdmin) | ||
AdminPermissionsClient.updateAdmin(newAdmin, true) | ||
} | ||
|
||
for (adminToDelete <- adminsToDelete) { | ||
AdminPermissionsClient.updateAdmin(adminToDelete, false) | ||
} | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
src/main/scala/org/broadinstitute/dsde/agora/server/webservice/util/GoogleApiUtils.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.broadinstitute.dsde.agora.server.webservice.util | ||
|
||
import java.io.File | ||
import java.util.Collections | ||
|
||
import com.google.api.client.auth.oauth2.Credential | ||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential | ||
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport | ||
import com.google.api.client.json.jackson2.JacksonFactory | ||
import com.google.api.services.admin.directory.{DirectoryScopes, Directory} | ||
import org.broadinstitute.dsde.agora.server.AgoraConfig | ||
|
||
import scala.concurrent.duration._ | ||
|
||
object GoogleApiUtils { | ||
val emailAddress = AgoraConfig.gcsServiceAccountEmail | ||
val JSON_FACTORY = JacksonFactory.getDefaultInstance | ||
val httpTransport = GoogleNetHttpTransport.newTrustedTransport | ||
val directoryScopes = Collections.singleton(DirectoryScopes.ADMIN_DIRECTORY_GROUP) | ||
|
||
private def getGroupServiceAccountCredential: Credential = { | ||
new GoogleCredential.Builder() | ||
.setTransport(httpTransport) | ||
.setJsonFactory(JSON_FACTORY) | ||
.setServiceAccountId(emailAddress) | ||
.setServiceAccountScopes(directoryScopes) | ||
.setServiceAccountUser(AgoraConfig.gcsUserEmail) | ||
.setServiceAccountPrivateKeyFromP12File(new File(AgoraConfig.gcsServiceAccountP12KeyFile)) | ||
.build() | ||
} | ||
|
||
def getGroupDirectory = { | ||
new Directory.Builder(httpTransport, JSON_FACTORY, getGroupServiceAccountCredential).setApplicationName("firecloud:agora").build() | ||
} | ||
} |
38 changes: 0 additions & 38 deletions
38
.../scala/org/broadinstitute/dsde/agora/server/webservice/util/GoogleCredentialHandler.scala
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
.../scala/org/broadinstitute/dsde/agora/server/dataaccess/permissions/AdminSweeperSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package org.broadinstitute.dsde.agora.server.dataaccess.permissions | ||
|
||
import akka.actor.ActorSystem | ||
import akka.testkit.{ImplicitSender, TestKit, TestActorRef} | ||
import org.broadinstitute.dsde.agora.server.dataaccess.permissions.AdminSweeper.Sweep | ||
import org.broadinstitute.dsde.agora.server.{AgoraTestData, AgoraTestFixture} | ||
import org.scalatest.{DoNotDiscover, WordSpecLike, Matchers, BeforeAndAfterAll} | ||
import scala.concurrent.duration._ | ||
|
||
object AdminSweeperSpec { | ||
def getMockAdminsList:() => List[String] = { () => | ||
List("fake@broadinstitute.org", AgoraTestData.owner1.get, AgoraTestData.owner2.get) | ||
} | ||
} | ||
|
||
@DoNotDiscover | ||
class AdminSweeperSpec(_system: ActorSystem) extends TestKit(_system) with WordSpecLike with Matchers with BeforeAndAfterAll with AgoraTestFixture with ImplicitSender { | ||
|
||
override protected def beforeAll() = { | ||
ensureDatabasesAreRunning() | ||
} | ||
|
||
override protected def afterAll() = { | ||
clearDatabases() | ||
} | ||
|
||
"Agora" should { | ||
"be able to synchronize it's list of admins via the AdminSweeper" in { | ||
addAdminUser() | ||
|
||
val adminSweeper = TestActorRef(AdminSweeper.props(AdminSweeperSpec.getMockAdminsList)) | ||
within(30 seconds) { | ||
adminSweeper ! Sweep | ||
awaitAssert(AdminPermissionsClient.listAdminUsers === AdminSweeperSpec.getMockAdminsList) | ||
} | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters