diff --git a/apps/shrine-app/src/main/scala/net/shrine/status/StatusJaxrs.scala b/apps/shrine-app/src/main/scala/net/shrine/status/StatusJaxrs.scala index fb47cd039..8c04a6cdb 100644 --- a/apps/shrine-app/src/main/scala/net/shrine/status/StatusJaxrs.scala +++ b/apps/shrine-app/src/main/scala/net/shrine/status/StatusJaxrs.scala @@ -1,82 +1,84 @@ package net.shrine.status import javax.ws.rs.{WebApplicationException, GET, Path, Produces} import javax.ws.rs.core.{Response, MediaType} import com.sun.jersey.spi.container.{ContainerRequest, ContainerRequestFilter} import com.typesafe.config.{Config => TsConfig} import org.json4s.{DefaultFormats, Formats} import org.json4s.native.Serialization import net.shrine.log.Loggable import scala.collection.JavaConverters._ import scala.collection.immutable.{Map,Set} import net.shrine.config.ConfigExtensions /** * A subservice that shares internal state of the shrine servlet. * * @author david * @since 12/2/15 */ @Path("/status") @Produces(Array(MediaType.APPLICATION_JSON)) case class StatusJaxrs(shrineConfig:TsConfig) extends Loggable { implicit def json4sFormats: Formats = DefaultFormats @GET @Path("version") def version: String = { val version = Version("changeMe") val versionString = Serialization.write(version) versionString } @GET @Path("config") def config: String = { //todo probably better to reach out and grab the config from ManuallyWiredShrineJaxrsResources once it is a singleton Serialization.write(Json4sConfig(shrineConfig)) } } case class Version(version:String) //todo SortedMap case class Json4sConfig(keyValues:Map[String,String]){ } object Json4sConfig{ def isPassword(key:String):Boolean = { if(key.toLowerCase.contains("password")) true else false } def apply(config:TsConfig):Json4sConfig = { val entries: Set[(String, String)] = config.entrySet.asScala.to[Set].map(x => (x.getKey,x.getValue.render())).filterNot(x => isPassword(x._1)) val sortedMap: Map[String, String] = entries.toMap Json4sConfig(sortedMap) } } class PermittedHostOnly(shrineConfig:TsConfig) extends ContainerRequestFilter { //todo generalize for happy, too //todo for tomcat 8 see https://jersey.java.net/documentation/latest/filters-and-interceptors.html for a cleaner version //code from http://stackoverflow.com/questions/17143514/how-to-add-custom-response-and-abort-request-in-jersey-1-11-filters + + //how to apply in http://stackoverflow.com/questions/4358213/how-does-one-intercept-a-request-during-the-jersey-lifecycle override def filter(requestContext: ContainerRequest): ContainerRequest = { val hostOfOrigin = requestContext.getBaseUri.getHost val permittedHostOfOrigin:String = shrineConfig.getOption("shrine.status.permittedHostOfOrigin",_.getString).getOrElse(java.net.InetAddress.getLocalHost.getHostName) if(hostOfOrigin == permittedHostOfOrigin) requestContext else { val response = Response.status(Response.Status.UNAUTHORIZED).entity(s"Only available from $permittedHostOfOrigin").build() throw new WebApplicationException(response) } } } \ No newline at end of file diff --git a/apps/shrine-app/src/main/scala/net/shrine/wiring/AuthStrategy.scala b/apps/shrine-app/src/main/scala/net/shrine/wiring/AuthStrategy.scala index 243b7764d..8732444a6 100644 --- a/apps/shrine-app/src/main/scala/net/shrine/wiring/AuthStrategy.scala +++ b/apps/shrine-app/src/main/scala/net/shrine/wiring/AuthStrategy.scala @@ -1,84 +1,77 @@ package net.shrine.wiring import net.shrine.authorization.steward.StewardConfig import net.shrine.config.Keys import net.shrine.authentication.{AuthenticationType, Authenticator, PmAuthenticator} import net.shrine.authorization.{AuthorizationType, StewardQueryAuthorizationService, QueryAuthorizationService, AllowsAllAuthorizationService} import net.shrine.service.AllowsAllAuthenticator import net.shrine.client.Poster import net.shrine.hms.authorization.HmsDataStewardAuthorizationService import net.shrine.hms.authentication.EcommonsPmAuthenticator import net.shrine.hms.authorization.JerseySheriffClient /** - * @author clint - * @since Jul 1, 2014 - */ -trait AuthStrategy { - def determineAuthenticator(authType: AuthenticationType, pmPoster: Poster): Authenticator + * @author clint + * @since Jul 1, 2014 + */ +object AuthStrategy { - def determineQueryAuthorizationService(authType: AuthorizationType, shrineConfig: ShrineConfig, authenticator: Authenticator): QueryAuthorizationService -} + import AuthenticationType._ + import AuthorizationType._ -object AuthStrategy { - object Default extends AuthStrategy { - import AuthenticationType._ - import AuthorizationType._ - - override def determineAuthenticator(authType: AuthenticationType, pmPoster: Poster): Authenticator = authType match { - case NoAuthentication => AllowsAllAuthenticator - case Pm => PmAuthenticator(pmPoster) - case Ecommons => EcommonsPmAuthenticator(pmPoster) - case _ => throw new Exception(s"Disallowed authentication type '$authType'") - } + def determineAuthenticator(authType: AuthenticationType, pmPoster: Poster): Authenticator = authType match { + case NoAuthentication => AllowsAllAuthenticator + case Pm => PmAuthenticator(pmPoster) + case Ecommons => EcommonsPmAuthenticator(pmPoster) + case _ => throw new Exception(s"Disallowed authentication type '$authType'") + } - override def determineQueryAuthorizationService(authType: AuthorizationType, shrineConfig: ShrineConfig, authenticator: Authenticator): QueryAuthorizationService = { - authType match { - case ShrineSteward => makeShrineStewardAuthorizationService(shrineConfig) - case HmsSteward => makeHmsStewardAuthorizationService(shrineConfig, authenticator) - case NoAuthorization => AllowsAllAuthorizationService - case _ => throw new Exception(s"Disallowed authorization type '$authType'") - } + def determineQueryAuthorizationService(authType: AuthorizationType, shrineConfig: ShrineConfig, authenticator: Authenticator): QueryAuthorizationService = { + authType match { + case ShrineSteward => makeShrineStewardAuthorizationService(shrineConfig) + case HmsSteward => makeHmsStewardAuthorizationService(shrineConfig, authenticator) + case NoAuthorization => AllowsAllAuthorizationService + case _ => throw new Exception(s"Disallowed authorization type '$authType'") } + } - private def makeShrineStewardAuthorizationService(shrineConfig: ShrineConfig): QueryAuthorizationService = { - require(shrineConfig.queryEntryPointConfig.isDefined, s"${Keys.queryEntryPoint} section must be defined in shrine.conf") - val queryEntryPointConfig = shrineConfig.queryEntryPointConfig.get + private def makeShrineStewardAuthorizationService(shrineConfig: ShrineConfig): QueryAuthorizationService = { + require(shrineConfig.queryEntryPointConfig.isDefined, s"${Keys.queryEntryPoint} section must be defined in shrine.conf") + val queryEntryPointConfig = shrineConfig.queryEntryPointConfig.get - require(queryEntryPointConfig.stewardConfig.isDefined, s"${Keys.queryEntryPoint}.shrineSteward section must be defined in shrine.conf") - val stewardConfig: StewardConfig = queryEntryPointConfig.stewardConfig.get + require(queryEntryPointConfig.stewardConfig.isDefined, s"${Keys.queryEntryPoint}.shrineSteward section must be defined in shrine.conf") + val stewardConfig: StewardConfig = queryEntryPointConfig.stewardConfig.get - StewardQueryAuthorizationService( - qepUserName = stewardConfig.qepUserName, - qepPassword = stewardConfig.qepPassword, - stewardBaseUrl = stewardConfig.stewardBaseUrl) - } + StewardQueryAuthorizationService( + qepUserName = stewardConfig.qepUserName, + qepPassword = stewardConfig.qepPassword, + stewardBaseUrl = stewardConfig.stewardBaseUrl) + } - private def makeHmsStewardAuthorizationService(shrineConfig: ShrineConfig, authenticator: => Authenticator): QueryAuthorizationService = { - //NB: Fail fast here, since on the fully-meshed HMS deployment, all nodes are expected to be - //query entry points - require(shrineConfig.queryEntryPointConfig.isDefined, s"${Keys.queryEntryPoint} section must be defined in shrine.conf") + private def makeHmsStewardAuthorizationService(shrineConfig: ShrineConfig, authenticator: => Authenticator): QueryAuthorizationService = { + //NB: Fail fast here, since on the fully-meshed HMS deployment, all nodes are expected to be + //query entry points + require(shrineConfig.queryEntryPointConfig.isDefined, s"${Keys.queryEntryPoint} section must be defined in shrine.conf") - val queryEntryPointConfig = shrineConfig.queryEntryPointConfig.get + val queryEntryPointConfig = shrineConfig.queryEntryPointConfig.get - val sheriffEndpointOption = queryEntryPointConfig.sheriffEndpoint - val sheriffCredentialsOption = queryEntryPointConfig.sheriffCredentials + val sheriffEndpointOption = queryEntryPointConfig.sheriffEndpoint + val sheriffCredentialsOption = queryEntryPointConfig.sheriffCredentials - //NB: Fail fast, HMS nodes need to use The Sheriff - require(sheriffEndpointOption.isDefined, "Sheriff endpoint must be defined in shrine.conf") - //NB: Fail fast, HMS nodes need to use The Sheriff - require(sheriffCredentialsOption.isDefined, "Sheriff credentials must be defined in shrine.conf") + //NB: Fail fast, HMS nodes need to use The Sheriff + require(sheriffEndpointOption.isDefined, "Sheriff endpoint must be defined in shrine.conf") + //NB: Fail fast, HMS nodes need to use The Sheriff + require(sheriffCredentialsOption.isDefined, "Sheriff credentials must be defined in shrine.conf") - val sheriffUrl = sheriffEndpointOption.get.url.toString + val sheriffUrl = sheriffEndpointOption.get.url.toString - val sheriffUsername = sheriffCredentialsOption.get.username - val sheriffPassword = sheriffCredentialsOption.get.password + val sheriffUsername = sheriffCredentialsOption.get.username + val sheriffPassword = sheriffCredentialsOption.get.password - val sheriffClient = JerseySheriffClient(sheriffUrl, sheriffUsername, sheriffPassword) + val sheriffClient = JerseySheriffClient(sheriffUrl, sheriffUsername, sheriffPassword) - HmsDataStewardAuthorizationService(sheriffClient, authenticator) - } + HmsDataStewardAuthorizationService(sheriffClient, authenticator) } } \ No newline at end of file diff --git a/apps/shrine-app/src/main/scala/net/shrine/wiring/ManuallyWiredShrineJaxrsResources.scala b/apps/shrine-app/src/main/scala/net/shrine/wiring/ManuallyWiredShrineJaxrsResources.scala index 89c39a04f..8319ebd44 100644 --- a/apps/shrine-app/src/main/scala/net/shrine/wiring/ManuallyWiredShrineJaxrsResources.scala +++ b/apps/shrine-app/src/main/scala/net/shrine/wiring/ManuallyWiredShrineJaxrsResources.scala @@ -1,384 +1,347 @@ package net.shrine.wiring +import javax.sql.DataSource + import com.typesafe.config.{Config, ConfigFactory} -import net.shrine.adapter.Adapter -import net.shrine.adapter.AdapterMap -import net.shrine.adapter.DeleteQueryAdapter -import net.shrine.adapter.FlagQueryAdapter -import net.shrine.adapter.ReadInstanceResultsAdapter -import net.shrine.adapter.ReadPreviousQueriesAdapter -import net.shrine.adapter.ReadQueryDefinitionAdapter -import net.shrine.adapter.ReadQueryResultAdapter -import net.shrine.adapter.ReadTranslatedQueryDefinitionAdapter -import net.shrine.adapter.RenameQueryAdapter -import net.shrine.adapter.RunQueryAdapter -import net.shrine.adapter.UnFlagQueryAdapter -import net.shrine.adapter.dao.AdapterDao -import net.shrine.adapter.dao.I2b2AdminDao -import net.shrine.adapter.dao.squeryl.SquerylAdapterDao -import net.shrine.adapter.dao.squeryl.SquerylI2b2AdminDao +import net.shrine.adapter.{Adapter, AdapterMap, DeleteQueryAdapter, FlagQueryAdapter, ReadInstanceResultsAdapter, ReadPreviousQueriesAdapter, ReadQueryDefinitionAdapter, ReadQueryResultAdapter, ReadTranslatedQueryDefinitionAdapter, RenameQueryAdapter, RunQueryAdapter, UnFlagQueryAdapter} +import net.shrine.adapter.dao.{AdapterDao, I2b2AdminDao} +import net.shrine.adapter.dao.squeryl.{SquerylAdapterDao, SquerylI2b2AdminDao} import net.shrine.adapter.dao.squeryl.tables.{Tables => AdapterTables} -import net.shrine.adapter.service.AdapterRequestHandler -import net.shrine.adapter.service.AdapterResource -import net.shrine.adapter.service.AdapterService -import net.shrine.adapter.service.I2b2AdminResource -import net.shrine.adapter.service.I2b2AdminService -import net.shrine.adapter.translators.ExpressionTranslator -import net.shrine.adapter.translators.QueryDefinitionTranslator +import net.shrine.adapter.service.{AdapterRequestHandler, AdapterResource, AdapterService, I2b2AdminResource, I2b2AdminService} +import net.shrine.adapter.translators.{ExpressionTranslator, QueryDefinitionTranslator} import net.shrine.authentication.Authenticator import net.shrine.authorization.QueryAuthorizationService -import net.shrine.broadcaster.AdapterClientBroadcaster -import net.shrine.broadcaster.BroadcastAndAggregationService -import net.shrine.broadcaster.BroadcasterClient -import net.shrine.broadcaster.InJvmBroadcasterClient -import net.shrine.broadcaster.NodeHandle -import net.shrine.broadcaster.PosterBroadcasterClient -import net.shrine.broadcaster.SigningBroadcastAndAggregationService +import net.shrine.broadcaster.{AdapterClientBroadcaster, BroadcastAndAggregationService, BroadcasterClient, InJvmBroadcasterClient, NodeHandle, PosterBroadcasterClient, SigningBroadcastAndAggregationService} +import net.shrine.broadcaster.dao.HubDao +import net.shrine.broadcaster.dao.squeryl.SquerylHubDao +import net.shrine.broadcaster.service.{BroadcasterMultiplexerResource, BroadcasterMultiplexerService} +import net.shrine.client.{EndpointConfig, HttpClient, JerseyHttpClient, OntClient, Poster, PosterOntClient} +import net.shrine.config.mappings.{AdapterMappings, AdapterMappingsSource, ClasspathFormatDetectingAdapterMappingsSource} +import net.shrine.crypto.{DefaultSignerVerifier, KeyStoreCertCollection, TrustParam} +import net.shrine.dao.squeryl.{DataSourceSquerylInitializer, SquerylDbAdapterSelecter, SquerylInitializer} +import net.shrine.happy.{HappyShrineResource, HappyShrineService} import net.shrine.log.Loggable +import net.shrine.ont.data.{OntClientOntologyMetadata, OntologyMetadata} +import net.shrine.protocol.{NodeId, RequestType, ResultOutputType} +import net.shrine.service.{I2b2BroadcastResource, I2b2BroadcastService, ShrineResource, ShrineService} import net.shrine.service.dao.AuditDao import net.shrine.service.dao.squeryl.SquerylAuditDao import net.shrine.service.dao.squeryl.tables.{Tables => HubTables} -import net.shrine.broadcaster.service.BroadcasterMultiplexerResource -import net.shrine.broadcaster.service.BroadcasterMultiplexerService -import net.shrine.client.{EndpointConfig, HttpClient, JerseyHttpClient, OntClient, Poster, PosterOntClient} -import net.shrine.config.mappings.AdapterMappings -import net.shrine.config.mappings.AdapterMappingsSource -import net.shrine.config.mappings.ClasspathFormatDetectingAdapterMappingsSource -import net.shrine.crypto.DefaultSignerVerifier -import net.shrine.crypto.KeyStoreCertCollection -import net.shrine.dao.squeryl.DataSourceSquerylInitializer -import net.shrine.dao.squeryl.SquerylDbAdapterSelecter -import net.shrine.ont.data.OntClientOntologyMetadata -import net.shrine.protocol.NodeId -import net.shrine.protocol.RequestType -import net.shrine.protocol.ResultOutputType -import net.shrine.happy.HappyShrineResource -import net.shrine.happy.HappyShrineService -import net.shrine.service.I2b2BroadcastResource -import net.shrine.service.I2b2BroadcastService -import net.shrine.service.ShrineResource -import net.shrine.service.ShrineService -import net.shrine.crypto.TrustParam -import javax.sql.DataSource import net.shrine.status.StatusJaxrs import org.squeryl.internals.DatabaseAdapter -import net.shrine.dao.squeryl.SquerylInitializer -import net.shrine.ont.data.OntologyMetadata -import net.shrine.broadcaster.dao.HubDao -import net.shrine.broadcaster.dao.squeryl.SquerylHubDao /** * @author clint * @since Jan 14, 2014 * * Application wiring for Shrine, in the base, non-HMS case. All vals are protecetd, so they may be accessed, * in subclasses without ballooning this class's public API, and lazy, to work around init-order surprises when * overriding vals declared inline. See * * https://stackoverflow.com/questions/15762650/scala-override-val-in-class-inheritance * * among other links mentioning val overrides, early initializers, etc. -Clint */ -class ManuallyWiredShrineJaxrsResources(authStrategy: AuthStrategy = AuthStrategy.Default) extends ShrineJaxrsResources with Loggable { +class ManuallyWiredShrineJaxrsResources() extends ShrineJaxrsResources with Loggable { import ManuallyWiredShrineJaxrsResources._ import NodeHandleSource.makeNodeHandles override def resources: Iterable[AnyRef] = { Seq(happyResource,statusJaxrs) ++ shrineResource ++ i2b2BroadcastResource ++ adapterResource ++ i2b2AdminResource ++ broadcasterMultiplexerResource } //Load config from file on the classpath called "shrine.conf" protected lazy val config: Config = ConfigFactory.load("shrine") protected lazy val shrineConfig: ShrineConfig = ShrineConfig(config) protected lazy val nodeId: NodeId = NodeId(shrineConfig.humanReadableNodeName) //TODO: Don't assume keystore lives on the filesystem, could come from classpath, etc protected lazy val shrineCertCollection: KeyStoreCertCollection = KeyStoreCertCollection.fromFile(shrineConfig.keystoreDescriptor) protected lazy val keystoreTrustParam: TrustParam = TrustParam.SomeKeyStore(shrineCertCollection) protected lazy val signerVerifier: DefaultSignerVerifier = new DefaultSignerVerifier(shrineCertCollection) protected lazy val dataSource: DataSource = Jndi("java:comp/env/jdbc/shrineDB").get protected lazy val squerylAdapter: DatabaseAdapter = SquerylDbAdapterSelecter.determineAdapter(shrineConfig.shrineDatabaseType) protected lazy val squerylInitializer: SquerylInitializer = new DataSourceSquerylInitializer(dataSource, squerylAdapter) private def makePoster = poster(shrineCertCollection) _ private lazy val pmEndpoint: EndpointConfig = shrineConfig.pmEndpoint private lazy val ontEndpoint: EndpointConfig = shrineConfig.ontEndpoint protected lazy val pmPoster: Poster = makePoster(pmEndpoint) protected lazy val ontPoster: Poster = makePoster(ontEndpoint) protected lazy val breakdownTypes: Set[ResultOutputType] = shrineConfig.breakdownResultOutputTypes protected lazy val hubDao: HubDao = new SquerylHubDao(squerylInitializer, new net.shrine.broadcaster.dao.squeryl.tables.Tables) //todo move as much of this block as possible to the adapter project protected lazy val (adapterService, i2b2AdminService, adapterDao, adapterMappings) = adapterComponentsToTuple(shrineConfig.adapterConfig.map { adapterConfig => val crcEndpoint: EndpointConfig = adapterConfig.crcEndpoint val crcPoster: Poster = makePoster(crcEndpoint) val squerylAdapterTables: AdapterTables = new AdapterTables val adapterDao: AdapterDao = new SquerylAdapterDao(squerylInitializer, squerylAdapterTables)(breakdownTypes) //NB: Is i2b2HiveCredentials.projectId the right project id to use? val i2b2AdminDao: I2b2AdminDao = new SquerylI2b2AdminDao(shrineConfig.crcHiveCredentials.projectId, squerylInitializer, squerylAdapterTables) val adapterMappingsSource: AdapterMappingsSource = ClasspathFormatDetectingAdapterMappingsSource(adapterConfig.adapterMappingsFileName) //NB: Fail fast val adapterMappings: AdapterMappings = adapterMappingsSource.load.get val expressionTranslator: ExpressionTranslator = ExpressionTranslator(adapterMappings) val queryDefinitionTranslator: QueryDefinitionTranslator = new QueryDefinitionTranslator(expressionTranslator) val doObfuscation = adapterConfig.setSizeObfuscation val runQueryAdapter = new RunQueryAdapter( crcPoster, adapterDao, shrineConfig.crcHiveCredentials, queryDefinitionTranslator, adapterConfig.adapterLockoutAttemptsThreshold, doObfuscation, adapterConfig.immediatelyRunIncomingQueries, breakdownTypes, collectAdapterAudit = adapterConfig.collectAdapterAudit ) val readInstanceResultsAdapter: Adapter = new ReadInstanceResultsAdapter( crcPoster, shrineConfig.crcHiveCredentials, adapterDao, doObfuscation, breakdownTypes, collectAdapterAudit = adapterConfig.collectAdapterAudit ) val readQueryResultAdapter: Adapter = new ReadQueryResultAdapter( crcPoster, shrineConfig.crcHiveCredentials, adapterDao, doObfuscation, breakdownTypes, collectAdapterAudit = adapterConfig.collectAdapterAudit ) val readPreviousQueriesAdapter: Adapter = new ReadPreviousQueriesAdapter(adapterDao) val deleteQueryAdapter: Adapter = new DeleteQueryAdapter(adapterDao) val renameQueryAdapter: Adapter = new RenameQueryAdapter(adapterDao) val readQueryDefinitionAdapter: Adapter = new ReadQueryDefinitionAdapter(adapterDao) val readTranslatedQueryDefinitionAdapter: Adapter = new ReadTranslatedQueryDefinitionAdapter(nodeId, queryDefinitionTranslator) val flagQueryAdapter: Adapter = new FlagQueryAdapter(adapterDao) val unFlagQueryAdapter: Adapter = new UnFlagQueryAdapter(adapterDao) val adapterMap = AdapterMap(Map( RequestType.QueryDefinitionRequest -> runQueryAdapter, RequestType.GetRequestXml -> readQueryDefinitionAdapter, RequestType.UserRequest -> readPreviousQueriesAdapter, RequestType.InstanceRequest -> readInstanceResultsAdapter, RequestType.MasterDeleteRequest -> deleteQueryAdapter, RequestType.MasterRenameRequest -> renameQueryAdapter, RequestType.GetQueryResult -> readQueryResultAdapter, RequestType.ReadTranslatedQueryDefinitionRequest -> readTranslatedQueryDefinitionAdapter, RequestType.FlagQueryRequest -> flagQueryAdapter, RequestType.UnFlagQueryRequest -> unFlagQueryAdapter)) AdapterComponents( new AdapterService(nodeId, signerVerifier, adapterConfig.maxSignatureAge, adapterMap), new I2b2AdminService(adapterDao, i2b2AdminDao, pmPoster, runQueryAdapter), adapterDao, adapterMappings) }) private val localAdapterServiceOption: Option[AdapterRequestHandler] = shrineConfig.hubConfig.flatMap(hubConfig => makeAdapterServiceOption(hubConfig.shouldQuerySelf, adapterService)) private val broadcastDestinations: Option[Set[NodeHandle]] = shrineConfig.hubConfig.map(hubConfig => makeNodeHandles(keystoreTrustParam, hubConfig.maxQueryWaitTime, hubConfig.downstreamNodes, nodeId, localAdapterServiceOption, breakdownTypes)) protected lazy val (shrineService, i2b2Service, auditDao) = queryEntryPointComponentsToTuple(shrineConfig.queryEntryPointConfig.map { queryEntryPointConfig => val broadcasterClient: BroadcasterClient = { if(queryEntryPointConfig.broadcasterIsLocal) { //If broadcaster is local, we need a hub config //TODO: Enforce this when unmarshalling configs require(broadcastDestinations.isDefined, "Local broadcaster specified, but no downstream nodes defined") val broadcaster: AdapterClientBroadcaster = AdapterClientBroadcaster(broadcastDestinations.get, hubDao) InJvmBroadcasterClient(broadcaster) } else { //if broadcaster is remote, we need an endpoint //TODO: Enforce this when unmarshalling configs require(queryEntryPointConfig.broadcasterServiceEndpoint.isDefined, "Non-local broadcaster requested, but no URL for the remote broadcaster is specified") PosterBroadcasterClient(makePoster(queryEntryPointConfig.broadcasterServiceEndpoint.get), breakdownTypes) } } val commonName:String = shrineCertCollection.myCommonName.getOrElse{ val hostname = java.net.InetAddress.getLocalHost.getHostName warn(s"No common name available from ${shrineCertCollection.descriptor}. Using $hostname instead.") hostname } val broadcastService: BroadcastAndAggregationService = SigningBroadcastAndAggregationService(broadcasterClient, signerVerifier, queryEntryPointConfig.signingCertStrategy) val auditDao: AuditDao = new SquerylAuditDao(squerylInitializer, new HubTables) val authenticationType = queryEntryPointConfig.authenticationType val authorizationType = queryEntryPointConfig.authorizationType - val authenticator: Authenticator = authStrategy.determineAuthenticator(authenticationType, pmPoster) + val authenticator: Authenticator = AuthStrategy.determineAuthenticator(authenticationType, pmPoster) - val authorizationService: QueryAuthorizationService = authStrategy.determineQueryAuthorizationService(authorizationType, shrineConfig, authenticator) + val authorizationService: QueryAuthorizationService = AuthStrategy.determineQueryAuthorizationService(authorizationType, shrineConfig, authenticator) debug(s"authorizationService set to $authorizationService") QueryEntryPointComponents( ShrineService( commonName, auditDao, authenticator, authorizationService, queryEntryPointConfig.includeAggregateResults, broadcastService, queryEntryPointConfig.maxQueryWaitTime, breakdownTypes, queryEntryPointConfig.collectQepAudit ), I2b2BroadcastService( commonName, auditDao, authenticator, authorizationService, queryEntryPointConfig.includeAggregateResults, broadcastService, queryEntryPointConfig.maxQueryWaitTime, breakdownTypes, queryEntryPointConfig.collectQepAudit ), auditDao) }) private lazy val broadcasterOption = unpackHubComponents { for { hubConfig <- shrineConfig.hubConfig } yield { require(broadcastDestinations.isDefined, "This node is configured to be a hub, but no downstream nodes are defined") HubComponents(AdapterClientBroadcaster(broadcastDestinations.get, hubDao)) } } protected lazy val broadcasterMultiplexerService = { for { broadcaster <- broadcasterOption hubConfig <- shrineConfig.hubConfig } yield { BroadcasterMultiplexerService(broadcaster, hubConfig.maxQueryWaitTime) } } protected lazy val pmUrlString: String = shrineConfig.pmEndpoint.url.toString protected lazy val ontologyMetadata: OntologyMetadata = { import scala.concurrent.duration._ //TODO: XXX: Un-hard-code max wait time param val ontClient: OntClient = new PosterOntClient(shrineConfig.ontHiveCredentials, 1.minute, ontPoster) new OntClientOntologyMetadata(ontClient) } //TODO: Don't assume we're an adapter with an AdapterMappings (don't call .get) protected lazy val happyService: HappyShrineService = { new HappyShrineService( shrineConfig, shrineCertCollection, signerVerifier, pmPoster, ontologyMetadata, adapterMappings, auditDao, adapterDao, broadcasterOption, adapterService) } protected lazy val happyResource: HappyShrineResource = new HappyShrineResource(happyService) protected lazy val statusJaxrs: StatusJaxrs = StatusJaxrs(config) protected lazy val shrineResource: Option[ShrineResource] = shrineService.map(ShrineResource(_)) protected lazy val i2b2BroadcastResource: Option[I2b2BroadcastResource] = i2b2Service.map(new I2b2BroadcastResource(_, breakdownTypes)) protected lazy val adapterResource: Option[AdapterResource] = adapterService.map(AdapterResource(_)) protected lazy val i2b2AdminResource: Option[I2b2AdminResource] = i2b2AdminService.map(I2b2AdminResource(_, breakdownTypes)) protected lazy val broadcasterMultiplexerResource: Option[BroadcasterMultiplexerResource] = broadcasterMultiplexerService.map(BroadcasterMultiplexerResource(_)) } object ManuallyWiredShrineJaxrsResources { def makeAdapterServiceOption(isQueryable: Boolean, adapterRequestHandler: Option[AdapterRequestHandler]): Option[AdapterRequestHandler] = { if (isQueryable) { require(adapterRequestHandler.isDefined, "Self-querying requested, but this node is not configured to be an adapter") adapterRequestHandler } else { None } } def makeHttpClient(keystoreCertCollection: KeyStoreCertCollection, endpoint: EndpointConfig): HttpClient = { - import TrustParam.{ AcceptAllCerts, SomeKeyStore } + import TrustParam.{AcceptAllCerts, SomeKeyStore} val trustParam = if (endpoint.acceptAllCerts) AcceptAllCerts else SomeKeyStore(keystoreCertCollection) JerseyHttpClient(trustParam, endpoint.timeout) } private final case class AdapterComponents(adapterService: AdapterService, i2b2AdminService: I2b2AdminService, adapterDao: AdapterDao, adapterMappings: AdapterMappings) private final case class QueryEntryPointComponents(shrineService: ShrineService, i2b2Service: I2b2BroadcastService, auditDao: AuditDao) private final case class HubComponents(broadcaster: AdapterClientBroadcaster) //TODO: TEST private def adapterComponentsToTuple(option: Option[AdapterComponents]): (Option[AdapterService], Option[I2b2AdminService], Option[AdapterDao], Option[AdapterMappings]) = option match { case None => (None, None, None, None) case Some(AdapterComponents(a, b, c, d)) => (Option(a), Option(b), Option(c), Option(d)) } //TODO: TEST private def queryEntryPointComponentsToTuple(option: Option[QueryEntryPointComponents]): (Option[ShrineService], Option[I2b2BroadcastService], Option[AuditDao]) = option match { case None => (None, None, None) case Some(QueryEntryPointComponents(a, b, c)) => (Option(a), Option(b), Option(c)) } //TODO: TEST private def unpackHubComponents(option: Option[HubComponents]): Option[AdapterClientBroadcaster] = option.map(_.broadcaster) def poster(keystoreCertCollection: KeyStoreCertCollection)(endpoint: EndpointConfig): Poster = { val httpClient = makeHttpClient(keystoreCertCollection, endpoint) Poster(endpoint.url.toString, httpClient) } } diff --git a/apps/shrine-app/src/test/scala/net/shrine/wiring/AuthStrategyTest.scala b/apps/shrine-app/src/test/scala/net/shrine/wiring/AuthStrategyTest.scala index 0a9861417..a9ca9a03f 100644 --- a/apps/shrine-app/src/test/scala/net/shrine/wiring/AuthStrategyTest.scala +++ b/apps/shrine-app/src/test/scala/net/shrine/wiring/AuthStrategyTest.scala @@ -1,114 +1,113 @@ package net.shrine.wiring import net.shrine.protocol.CredentialConfig import net.shrine.util.ShouldMatchersForJUnit import org.junit.Test import net.shrine.client.{EndpointConfig, Poster} import net.shrine.authentication.{AuthenticationType, PmAuthenticator, Authenticator} import net.shrine.hms.authentication.EcommonsPmAuthenticator import net.shrine.service.{QepConfig, AllowsAllAuthenticator} import net.shrine.authorization.{AuthorizationType, AllowsAllAuthorizationService} import net.shrine.hms.authorization.HmsDataStewardAuthorizationService import java.net.URL import net.shrine.hms.authorization.JerseySheriffClient import net.shrine.crypto.SigningCertStrategy /** * @author clint * @since Jul 2, 2014 */ final class AuthStrategyTest extends ShouldMatchersForJUnit { private[this] val pmPoster = Poster("http://example.com", null) @Test - def testDefaultDetermineAuthenticator: Unit = { - import AuthStrategy.Default + def testDefaultDetermineAuthenticator(): Unit = { import AuthenticationType._ intercept[Exception] { - Default.determineAuthenticator(null, pmPoster) + AuthStrategy.determineAuthenticator(null, pmPoster) } { - val authenticator = Default.determineAuthenticator(Pm, pmPoster).asInstanceOf[PmAuthenticator] + val authenticator = AuthStrategy.determineAuthenticator(Pm, pmPoster).asInstanceOf[PmAuthenticator] authenticator.pmPoster should be(pmPoster) } { - val authenticator = Default.determineAuthenticator(Ecommons, pmPoster).asInstanceOf[EcommonsPmAuthenticator] + val authenticator = AuthStrategy.determineAuthenticator(Ecommons, pmPoster).asInstanceOf[EcommonsPmAuthenticator] authenticator.pmPoster should be(pmPoster) } { - val authenticator = Default.determineAuthenticator(NoAuthentication, pmPoster) + val authenticator = AuthStrategy.determineAuthenticator(NoAuthentication, pmPoster) authenticator should be(AllowsAllAuthenticator) } } @Test - def testDefaultDetermineAuthorizationService: Unit = { - import AuthStrategy.Default + def testDefaultDetermineAuthorizationService(): Unit = { import AuthorizationType._ intercept[Exception] { - Default.determineQueryAuthorizationService(null, null, null) + AuthStrategy.determineQueryAuthorizationService(null, null, null) } { - val authService = Default.determineQueryAuthorizationService(NoAuthorization, null, null) + val authService = AuthStrategy.determineQueryAuthorizationService(NoAuthorization, null, null) authService should be(AllowsAllAuthorizationService) } { val authenticationType = AuthenticationType.Ecommons val authorizationType = HmsSteward import scala.concurrent.duration._ val sheriffUrl = "http://example.com/sheriff" val sheriffCredentials = CredentialConfig(None, "u", "p") val shrineConfig = ShrineConfig( None, //adapter config None, //hub config Some(QepConfig( authenticationType, authorizationType, - Some(EndpointConfig(new URL(sheriffUrl), false, 42.minutes)), + Some(EndpointConfig(new URL(sheriffUrl), acceptAllCerts = false, 42.minutes)), Some(sheriffCredentials), None, - false, + includeAggregateResults = false, 1.minute, None, SigningCertStrategy.Attach, - false)), + collectQepAudit = false)), null, //hiveCredentials null, //more hiveCredentials null, //pmEndpoint null, //ontEndpoint null, //adapterStatusQuery null, //humanReadableNodeName null, //shrineDatabaseType null, //keystoreDescriptor Set.empty ) //breakdown types val authenticator: Authenticator = AllowsAllAuthenticator - val authService = Default.determineQueryAuthorizationService(HmsSteward, shrineConfig, authenticator).asInstanceOf[HmsDataStewardAuthorizationService] + val authService = AuthStrategy.determineQueryAuthorizationService(HmsSteward, shrineConfig, authenticator).asInstanceOf[HmsDataStewardAuthorizationService] authService.authenticator should be(authenticator) + //noinspection ScalaUnnecessaryParentheses authService.sheriffClient should not be(null) val jerseySheriffClient = authService.sheriffClient.asInstanceOf[JerseySheriffClient] jerseySheriffClient.sheriffUrl should equal(sheriffUrl) jerseySheriffClient.sheriffUsername should equal(sheriffCredentials.username) jerseySheriffClient.sheriffPassword should equal(sheriffCredentials.password) } } } \ No newline at end of file