javax.inject.Singleton Scala Examples

The following examples show how to use javax.inject.Singleton. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: SimilarityAPIController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.api.similarity

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseOptAuthController, Security, HasPrettyPrintJSON}
import javax.inject.{Inject, Singleton}
import play.api.Configuration
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.mvc.ControllerComponents 
import scala.concurrent.{ExecutionContext, Future}
import services.RuntimeAccessLevel
import services.document.{DocumentService, ExtendedDocumentMetadata}
import services.generated.tables.records.DocumentRecord
import services.user.UserService
import services.similarity.{Similarity, SimilarityService}

@Singleton
class SimilarityAPIController @Inject() (
  val components: ControllerComponents,
  val config: Configuration,
  val documents: DocumentService,
  val similarities: SimilarityService,
  val users: UserService,
  val silhouette: Silhouette[Security.Env],
  implicit val ctx: ExecutionContext
) extends BaseOptAuthController(components, config, documents, users) with HasPrettyPrintJSON {

  implicit val similarDocumentWrites: Writes[(DocumentRecord, RuntimeAccessLevel, Similarity)] = (
    (JsPath \ "document_id").write[String] and
    (JsPath \ "author").writeNullable[String] and
    (JsPath \ "title").write[String] and 
    (JsPath \ "owner").write[String] and
    (JsPath \ "similarity").write[JsValue]
  )(t => (
      t._1.getId, 
      Option(t._1.getAuthor),
      t._1.getTitle,
      t._1.getOwner,
      Json.obj(
        "title" -> t._3.jaroWinkler, 
        "entities" -> t._3.jaccard)
  ))

  implicit val similarityAPIResponseWrites: Writes[(ExtendedDocumentMetadata, Seq[(DocumentRecord, RuntimeAccessLevel, Similarity)])] = (
    (JsPath \ "document_id").write[String] and
    (JsPath \ "author").writeNullable[String] and
    (JsPath \ "title").write[String] and 
    (JsPath \ "owner").write[String] and 
    (JsPath \ "similar").write[Seq[(DocumentRecord, RuntimeAccessLevel, Similarity)]]
  )(t => (
      t._1.id,
      t._1.author,
      t._1.title,
      t._1.ownerName,
      t._2
  ))

  def getSimilar(docId: String) = silhouette.UserAwareAction.async { implicit request => 
    documentResponse(docId, request.identity, { case (doc, accesslevel) => 
      if (accesslevel.canReadData) {
        similarities.findSimilar(docId, request.identity.map(_.username)).map { response => 
          jsonOk(Json.toJson((doc, response)))
        }
      } else {
        Future.successful(Forbidden)
      }
    })
  }
  
} 
Example 2
Source File: StatsController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.document.stats

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseOptAuthController, Security, HasVisitLogging, HasPrettyPrintJSON}
import java.io.{ByteArrayOutputStream, PrintWriter}
import javax.inject.{Inject, Singleton}
import kantan.csv._
import kantan.csv.ops._
import kantan.csv.CsvConfiguration.{Header, QuotePolicy}
import kantan.csv.engine.commons._
import services.annotation.AnnotationService
import services.document.DocumentService
import services.user.UserService
import services.user.Roles._
import services.visit.VisitService
import org.webjars.play.WebJarsUtil
import play.api.Configuration
import play.api.mvc.{AnyContent, Request, Result, ControllerComponents}
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.i18n.I18nSupport
import plugins.PluginRegistry
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class StatsController @Inject() (
  val components: ControllerComponents,
  val config: Configuration,
  val documents: DocumentService,
  val annotations: AnnotationService,
  val users: UserService,
  val silhouette: Silhouette[Security.Env],
  implicit val visitService: VisitService,
  implicit val webjars: WebJarsUtil,
  implicit val ctx: ExecutionContext
) extends BaseOptAuthController(components, config, documents, users) 
    with HasVisitLogging 
    with HasPrettyPrintJSON 
    with I18nSupport {
  
  private val CSV_CONFIG = CsvConfiguration(',', '"', QuotePolicy.WhenNeeded, Header.None)
    
  implicit val tuple2Writes: Writes[Tuple2[String, Long]] = (
    (JsPath \ "value").write[String] and
    (JsPath \ "count").write[Long]
  )(t => (t._1, t._2))
  
  private def toCSV(stats: Seq[(String, Long)]): String = {
    val out = new ByteArrayOutputStream()
    val writer = out.asCsvWriter[(String, Long)](CSV_CONFIG)
    stats.foreach(writer.write(_))
    writer.close()
    new String(out.toByteArray, "UTF-8")
  }
  
  def showDocumentStats(documentId: String, tab: Option[String]) = silhouette.UserAwareAction.async { implicit request =>
    documentReadResponse(documentId, request.identity,  { case (doc, accesslevel) =>
      logDocumentView(doc.document, None, accesslevel)      
      tab.map(_.toLowerCase) match {
        case Some(t) if t == "activity" =>  
          val plugins = PluginRegistry.listConfigs("document.stats.activity")
          Future.successful(Ok(views.html.document.stats.activity(doc, request.identity, accesslevel, plugins)))
          
        case Some(t) if t == "entities" =>
          val plugins = PluginRegistry.listConfigs("document.stats.entities")
          Future.successful(Ok(views.html.document.stats.entities(doc, request.identity, accesslevel, plugins)))
          
        case Some(t) if t == "tags" =>
          val plugins = PluginRegistry.listConfigs("document.stats.tags")
          Future.successful(Ok(views.html.document.stats.tags(doc, request.identity, accesslevel, plugins)))
          
        case _ =>
          val plugins = PluginRegistry.listConfigs("document.stats.activity")
          Future.successful(Ok(views.html.document.stats.activity(doc, request.identity, accesslevel, plugins)))
      }
    })
  }
  
  private def getTags(documentId: String)(action: (Seq[(String, Long)], Request[AnyContent]) => Result) =
    silhouette.UserAwareAction.async { implicit request =>
      documentReadResponse(documentId, request.identity,  { case (doc, accesslevel) =>
          annotations.getTagStats(documentId).map { buckets =>
            action(buckets, request.request)
          }
        }
      )
    }
  
  def getTagsAsJSON(documentId: String) = getTags(documentId) { case (buckets, request) =>
    jsonOk(Json.toJson(buckets))(request)
  }
  
  def getTagsAsCSV(documentId: String) = getTags(documentId) { case(buckets, request) =>
    Ok(toCSV(buckets)).withHeaders(CONTENT_DISPOSITION -> { s"attachment; filename=${documentId}_tags.csv" })
  }

} 
Example 3
Source File: MapController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.document.map

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseOptAuthController, HasVisitLogging, Security}
import javax.inject.{Inject, Singleton}
import services.document.DocumentService
import services.annotation.AnnotationService
import services.user.UserService
import services.user.Roles._
import services.visit.VisitService
import org.webjars.play.WebJarsUtil
import play.api.Configuration
import play.api.mvc.ControllerComponents
import play.api.i18n.I18nSupport
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class MapController @Inject() (
    val components: ControllerComponents,
    val config: Configuration,
    val annotations: AnnotationService,
    val document: DocumentService,
    val users: UserService,
    val silhouette: Silhouette[Security.Env],
    implicit val visitService: VisitService,
    implicit val ctx: ExecutionContext,
    implicit val webjars: WebJarsUtil
  ) extends BaseOptAuthController(components, config, document, users) with HasVisitLogging with I18nSupport {

  def showMap(documentId: String) = silhouette.UserAwareAction.async { implicit request =>
    documentReadResponse(documentId, request.identity,  { case (doc, accesslevel) =>
      logDocumentView(doc.document, None, accesslevel)
      annotations.countByDocId(documentId).map { documentAnnotationCount =>
        Ok(views.html.document.map.index(doc, request.identity, accesslevel, documentAnnotationCount))
      }
    })
  }

} 
Example 4
Source File: AccountInfoController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.my.account

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseController, HasPrettyPrintJSON, Security}
import javax.inject.{Inject, Singleton}
import play.api.Configuration
import play.api.libs.json.Json
import play.api.mvc.ControllerComponents
import scala.concurrent.{Future, ExecutionContext}
import services.contribution.ContributionService
import services.document.DocumentService
import services.user.UserService
import storage.uploads.Uploads

@Singleton
class AccountInfoController @Inject() (
    val components: ControllerComponents,
    val contributions: ContributionService,
    val documents: DocumentService,
    val silhouette: Silhouette[Security.Env],
    val users: UserService,
    val uploads: Uploads,
    val config: Configuration,
    implicit val ctx: ExecutionContext
  ) extends BaseController(components, config, users)
      with HasPrettyPrintJSON {

  
  def getCollaborators(username: String) = Action.async { implicit request =>
    contributions.getTopCollaborators(username).map { tuples => 
      val json = tuples.map(t => Json.obj("username" -> t._1, "edits" -> t._2)) 
      jsonOk(Json.toJson(json))
    }    
  }

} 
Example 5
Source File: WorkspaceController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.my

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseController, Security, HasPrettyPrintJSON}
import javax.inject.{Inject, Singleton}
import services.contribution.{Contribution, ContributionService}
import services.user.{User, UserService}
import org.webjars.play.WebJarsUtil
import play.api.{Configuration, Environment}
import play.api.i18n.I18nSupport
import play.api.libs.json.Json
import play.api.mvc.{ControllerComponents, RequestHeader}
import services.document.DocumentService
import scala.concurrent.{ExecutionContext, Future}

@Singleton
class WorkspaceController @Inject() (
  val components: ControllerComponents,
  val contributions: ContributionService,
  val users: UserService,
  val config: Configuration,
  val silhouette: Silhouette[Security.Env],
  implicit val documents: DocumentService,
  implicit val ctx: ExecutionContext,
  implicit val env: Environment,
  implicit val webjars: WebJarsUtil
) extends BaseController(components, config, users) with I18nSupport with HasPrettyPrintJSON {

  
  def workspace(usernameInPath: String) = silhouette.UserAwareAction.async { implicit request =>    
    // If the user is logged in & the name in the path == username it's the profile owner
    val isProfileOwner = request.identity match {
      case Some(userWithRoles) => userWithRoles.username.equalsIgnoreCase(usernameInPath)
      case None => false
    }
    
    if (isProfileOwner)
      Future.successful(Ok(views.html.my.workspace()))
    else
      renderPublicProfile(usernameInPath, request.identity)
  }

  def activityFeed(usernameInPath: String) = silhouette.UserAwareAction.async { implicit request =>
    val loggedInAs = request.identity.map(_.username)
    contributions.getUserActivityFeed(Seq(usernameInPath), loggedInAs).map { response => 
      jsonOk(Json.toJson(response))
    } 
  }
  
} 
Example 6
Source File: SearchController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.my.directory.search

import controllers.{Security, HasPrettyPrintJSON}
import controllers.my.directory.ConfiguredPresentation
import com.mohiva.play.silhouette.api.Silhouette
import javax.inject.{Inject, Singleton}
import org.joda.time.DateTime
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.mvc.{AnyContent, Request, AbstractController, ControllerComponents}
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
import services.HasDate
import services.document.DocumentService
import services.document.search._

@Singleton
class SearchController @Inject() (
  components: ControllerComponents,
  silhouette: Silhouette[Security.Env],
  documentService: DocumentService,
  implicit val ctx: ExecutionContext
) extends AbstractController(components) 
    with HasPrettyPrintJSON
    with HasDate {

  import ConfiguredPresentation._

  implicit val searchOptionsReads: Reads[SearchArgs] = (
    (JsPath \ "q").readNullable[String] and
    (JsPath \ "in").readNullable[String]
      .map(_.flatMap(Scope.withName).getOrElse(Scope.ALL)) and
    (JsPath \ "type").readNullable[String]
      .map(_.flatMap(DocumentType.withName)) and
    (JsPath \ "owner").readNullable[String] and
    (JsPath \ "max_age").readNullable[DateTime]
  )(SearchArgs.apply _) 

  private def parseQueryString(params: Map[String, String]) = 
    params.get("q").map { q => // Require at least a query phrase
      SearchArgs(
        Some(q),
        params.get("in").flatMap(Scope.withName).getOrElse(Scope.ALL),
        params.get("type").flatMap(DocumentType.withName),
        params.get("owner"),
        params.get("max_age").flatMap(parseDate)
      ) 
    }

  def parseSearchArgs(request: Request[AnyContent]) = request.body.asJson match {
    case Some(json) =>
      Try(Json.fromJson[SearchArgs](json).get).toOption

    case None => // Try query string instead
      val asMap = request.queryString
        .mapValues(_.headOption)
        .filter(_._2.isDefined)
        .mapValues(_.get)
      parseQueryString(asMap)
  }
  
  
  def search = silhouette.UserAwareAction.async { implicit request =>
    parseSearchArgs(request) match {
      case Some(args) => 
        documentService.search(request.identity.map(_.username), args).map { documents => 
          val presentation = ConfiguredPresentation.forMyDocument(documents, None, None)
          jsonOk(Json.toJson(presentation))
        }

      case None =>
        Future.successful(BadRequest)
    } 
  }

} 
Example 7
Source File: FolderActionsController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.my.directory.delete

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseController, HasPrettyPrintJSON, Security}
import java.util.UUID
import javax.inject.{Inject, Singleton}
import play.api.Configuration
import play.api.mvc.ControllerComponents
import scala.concurrent.{ExecutionContext, Future}
import services.SharingLevel
import services.folder.FolderService
import services.generated.tables.records.{FolderRecord, SharingPolicyRecord}
import services.user.UserService

@Singleton
class FolderActionsController @Inject() (
  val components: ControllerComponents,
  val folders: FolderService,
  val silhouette: Silhouette[Security.Env],
  val users: UserService,
  val config: Configuration,
  implicit val ctx: ExecutionContext
) extends BaseController(components, config, users)
    with HasPrettyPrintJSON {

  
  private def isAllowed(username: String, folder: FolderRecord, policy: Option[SharingPolicyRecord]) = {
    folder.getOwner == username || 
      policy.map { p => 
        p.getSharedWith == username && p.getAccessLevel == SharingLevel.ADMIN.toString
      }.getOrElse(false)
  }

  def deleteFolder(id: UUID) = silhouette.SecuredAction.async { implicit request =>
    folders.getFolder(id, request.identity.username).flatMap { _ match {
      case Some((folder, policy)) =>
        if (isAllowed(request.identity.username, folder, policy)) {
          folders.deleteFolder(folder.getId).map { success => 
            if (success) Ok
            else InternalServerError
          }
        } else {
          Future.successful(Forbidden)
        }

      case None => Future.successful(NotFound)
    }}
  }

  def bulkDeleteFolders() =
    silhouette.SecuredAction.async { implicit request => ??? }

  def unshareFolder(id: UUID) =
    silhouette.SecuredAction.async { implicit request => ??? }

  def bulkUnshareFolders() =
    silhouette.SecuredAction.async { implicit request => ??? }

  def deleteReadme(folderId: UUID) =
    silhouette.SecuredAction.async { implicit request => 
      val f = Option(folderId) match {
        case Some(id) => folders.deleteReadme(folderId)
        case None => users.deleteReadme(request.identity.username)
      }

      f.map { success => 
        if (success) Ok else InternalServerError
      }
    }

} 
Example 8
Source File: DocumentActionsController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.my.directory.delete

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseController, HasPrettyPrintJSON, Security}
import javax.inject.{Inject, Singleton}
import play.api.Configuration
import play.api.libs.json.{Json, JsValue}
import play.api.mvc.ControllerComponents
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Try
import services.RuntimeAccessLevel
import services.annotation.AnnotationService
import services.contribution.ContributionService
import services.document.DocumentService
import services.folder.FolderService
import services.generated.tables.records.DocumentRecord
import services.user.UserService

@Singleton
class DocumentActionsController @Inject() (
  val annotations: AnnotationService,
  val components: ControllerComponents,
  val contributions: ContributionService,
  val documents: DocumentService,
  val folders: FolderService,
  val silhouette: Silhouette[Security.Env],
  val users: UserService,
  val config: Configuration,
  implicit val ctx: ExecutionContext
) extends BaseController(components, config, users)
    with HasPrettyPrintJSON {

  
  def bulkUnshareDocuments() = silhouette.SecuredAction.async { implicit request => 
    val docIds = getDocIdPayload(request.body.asJson)
    val user = request.identity.username

    Future.sequence {
      docIds.map(documents.removeDocumentCollaborator(_, user))
    }.map { results =>
      val success = !results.exists(!_)
      if (success) Ok else BadRequest
    }
  }

} 
Example 9
Source File: TaskAPIController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.api.task

import akka.actor.ActorSystem
import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseAuthController, HasPrettyPrintJSON, Security}
import java.util.UUID
import javax.inject.{Inject, Singleton}
import play.api.Configuration
import play.api.libs.json.Json
import play.api.mvc.ControllerComponents 
import services.document.DocumentService
import services.task.{TaskType, TaskService, TaskRecordAggregate}
import services.user.UserService
import services.user.Roles._
import scala.concurrent.{ExecutionContext, Future}
import transform.JobDefinition
import transform.georesolution.{GeoresolutionService, TableGeoresolutionJobDefinition}
import transform.ner.{NERService, NERJobDefinition}

@Singleton
class TaskAPIController @Inject() (
  val components: ControllerComponents,
  val config: Configuration,
  val documents: DocumentService,
  val users: UserService,
  val ner: NERService,
  val georesolution: GeoresolutionService,
  val silhouette: Silhouette[Security.Env],
  val tasks: TaskService,
  implicit val system: ActorSystem,
  implicit val ctx: ExecutionContext
) extends BaseAuthController(components, config, documents, users) with HasPrettyPrintJSON {

  def spawnJob = silhouette.SecuredAction.async { implicit request =>
    request.body.asJson.map(json => Json.fromJson[JobDefinition](json)) match {
      case Some(result) if result.isSuccess =>
        val taskDefinition = result.get
        documentResponse(taskDefinition.documents.head, request.identity, { case (docInfo, accesslevel) =>
          if (accesslevel.canWrite)
            taskDefinition.taskType match {  
              case TaskType("GEORESOLUTION") =>
                val definition = Json.fromJson[TableGeoresolutionJobDefinition](request.body.asJson.get).get
                georesolution.spawnJob(docInfo.document, docInfo.fileparts, definition)
                Ok

              case TaskType("NER") =>
                val definition = Json.fromJson[NERJobDefinition](request.body.asJson.get).get
                val jobId = ner.spawnJob(docInfo.document, docInfo.fileparts, definition)
                jsonOk(Json.obj("job_id" -> jobId))
                
              case t =>
                BadRequest(Json.parse("{ \"error\": \"unsupported task type: " + t + "\" }"))
            }
          else
            Forbidden(Json.parse("{ \"error\": \"insufficient access privileges\"}"))
        })
        
      case Some(result) if result.isError => Future.successful(BadRequest(Json.parse("{ \"error\": \"JSON parse error\" }")))
      case None => Future.successful(BadRequest(Json.parse("{ \"error\": \"missing task definition\" }")))
    }
  }

  def getJobProgress(jobId: UUID) = silhouette.SecuredAction.async { implicit request => 
    tasks.findByJobId(jobId).map { _ match {
      case Some(progress) => jsonOk(Json.toJson(progress))
      case None => NotFound
    }}
  }

  def progressByDocument(id: String) = silhouette.SecuredAction.async { implicit request =>    
    documents.getExtendedMeta(id, Some(request.identity.username)).flatMap(_ match {
      case Some((doc, accesslevel)) =>
        if (accesslevel.canReadAll) {
          tasks.findByDocument(id).map {
            case Some(taskRecord) => jsonOk(Json.toJson(taskRecord))
            case None => NotFound
          }
        } else {
          Future.successful(Forbidden)
        }
        
      case None => Future.successful(NotFound)
    })
  }
  
} 
Example 10
Source File: DiscussionController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.document.discussion

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseAuthController, Security}
import javax.inject.{Inject, Singleton}
import services.document.DocumentService
import services.user.UserService
import services.user.Roles._
import org.webjars.play.WebJarsUtil
import play.api.Configuration
import play.api.mvc.ControllerComponents
import play.api.i18n.I18nSupport
import scala.concurrent.ExecutionContext

@Singleton
class DiscussionController @Inject() (
    val components: ControllerComponents,
    val config: Configuration,
    val documents: DocumentService,
    val users: UserService,
    val silhouette: Silhouette[Security.Env],
    implicit val webjars: WebJarsUtil,
    implicit val ctx: ExecutionContext
  ) extends BaseAuthController(components, config, documents, users) with I18nSupport {

  def showDiscussionBoard(documentId: String) = silhouette.SecuredAction.async { implicit request =>
    documentResponse(documentId, request.identity, { case (doc, accesslevel) =>
      Ok(views.html.document.discussion.index(doc, Some(request.identity), accesslevel)) })
  }

} 
Example 11
Source File: PluginAPIController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.api.plugin

import controllers.{BaseOptAuthController, HasPrettyPrintJSON}
import javax.inject.{Inject, Singleton}
import org.pelagios.recogito.sdk.ner.NERPlugin
import play.api.Configuration
import play.api.libs.json._
import play.api.libs.functional.syntax._
import play.api.mvc.ControllerComponents
import plugins.PluginRegistry
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
import services.document.DocumentService
import services.user.UserService
import transform.ner.NERPluginManager

@Singleton
class PluginAPIController @Inject() (
  val components: ControllerComponents,
  val config: Configuration,
  val documents: DocumentService,
  val users: UserService,
  implicit val ctx: ExecutionContext
) extends BaseOptAuthController(components, config, documents, users) with HasPrettyPrintJSON {

  implicit val pluginWrites: Writes[NERPlugin] = (
    (JsPath \ "identifier").write[String] and
    (JsPath \ "name").write[String] and
    (JsPath \ "languages").write[Seq[String]] and
    (JsPath \ "organization").write[String] and
    (JsPath \ "description").write[String] and 
    (JsPath \ "version").write[String]
  )(p => (
     p.getClass.getName,
     p.getName,
     p.getSupportedLanguages.asScala,
     p.getOrganization,
     p.getDescription,
     p.getVersion
  ))

  def listNERPlugins = Action { implicit request =>
    val plugins = NERPluginManager.plugins
    jsonOk(Json.toJson(plugins))
  }

  def loadPlugin(ext: String, id: String) = Action.async { implicit request =>
    PluginRegistry.loadPlugin(ext, id).map { _ match {
      case Some(js) => Ok(js).as("application/javascript")
      case None => NotFound 
    }}
  }

  def loadCSS(ext: String, id: String) = Action.async { implicit request => 
    PluginRegistry.loadCSS(ext, id).map { _ match {
      case Some(css) => Ok(css).as("text/css")
      case None => NotFound
    }}
  }

} 
Example 12
Source File: ContributionAPIController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.api.contribution

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseOptAuthController, Security, HasPrettyPrintJSON}
import javax.inject.{Inject, Singleton}
import play.api.Configuration
import play.api.libs.json.Json
import play.api.mvc.ControllerComponents 
import scala.concurrent.{ExecutionContext, Future}
import services.HasDate
import services.contribution.ContributionService
import services.document.DocumentService
import services.user.UserService

@Singleton
class ContributionAPIController @Inject() (
  val components: ControllerComponents,
  val config: Configuration,
  val contributions: ContributionService,
  val documents: DocumentService,
  val users: UserService,
  val silhouette: Silhouette[Security.Env],
  implicit val ctx: ExecutionContext
) extends BaseOptAuthController(components, config, documents, users) with HasPrettyPrintJSON with HasDate {

  def getDocumentStats(id: String) = silhouette.UserAwareAction.async { implicit request => 
    documentResponse(id, request.identity, { case (doc, accesslevel) => 
      if (accesslevel.canReadData) {
        contributions.getDocumentStats(id).map { stats => 
          jsonOk(Json.toJson(stats))
        }
      } else {
        Future.successful(Forbidden)
      }
    })
  }

  def countContributionsSince(docId: String, timestamp: String) = silhouette.UserAwareAction.async { implicit request => 
    documentResponse(docId, request.identity, { case (doc, accesslevel) =>
      if (accesslevel.canReadData) {
        parseDate(timestamp) match {
          case Some(date) => 
            contributions.countContributionsSince(docId, date).map { count => 
            jsonOk(Json.obj(
              "id" -> doc.id, 
              "contributions" -> count,
              "since" -> formatDate(date)))
          }

          case None => 
            Future.successful(BadRequest)
        }
      } else {
        Future.successful(Forbidden)
      }
    })
  }
  
} 
Example 13
Source File: PlaceAPIController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.api.entity

import com.mohiva.play.silhouette.api.Silhouette
import com.vividsolutions.jts.geom.Coordinate
import controllers.{BaseOptAuthController, HasPrettyPrintJSON, Security}
import javax.inject.{Inject, Singleton}
import services.document.DocumentService
import services.entity.builtin.EntityService
import services.user.UserService
import services.user.Roles._
import play.api.Configuration
import play.api.libs.json.Json
import play.api.mvc.{Action, ControllerComponents}
import scala.concurrent.{Future, ExecutionContext }
import scala.util.{Try, Success, Failure}
import services.entity.EntityType

@Singleton
class PlaceAPIController @Inject() (
  val components: ControllerComponents,
  val config: Configuration,
  val documents: DocumentService,
  val users: UserService,
  val entities: EntityService,
  val silhouette: Silhouette[Security.Env],
  implicit val ctx: ExecutionContext
) extends BaseOptAuthController(components, config, documents, users) with HasPrettyPrintJSON {

  
  def searchPlacesInDocument(query: String, docId: String, offset: Int, size: Int) = silhouette.UserAwareAction.async { implicit request =>
    documentResponse(docId, request.identity, { case (metadata, accesslevel) =>
      if (accesslevel.canReadData)
        entities.searchEntitiesInDocument(query, docId, Some(EntityType.PLACE), offset, size).map { results =>
          jsonOk(Json.toJson(results.map(_.entity)))
        }
      else
        Future.successful(Forbidden)
    })
  }

} 
Example 14
Source File: AuthoritiesAPIController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.api.entity

import controllers.{BaseOptAuthController, HasPrettyPrintJSON}
import javax.inject.{Inject, Singleton}
import play.api.Configuration
import play.api.libs.json.{Json, JsObject}
import play.api.mvc.ControllerComponents
import scala.concurrent.ExecutionContext
import services.document.DocumentService
import services.entity.{AuthorityFileService, EntityType}
import services.entity.builtin.EntityService
import services.user.UserService

@Singleton
class AuthoritiesAPIController @Inject() (
  val authorities: AuthorityFileService,
  val components: ControllerComponents,
  val config: Configuration,
  val documents: DocumentService,
  val entities: EntityService,
  val users: UserService,
  implicit val ctx: ExecutionContext
) extends BaseOptAuthController(components, config, documents, users) with HasPrettyPrintJSON {

  def listGazetteers = Action.async { implicit request =>
    val fMetadata = authorities.listAll(Some(EntityType.PLACE))
    val fRecordCounts = entities.countByAuthority(Some(EntityType.PLACE))
    
    val f = for {
      metadata <- fMetadata
      counts <- fRecordCounts
    } yield (metadata, counts)
    
    f.map { case (listedGazetteers, counts) =>
      import AuthorityFileService._ // Import implicit JSON serialization
      
      // In order to see possible inconsistencies between DB and index,
      // we separately handle: i) gazetteers described in the DB, ii) gazetteer
      // IDs recorded in the index, but without a metadata record in the DB.
      // Normally, the list below should be empty.
      val unlistedGazetteers = counts.filterNot { case (id, count) => 
        listedGazetteers.map(_.getId).contains(id) 
      }
      
      val json = listedGazetteers.map {  m =>
          val count = counts.find(_._1 == m.getId).map(_._2).getOrElse(0l)
          Json.toJson(m).as[JsObject] ++ Json.obj("count" -> count)
        } ++ unlistedGazetteers.map { case (id, count) =>
          Json.obj(
            "identifier" -> id,
            "authority_type" -> "PLACE",
            "shortname" -> id,
            "count" -> count,
            "conflicted" -> true)
        }
      
      jsonOk(Json.toJson(json))
    }
  }

} 
Example 15
Source File: AdminController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.admin

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseAuthController, Security}
import javax.inject.{Inject, Singleton}
import services.annotation.AnnotationService
import services.contribution.ContributionService
import services.document.{DocumentService, DocumentToJSON}
import services.user.UserService
import services.user.Roles._
import services.visit.VisitService
import org.webjars.play.WebJarsUtil
import play.api.Configuration
import play.api.libs.json.Json
import play.api.mvc.ControllerComponents
import scala.concurrent.ExecutionContextExecutor
import controllers.HasPrettyPrintJSON

@Singleton
class AdminController @Inject() (
  val components: ControllerComponents, 
  val config: Configuration,
  val annotations: AnnotationService,
  val contributions: ContributionService,
  val documents: DocumentService,
  val users: UserService,
  val visits: VisitService,
  val silhouette: Silhouette[Security.Env],
  implicit val ctx: ExecutionContextExecutor,
  implicit val webJarsUtil: WebJarsUtil
) extends BaseAuthController(components, config, documents, users) with HasPrettyPrintJSON {
        
  def index = silhouette.SecuredAction(Security.WithRole(Admin)) { implicit request =>
    Ok(views.html.admin.activity())
  }
  
  def getStats() = silhouette.SecuredAction(Security.WithRole(Admin)).async { implicit request =>
    // DocumentRecord JSON serialization
    import DocumentToJSON._
    
    val fRecentContributions = contributions.getMostRecent(10)
    val fSystemStats = contributions.getSystemStats()
    val fTotalAnnotations = annotations.countTotal()
    val fTotalVisits = visits.countTotal()
    val fTotalUsers = users.countUsers()

    val f = for {
      recentContributions <- fRecentContributions
      recentAffectedDocuments <- documents.getDocumentRecordsById(recentContributions.map(_.affectsItem.documentId))
      stats <- fSystemStats
      annotationCount <- fTotalAnnotations
      visitCount <- fTotalVisits
      userCount <- fTotalUsers
    } yield (recentContributions, recentAffectedDocuments, stats, annotationCount, visitCount, userCount)
    
    f.map { case (recentContributions, recentAffectedDocuments, stats, annotationCount, visitCount, userCount) =>
      val response =
        Json.obj(
          "recent_contributions" -> recentContributions,
          "recent_documents" -> recentAffectedDocuments,
          "contribution_stats" -> stats,
          "total_annotations" -> annotationCount,
          "total_visits" -> visitCount,
          "total_users" -> userCount)
      jsonOk(response)
    }
  }

  def getSignupHistory = silhouette.SecuredAction(Security.WithRole(Admin)).async { implicit request =>
    users.getSignupsOverTime().map { history =>
      val json = history.map(t => Json.obj("timestamp" -> t._1, "count" -> t._2))
      jsonOk(Json.toJson(json))
    }
  }
  
} 
Example 16
Source File: BackupAdminController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.admin.backup

import akka.actor.ActorSystem
import akka.stream.scaladsl.FileIO
import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseAuthController, Security}
import controllers.document.BackupReader
import javax.inject.{Inject, Singleton}
import services.ContentType
import services.annotation.AnnotationService
import services.document.DocumentService
import services.generated.tables.records.DocumentFilepartRecord
import services.user.UserService
import services.user.Roles._
import services.visit.VisitService
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat
import org.webjars.play.WebJarsUtil
import play.api.Configuration
import play.api.mvc.{ControllerComponents, ResponseHeader, Result}
import play.api.libs.Files.TemporaryFileCreator
import play.api.http.HttpEntity
import scala.concurrent.{ExecutionContext, Future}
import storage.db.DB
import storage.es.migration.AnnotationMigrationUtil
import transform.tiling.TilingService

@Singleton
class BackupAdminController @Inject() (
    val components: ControllerComponents,
    val config: Configuration,
    val migrationUtil: AnnotationMigrationUtil,
    val users: UserService,
    val visits: VisitService,
    val silhouette: Silhouette[Security.Env],
    implicit val db: DB,
    implicit val tilingService: TilingService,
    implicit val annotations: AnnotationService,
    implicit val documents: DocumentService,
    implicit val ctx: ExecutionContext,
    implicit val system: ActorSystem,
    implicit val tmpFileCreator: TemporaryFileCreator,
    implicit val webJarsUtil: WebJarsUtil
  ) extends BaseAuthController(components, config, documents, users) with BackupReader {

  

  def restore = silhouette.SecuredAction(Security.WithRole(Admin)).async { implicit request =>
    request.body.asMultipartFormData.flatMap(_.file("backup")) match {
      case Some(formData) =>
        restoreBackup(formData.ref.path.toFile, runAsAdmin = true, forcedOwner = None).map { case (doc, fileparts) =>
          Ok
        }.recover { case t: Throwable =>
          t.printStackTrace()
          InternalServerError
        }

      case None =>
        Future.successful(BadRequest)
    }
  }

  def exportVisits = silhouette.SecuredAction(Security.WithRole(Admin)).async { implicit request =>
    visits.scrollExport().map { path =>
      val fmt = DateTimeFormat.forPattern("yyyy-MM-dd")
      val source = FileIO.fromPath(path)
      val filename = s"visits-exported-${fmt.print(DateTime.now)}.csv"
      Result(
        header = ResponseHeader(200, Map("Content-Disposition" -> s"""attachment; filename="${filename}"""")),
        body = HttpEntity.Streamed(source, None, Some("text/csv"))
      )
    }
  }

  def deleteVisitsOlderThan(date: Option[String]) = silhouette.SecuredAction(Security.WithRole(Admin)).async { implicit request =>
    date match {
      case Some(_) =>
        Future.successful(BadRequest("User-provided dates not supported yet."))

      case _ =>
        val cutoffDate = DateTime.now minusMonths 6
        visits.deleteOlderThan(cutoffDate).map { success =>
          if (success) Ok("Done.")
          else InternalServerError("Something went wrong.")
        }
    }
  }

} 
Example 17
Source File: MaintenanceController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.admin.maintenance

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{BaseAuthController, Security, HasPrettyPrintJSON}
import java.io.File
import javax.inject.{Inject, Singleton}
import org.joda.time.DateTime
import org.webjars.play.WebJarsUtil
import play.api.{Configuration, Environment}
import play.api.mvc.ControllerComponents
import play.api.libs.json._
import play.api.libs.functional.syntax._
import scala.concurrent.ExecutionContext
import services.announcement.AnnouncementService
import services.document.DocumentService
import services.generated.tables.records.UploadRecord
import services.upload.UploadService
import services.user.UserService
import services.user.Roles._
import services.HasDate
import storage.es.ES
import storage.uploads.Uploads

@Singleton
class MaintenanceController @Inject()(
  val announcements: AnnouncementService,
  val components: ControllerComponents, 
  val config: Configuration,
  val documents: DocumentService,
  val env: Environment,
  val es: ES,
  val silhouette: Silhouette[Security.Env],
  val uploadService: UploadService,
  val uploadStorage: Uploads,
  val users: UserService,
  implicit val ctx: ExecutionContext,
  implicit val webJarsUtil: WebJarsUtil
) extends BaseAuthController(components, config, documents, users) with HasPrettyPrintJSON with HasDate {

  implicit val uploadRecordWrites: Writes[UploadRecord] = (
    (JsPath \ "owner").write[String] and
    (JsPath \ "title").write[String] and
    (JsPath \ "created_at").write[DateTime]
  )(upload => (
    upload.getOwner,
    upload.getTitle,
    new DateTime(upload.getCreatedAt)
  ))
  
  def index = silhouette.SecuredAction(Security.WithRole(Admin)).async { implicit request =>
    uploadService.listPendingUploads().map { uploads =>
      Ok(views.html.admin.maintenance())
    }
  }

  
  def insertBroadcast = silhouette.SecuredAction(Security.WithRole(Admin)).async { implicit request =>
    announcements.insertBroadcastAnnouncement(
    """# Like Recogito? Vote for us!

We are excited that Recogito has been nominated for the [Digital Humanities Awards](http://dhawards.org/dhawards2018/voting/) this year. 
If you like Recogito, do consider voting for us.

Many thanks & happy annotating!
    """).map(_ => Ok)
  }
  
  def deleteAllServiceAnnouncements = silhouette.SecuredAction(Security.WithRole(Admin)).async { implicit request =>
    announcements.clearAll().map { success =>
      if (success) Ok
      else InternalServerError
    }
  }
  
} 
Example 18
Source File: StatusController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.landing

import javax.inject.{Inject, Singleton}
import play.api.mvc.{AbstractController, Action, ControllerComponents}
import scala.concurrent.ExecutionContext
import services.user.UserService
import services.contribution.ContributionService

@Singleton
class StatusController @Inject()(
  val components: ControllerComponents,
  val users: UserService,
  val edits: ContributionService,
  implicit val ctx: ExecutionContext
) extends AbstractController(components) {
  
  def index = Action.async { request =>
    val fDBOnline = users.countUsers()
      .map { _ => true }
      .recover { case t: Throwable => false }
      
    val fIndexOnline = edits.countLast24hrs()
      .map { _ => true }
      .recover { case t: Throwable => false }
    
    val f = for {
      dbOnline <- fDBOnline
      idxOnline <- fIndexOnline
    } yield (dbOnline, idxOnline)
    
    f.map { case (dbOnline, idxOnline) =>
      Ok(views.html.landing.status(dbOnline, idxOnline))
    }    
  }
  
} 
Example 19
Source File: SqlComponent.scala    From fusion-data   with Apache License 2.0 5 votes vote down vote up
package mass.db.slick

import akka.Done
import akka.actor.ActorSystem
import com.typesafe.scalalogging.StrictLogging
import com.zaxxer.hikari.HikariDataSource
import fusion.core.extension.FusionCore
import fusion.jdbc.{ FusionJdbc, JdbcTemplate }
import javax.inject.{ Inject, Singleton }
import slick.basic.DatabasePublisher

import scala.concurrent.Future
import scala.util.Failure


@Singleton
class SqlComponent @Inject() (val profile: PgProfile, classicSystem: ActorSystem) extends StrictLogging {
  import profile.api._
  val dataSource: HikariDataSource = FusionJdbc(classicSystem).component
  val db = databaseForDataSource(dataSource)
  val jdbcTemplate: JdbcTemplate = JdbcTemplate(dataSource)
  FusionCore(classicSystem).shutdowns.beforeActorSystemTerminate("StopSqlManager") { () =>
    Future {
      db.close()
      Done
    }(classicSystem.dispatcher)
  }

  def runTransaction[R, E <: Effect.Write](a: DBIOAction[R, NoStream, E]): Future[R] =
    wrapperLogging(db.run(a.transactionally))

  def run[R](a: DBIOAction[R, NoStream, Nothing]): Future[R] = wrapperLogging(db.run(a))

  def stream[T](a: DBIOAction[_, Streaming[T], Nothing]): DatabasePublisher[T] = db.stream(a)

  def streamTransaction[T, E <: Effect.Write](a: DBIOAction[_, Streaming[T], E]): DatabasePublisher[T] =
    db.stream(a.transactionally)

  @inline private def wrapperLogging[T](f: Future[T]): Future[T] =
    f.andThen { case Failure(e) => logger.warn(s"Slick run error [${e.toString}].") }(db.ioExecutionContext)

  override def toString = s"SqlSystem($dataSource, $jdbcTemplate, $db)"
} 
Example 20
Source File: DynamoService.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.iep.archaius

import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicLong
import javax.inject.Inject
import javax.inject.Singleton

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient
import com.netflix.iep.service.AbstractService
import com.typesafe.config.Config

import scala.concurrent.ExecutionContext
import scala.concurrent.Future


@Singleton
class DynamoService @Inject()(client: AmazonDynamoDB, config: Config) extends AbstractService {

  private val nextId = new AtomicLong()
  private val pool = Executors.newFixedThreadPool(
    Runtime.getRuntime.availableProcessors(),
    (r: Runnable) => {
      new Thread(r, s"dynamo-db-${nextId.getAndIncrement()}")
    }
  )
  private val ec = ExecutionContext.fromExecutorService(pool)

  override def startImpl(): Unit = ()

  override def stopImpl(): Unit = {
    client match {
      case c: AmazonDynamoDBClient => c.shutdown()
      case _                       =>
    }
  }

  def execute[T](task: AmazonDynamoDB => T): Future[T] = Future(task(client))(ec)
} 
Example 21
Source File: InstrumentationService.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.iep.clienttest

import java.util.UUID
import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton

import com.netflix.iep.service.AbstractService
import com.typesafe.config.Config
import org.slf4j.LoggerFactory

@Singleton
class InstrumentationService @Inject()(config: Config, metrics: MetricLibrary)
    extends AbstractService {

  private val logger = LoggerFactory.getLogger("")

  private val tagsPerMetric = config.getInt("netflix.iep.clienttest.tags-per-metric")

  private val numCounters = config.getInt("netflix.iep.clienttest.num-counters")
  private val numTimers = config.getInt("netflix.iep.clienttest.num-timers")
  private val numDistSummaries = config.getInt("netflix.iep.clienttest.num-dist-summaries")
  private val numGauges = config.getInt("netflix.iep.clienttest.num-gauges")
  private val numPolledGauges = config.getInt("netflix.iep.clienttest.num-polled-gauges")
  private val numSlowPolledGauges = config.getInt("netflix.iep.clienttest.num-slow-polled-gauges")

  // To minimize other noise in terms of memory use and computation we use the same base tag
  // set for all metrics.
  private val tagsData = (0 until tagsPerMetric).map { i =>
    val key = f"$i%05d"
    key -> UUID.randomUUID().toString
  }.toMap

  private val executor = Executors.newScheduledThreadPool(2)
  executor.scheduleWithFixedDelay(() => update(), 0L, 10, TimeUnit.SECONDS)

  // Polled sources only need to be registered once
  (0 until numPolledGauges).foreach { i =>
    metrics.poll("polledGauge", createTags(i), i.toDouble)
  }
  (0 until numSlowPolledGauges).foreach { i =>
    metrics.poll("slowPolledGauge", createTags(i), {
      Thread.sleep(120000)
      i.toDouble
    })
  }

  private def update(): Unit = {
    logger.info("update starting")
    logger.info(s"updating $numCounters counters")
    (0 until numCounters).foreach { i =>
      metrics.increment("counter", createTags(i))
    }
    logger.info(s"updating $numTimers timers")
    (0 until numTimers).foreach { i =>
      metrics.recordTime("timer", createTags(i), i)
    }
    logger.info(s"updating $numDistSummaries distribution summaries")
    (0 until numDistSummaries).foreach { i =>
      metrics.recordTime("distSummary", createTags(i), i)
    }
    logger.info(s"updating $numGauges gauges")
    (0 until numGauges).foreach { i =>
      metrics.set("gauge", createTags(i), i)
    }
    logger.info("update complete")
  }

  private def createTags(i: Int): Map[String, String] = {
    tagsData + ("id" -> i.toString)
  }

  override def startImpl(): Unit = ()

  override def stopImpl(): Unit = {
    executor.shutdownNow()
  }
} 
Example 22
Source File: LocalFilePersistService.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.atlas.persistence

import akka.Done
import akka.NotUsed
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Flow
import akka.stream.scaladsl.Keep
import akka.stream.scaladsl.RestartFlow
import akka.stream.scaladsl.Sink
import com.netflix.atlas.akka.StreamOps
import com.netflix.atlas.akka.StreamOps.SourceQueue
import com.netflix.atlas.core.model.Datapoint
import com.netflix.iep.service.AbstractService
import com.netflix.spectator.api.Registry
import com.typesafe.config.Config
import com.typesafe.scalalogging.StrictLogging
import javax.inject.Inject
import javax.inject.Singleton

import scala.concurrent.Await
import scala.concurrent.Future
import scala.concurrent.duration.Duration

@Singleton
class LocalFilePersistService @Inject()(
  val config: Config,
  val registry: Registry,
  // S3CopyService is actually NOT used by this service, it is here just to guarantee that the
  // shutdown callback (stopImpl) of this service is invoked before S3CopyService's
  val s3CopyService: S3CopyService,
  implicit val system: ActorSystem
) extends AbstractService
    with StrictLogging {
  implicit val ec = scala.concurrent.ExecutionContext.global
  implicit val mat = ActorMaterializer()

  private val queueSize = config.getInt("atlas.persistence.queue-size")

  private val fileConfig = config.getConfig("atlas.persistence.local-file")
  private val dataDir = fileConfig.getString("data-dir")
  private val maxRecords = fileConfig.getLong("max-records")
  private val maxDurationMs = fileConfig.getDuration("max-duration").toMillis
  private val maxLateDurationMs = fileConfig.getDuration("max-late-duration").toMillis
  private val rollingConf = RollingConfig(maxRecords, maxDurationMs, maxLateDurationMs)

  require(queueSize > 0)
  require(maxRecords > 0)
  require(maxDurationMs > 0)

  private var queue: SourceQueue[Datapoint] = _
  private var flowComplete: Future[Done] = _

  override def startImpl(): Unit = {
    logger.info("Starting service")
    val (q, f) = StreamOps
      .blockingQueue[Datapoint](registry, "LocalFilePersistService", queueSize)
      .via(getRollingFileFlow)
      .toMat(Sink.ignore)(Keep.both)
      .run
    queue = q
    flowComplete = f
  }

  private def getRollingFileFlow(): Flow[Datapoint, NotUsed, NotUsed] = {
    import scala.concurrent.duration._
    RestartFlow.withBackoff(
      minBackoff = 1.second,
      maxBackoff = 3.seconds,
      randomFactor = 0,
      maxRestarts = -1
    ) { () =>
      Flow.fromGraph(
        new RollingFileFlow(dataDir, rollingConf, registry)
      )
    }
  }

  // This service should stop the Akka flow when application is shutdown gracefully, and let
  // S3CopyService do the cleanup. It should trigger:
  //   1. stop taking more data points (monitor droppedQueueClosed)
  //   2. close current file writer so that last file is ready to copy to s3
  override def stopImpl(): Unit = {
    logger.info("Stopping service")
    queue.complete()
    Await.result(flowComplete, Duration.Inf)
    logger.info("Stopped service")
  }

  def persist(dp: Datapoint): Unit = {
    queue.offer(dp)
  }
} 
Example 23
Source File: S3CopyService.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.atlas.persistence

import java.io.File
import java.nio.file.Files
import java.nio.file.Paths

import akka.NotUsed
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.KillSwitch
import akka.stream.KillSwitches
import akka.stream.scaladsl.Keep
import akka.stream.scaladsl.Source
import com.netflix.atlas.core.util.Streams
import com.netflix.iep.service.AbstractService
import com.netflix.spectator.api.Registry
import com.typesafe.config.Config
import com.typesafe.scalalogging.StrictLogging
import javax.inject.Inject
import javax.inject.Singleton

import scala.concurrent.duration._

@Singleton
class S3CopyService @Inject()(
  val config: Config,
  val registry: Registry,
  implicit val system: ActorSystem
) extends AbstractService
    with StrictLogging {

  private val dataDir = config.getString("atlas.persistence.local-file.data-dir")

  private implicit val mat = ActorMaterializer()

  private var killSwitch: KillSwitch = _
  private val s3Config = config.getConfig("atlas.persistence.s3")

  private val cleanupTimeoutMs = s3Config.getDuration("cleanup-timeout").toMillis
  private val maxInactiveMs = s3Config.getDuration("max-inactive-duration").toMillis
  private val maxFileDurationMs =
    config.getDuration("atlas.persistence.local-file.max-duration").toMillis

  require(
    maxInactiveMs > maxFileDurationMs,
    "`max-inactive-duration` MUST be longer than `max-duration`, otherwise file may be renamed before normal write competes"
  )

  override def startImpl(): Unit = {
    logger.info("Starting service")
    killSwitch = Source
      .tick(1.second, 5.seconds, NotUsed)
      .viaMat(KillSwitches.single)(Keep.right)
      .flatMapMerge(Int.MaxValue, _ => Source(FileUtil.listFiles(new File(dataDir))))
      .toMat(new S3CopySink(s3Config, registry, system))(Keep.left)
      .run()
  }

  override def stopImpl(): Unit = {
    logger.info("Stopping service")
    waitForCleanup()
    if (killSwitch != null) killSwitch.shutdown()
  }

  private def waitForCleanup(): Unit = {
    logger.info("Waiting for cleanup")
    val start = System.currentTimeMillis
    while (hasMoreFiles) {
      if (System.currentTimeMillis() > start + cleanupTimeoutMs) {
        logger.error("Cleanup timeout")
        return
      }
      Thread.sleep(1000)
    }
    logger.info("Cleanup done")
  }

  private def hasMoreFiles: Boolean = {
    try {
      Streams.scope(Files.list(Paths.get(dataDir))) { dir =>
        dir.anyMatch(f => Files.isRegularFile(f))
      }
    } catch {
      case e: Exception => {
        logger.error(s"Error checking hasMoreFiles in $dataDir", e)
        true // Assuming there's more files on error to retry
      }
    }
  }
} 
Example 24
Source File: Main.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.atlas.slotting

import com.amazonaws.services.autoscaling.AmazonAutoScaling
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB
import com.amazonaws.services.ec2.AmazonEC2
import com.google.inject.AbstractModule
import com.google.inject.Module
import com.google.inject.Provides
import com.google.inject.multibindings.Multibinder
import com.netflix.iep.aws.AwsClientFactory
import com.netflix.iep.guice.BaseModule
import com.netflix.iep.guice.GuiceHelper
import com.netflix.iep.service.Service
import com.netflix.iep.service.ServiceManager
import com.netflix.spectator.api.NoopRegistry
import com.netflix.spectator.api.Registry
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import com.typesafe.scalalogging.StrictLogging
import javax.inject.Singleton

object Main extends StrictLogging {

  private def isLocalEnv: Boolean = !sys.env.contains("EC2_INSTANCE_ID")

  private def getBaseModules: java.util.List[Module] = {
    val modules = {
      GuiceHelper.getModulesUsingServiceLoader
    }

    if (isLocalEnv) {
      // If we are running in a local environment, provide simple versions of registry
      // and config bindings. These bindings are normally provided by the final package
      // config for the app in the production setup.
      modules.add(new AbstractModule {
        override def configure(): Unit = {
          bind(classOf[Registry]).toInstance(new NoopRegistry)
          bind(classOf[Config]).toInstance(ConfigFactory.load())
        }
      })
    }

    modules
  }

  def main(args: Array[String]): Unit = {
    try {
      val modules = getBaseModules
      modules.add(new ServerModule)

      val guice = new GuiceHelper
      guice.start(modules)
      guice.getInjector.getInstance(classOf[ServiceManager])
      guice.addShutdownHook()
    } catch {
      // Send exceptions to main log file instead of wherever STDERR is sent for the process
      case t: Throwable => logger.error("fatal error on startup", t)
    }
  }

  class ServerModule extends BaseModule {
    override def configure(): Unit = {
      val serviceBinder = Multibinder.newSetBinder(binder(), classOf[Service])
      serviceBinder.addBinding().to(classOf[SlottingService])
    }

    @Provides
    @Singleton
    protected def providesAmazonDynamoDB(factory: AwsClientFactory): AmazonDynamoDB = {
      factory.getInstance(classOf[AmazonDynamoDB])
    }

    @Provides
    @Singleton
    protected def providesAmazonEC2(factory: AwsClientFactory): AmazonEC2 = {
      factory.getInstance(classOf[AmazonEC2])
    }

    @Provides
    @Singleton
    protected def providesAmazonAutoScaling(factory: AwsClientFactory): AmazonAutoScaling = {
      factory.getInstance(classOf[AmazonAutoScaling])
    }
  }
} 
Example 25
Source File: AppModuleSuite.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.atlas.aggregator

import javax.inject.Singleton
import com.google.inject.AbstractModule
import com.google.inject.Guice
import com.google.inject.Provider
import com.netflix.spectator.api.Clock
import com.netflix.spectator.api.NoopRegistry
import com.netflix.spectator.api.Registry
import com.netflix.spectator.atlas.AtlasConfig
import com.netflix.spectator.atlas.AtlasRegistry
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import org.scalatest.funsuite.AnyFunSuite

class AppModuleSuite extends AnyFunSuite {

  import AppModuleSuite._

  private val config = ConfigFactory.load()

  test("aggr service") {
    val injector = Guice.createInjector(
      new AppModule,
      new AbstractModule {
        override def configure(): Unit = {
          bind(classOf[Config]).toInstance(config)
          bind(classOf[Registry]).toProvider(classOf[RegistryProvider])
        }
      }
    )

    val aggr = injector.getInstance(classOf[AtlasAggregatorService])
    assert(aggr != null)
  }

  test("aggr config should use prefix") {
    val config = ConfigFactory.parseString("""
        |netflix.atlas.aggr.registry.atlas.uri = "test"
      """.stripMargin)
    val aggr = new AggrConfig(config, new NoopRegistry)
    assert(aggr.uri() === "test")
  }

  test("aggr config should use default for missing props") {
    val config = ConfigFactory.parseString("""
        |netflix.atlas.aggr.registry.atlas.uri = "test"
      """.stripMargin)
    val aggr = new AggrConfig(config, new NoopRegistry)
    assert(aggr.batchSize() === 10000)
  }
}

object AppModuleSuite {

  @Singleton
  class RegistryProvider extends Provider[Registry] {
    override def get(): Registry = {
      val cfg = new AtlasConfig {
        override def get(k: String): String = null
      }
      new AtlasRegistry(Clock.SYSTEM, cfg)
    }
  }
} 
Example 26
Source File: AtlasAggregatorService.scala    From iep-apps   with Apache License 2.0 5 votes vote down vote up
package com.netflix.atlas.aggregator

import com.netflix.iep.service.AbstractService
import com.netflix.spectator.api.Clock
import com.netflix.spectator.api.Id
import com.netflix.spectator.api.Registry
import com.netflix.spectator.atlas.AtlasRegistry
import com.typesafe.config.Config
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class AtlasAggregatorService @Inject()(config: Config, clock: Clock, registry: Registry)
    extends AbstractService
    with Aggregator {

  private val n = math.max(1, Runtime.getRuntime.availableProcessors() / 2)
  private val aggrCfg = new AggrConfig(config, registry)
  private val registries = (0 until n)
    .map(_ => new AtlasRegistry(clock, aggrCfg))
    .toArray

  override def startImpl(): Unit = {
    registries.foreach(_.start())
  }

  override def stopImpl(): Unit = {
    registries.foreach(_.stop())
  }

  def lookup(id: Id): AtlasRegistry = {
    // Max is needed because for Integer.MIN_VALUE the abs value will be negative
    val i = math.max(math.abs(id.hashCode()), 0) % n
    registries(i)
  }

  override def add(id: Id, value: Double): Unit = {
    lookup(id).counter(id).add(value)
  }

  override def max(id: Id, value: Double): Unit = {
    lookup(id).maxGauge(id).set(value)
  }
} 
Example 27
Source File: AUCMetric.scala    From sona   with Apache License 2.0 5 votes vote down vote up
package com.tencent.angel.sona.tree.objective.metric

import javax.inject.Singleton

object AUCMetric {
  private lazy val instance = new AUCMetric

  def getInstance(): AUCMetric = instance
}

@Singleton
class AUCMetric private extends EvalMetric {
  override def getKind: EvalMetric.Kind = EvalMetric.Kind.AUC

  override def eval(preds: Array[Float], labels: Array[Float]): Double = {
    requireBinary(preds, labels)
    val scores = labels.zip(preds).sortBy(_._2)

    val numTotal = scores.length
    val numPos = scores.count(_._1 > 0)
    val numNeg = numTotal - numPos

    // calculate the summation of ranks for positive samples
    val sumRanks = scores.zipWithIndex.filter(_._1._1.toInt == 1)
      .map(f => (1.0 + f._2) / numPos / numNeg).sum

    sumRanks.toFloat - (1.0 + numPos) / numNeg / 2.0
  }

  override def eval(preds: Array[Float], labels: Array[Float], start: Int, end: Int): Double = {
    requireBinary(preds, labels)
    eval(preds.slice(start, end), labels.slice(start, end))
  }

  private def requireBinary(preds: Array[Float], labels: Array[Float]): Unit = {
    if (preds.length != labels.length)
      throw new RuntimeException("AUC metric should be used for binary classification")
  }
} 
Example 28
Source File: LandingController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.landing

import com.mohiva.play.silhouette.api.Silhouette
import controllers.{ HasConfig, HasUserService, HasVisitLogging, HasPrettyPrintJSON, Security }
import java.io.FileInputStream
import javax.inject.{ Inject, Singleton }
import java.net.URI
import org.webjars.play.WebJarsUtil
import play.api.Configuration
import play.api.i18n.I18nSupport
import play.api.libs.json.{Json, JsObject}
import play.api.mvc.{Action, AbstractController, ControllerComponents}
import scala.concurrent.ExecutionContext
import services.annotation.AnnotationService
import services.contribution.ContributionService
import services.document.DocumentService
import services.user.UserService
import services.visit.VisitService

@Singleton
class LandingController @Inject() (
    val components: ControllerComponents,
    val config: Configuration,
    val annotations: AnnotationService,
    val contributions: ContributionService,
    val documents: DocumentService,
    val users: UserService,
    val silhouette: Silhouette[Security.Env],
    implicit val ctx: ExecutionContext,
    implicit val visits: VisitService,
    implicit val webjars: WebJarsUtil
) extends AbstractController(components) with HasConfig with HasUserService with HasVisitLogging with HasPrettyPrintJSON with I18nSupport {

  def index = silhouette.UserAwareAction { implicit request =>
    // Temporary hack only
    request.queryString.get("lang").flatMap(_.headOption) match {
      case Some(lang) =>
        Redirect(routes.LandingController.index).withLang(play.api.i18n.Lang(lang))
      case None =>
        request.identity match {
          case Some(user) =>
            Redirect(controllers.my.routes.WorkspaceController.workspace(user.username))

          case None =>
            logPageView()
            Ok(views.html.landing.index())
        }
    }
  }

  def getStats() = silhouette.UnsecuredAction.async { implicit request =>
    val fAnnotations = annotations.countTotal()
    val fEdits = contributions.countLast24hrs()
    val fUsers = users.countUsers()

    val f = for {
      annotations <- fAnnotations
      edits <- fEdits
      users <- fUsers
    } yield (annotations, edits, users)

    f.map { case (annotations, edits, users) =>
      jsonOk(Json.obj(
        "annotations" -> annotations,
        "edits" -> edits,
        "users" -> users
      ))
    }
  }

  def sitemap() = Action.async { implicit request =>
    documents.listOwnersWithPublicDocuments().map { users =>
      val baseURL = routes.LandingController.index().absoluteURL()
      val sitemap = users.map(user => s"${baseURL}${user}").mkString("\n")
      Ok(sitemap).as("text/plain")
    }
  }

  def robots() = Action { implicit request =>
    val sitemapURL = routes.LandingController.sitemap().absoluteURL()
    Ok(s"SITEMAP: ${sitemapURL}").as("text/plain")
  }

  def swaggerConfig() = Action { implicit request => 
    val json = Json.parse(new FileInputStream("conf/swagger.json"))
    val baseURL = new URI(routes.LandingController.index.absoluteURL)
    val host = if (baseURL.getPort == -1) baseURL.getHost else s"${baseURL.getHost}:${baseURL.getPort}"
    jsonOk(json.as[JsObject] ++ Json.obj("host" -> host))
  }

} 
Example 29
Source File: QrtzModels.scala    From fusion-data   with Apache License 2.0 5 votes vote down vote up
package mass.job.db.model

import javax.inject.{ Inject, Singleton }
import mass.db.slick.PgProfile

@Singleton
class QrtzModels @Inject() (val profile: PgProfile)
    extends QrtzSchedulerStateModelTable
    with QrtzSimpleTriggersModelTable
    with QrtzTriggerLogModelTable
    with QrtzLocksModelTable
    with QrtzFiredTriggersModelTable
    with QrtzCronTriggersModelTable
    with QrtzCalendarsModelTable
    with QrtzPausedTriggerGrpsModelTable
    with QrtzBlobTriggersModelTable
    with QrtzJobDetailsModelTable
    with QrtzSimpropTriggersModelTable
    with QrtzTriggersModelTable {
  import profile.api._

  
  lazy val schema: profile.SchemaDescription = Array(
    QrtzBlobTriggersModel.schema,
    QrtzCalendarsModel.schema,
    QrtzCronTriggersModel.schema,
    QrtzFiredTriggersModel.schema,
    QrtzJobDetailsModel.schema,
    QrtzLocksModel.schema,
    QrtzPausedTriggerGrpsModel.schema,
    QrtzSchedulerStateModel.schema,
    QrtzSimpleTriggersModel.schema,
    QrtzSimpropTriggersModel.schema,
    QrtzTriggerLogModel.schema,
    QrtzTriggersModel.schema).reduceLeft(_ ++ _)
} 
Example 30
Source File: MockRoute.scala    From fusion-data   with Apache License 2.0 5 votes vote down vote up
package mass.job.route.api

import akka.http.scaladsl.server.Route
import fusion.http.server.AbstractRoute
import fusion.json.jackson.http.JacksonSupport
import javax.inject.{ Inject, Singleton }

@Singleton
class MockRoute @Inject() (val jacksonSupport: JacksonSupport) extends AbstractRoute {
  override def route: Route = pathPrefix("api") {
    currentUser ~ ruleRoute
  }

  def ruleRoute: Route = pathGet("rule") {
    objectComplete(jacksonSupport.objectMapper.createArrayNode)
  }

  def currentUser: Route = pathGet("currentUser") {
    objectComplete(jacksonSupport.objectMapper.readTree(Mock.currentUser))
  }
}

object Mock {
  val currentUser =
    """{"name":"Serati Ma","avatar":"https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png","userid":"00000001","email":"[email protected]","signature":"海纳百川,有容乃大","title":"交互专家","group":"蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED","tags":[{"key":"0","label":"很有想法的"},{"key":"1","label":"专注设计"},{"key":"2","label":"辣~"},{"key":"3","label":"大长腿"},{"key":"4","label":"川妹子"},{"key":"5","label":"海纳百川"}],"notifyCount":12,"country":"China","geographic":{"province":{"label":"浙江省","key":"330000"},"city":{"label":"杭州市","key":"330100"}},"address":"西湖区工专路 77 号","phone":"0752-268888888"}"""
} 
Example 31
Source File: JobRoute.scala    From fusion-data   with Apache License 2.0 5 votes vote down vote up
package mass.job.route.api.v1

import akka.actor.ActorSystem
import akka.http.scaladsl.server.Route
import com.typesafe.scalalogging.StrictLogging
import fusion.http.server.{ AbstractRoute, JacksonDirectives }
import fusion.json.jackson.http.JacksonSupport
import javax.inject.{ Inject, Singleton }
import mass.common.page.Page
import mass.extension.MassCore
import mass.job.service.job.JobService
import mass.message.job._

@Singleton
class JobRoute @Inject() (jobService: JobService, val jacksonSupport: JacksonSupport)(implicit system: ActorSystem)
    extends AbstractRoute
    with JacksonDirectives
    with StrictLogging {
  private val pagePDM = ('page.as[Int].?(Page.DEFAULT_PAGE), Symbol("size").as[Int].?(Page.DEFAULT_SIZE), 'key.?)

  override def route: Route = pathPrefix("job") {
    createJobRoute ~
    updateJobRoute ~
    pageRoute ~
    itemByKeyRoute ~
    uploadJobZipRoute ~
    optionAllRoute ~
    uploadFileRoute
  }

  def createJobRoute: Route = pathPost("create") {
    entity(jacksonAs[JobCreateReq]) { req =>
      futureComplete(jobService.createJob(req))
    }
  }

  def updateJobRoute: Route = pathPost("update") {
    entity(jacksonAs[JobUpdateReq]) { req =>
      futureComplete(jobService.updateJob(req))
    }
  }

  def itemByKeyRoute: Route = pathGet("item" / Segment) { key =>
    futureComplete(jobService.findItemByKey(key))
  }

  def pageRoute: Route = pathGet("page") {
    parameters(pagePDM).as(JobPageReq.apply _) { req =>
      futureComplete(jobService.page(req))
    }
  }

  def uploadJobZipRoute: Route = pathPost("upload_job") {
    extractExecutionContext { implicit ec =>
      storeUploadedFile("job", createTempFileFunc(MassCore(system).tempDirectory)) {
        case (fileInfo, file) =>
          futureComplete(jobService.uploadJobOnZip(fileInfo, file.toPath))
      }
    }
  }

  def uploadFileRoute: Route = pathPost("upload_file") {
    extractExecutionContext { implicit ec =>
      uploadedFiles(createTempFileFunc(MassCore(system).tempDirectory)) { list =>
        futureComplete(jobService.uploadFiles(list))
      }
    }
  }

  def optionAllRoute: Route = pathGet("option_all") {
    futureComplete(jobService.listOption())
  }
} 
Example 32
Source File: JobService.scala    From fusion-data   with Apache License 2.0 5 votes vote down vote up
package mass.job.service.job

import java.io.File
import java.nio.charset.StandardCharsets
import java.nio.file.{ Files, Path }

import akka.actor.typed.{ ActorRef, ActorSystem }
import akka.actor.typed.scaladsl.AskPattern._
import akka.http.scaladsl.server.directives.FileInfo
import akka.util.Timeout
import javax.inject.{ Inject, Singleton }
import mass.job.service.job.JobActor.CommandReply
import mass.message.job._

import scala.collection.immutable
import scala.concurrent.duration._
import scala.concurrent.{ ExecutionContext, Future }
import scala.reflect.ClassTag

@Singleton
class JobService @Inject() (implicit system: ActorSystem[_]) {
  implicit val timeout: Timeout = Timeout(10.seconds)
  val jobActor: ActorRef[JobActor.Command] = JobActor.init(system)

  def listOption(): Future[JobGetAllOptionResp] = askToJob[JobGetAllOptionResp](JobGetAllOptionReq())

  def uploadFiles(list: immutable.Seq[(FileInfo, File)])(implicit ec: ExecutionContext): Future[JobUploadFilesResp] = {
    askToJob[JobUploadFilesResp](JobUploadFilesReq(list)).andThen {
      case _ => list.foreach { case (_, file) => Files.deleteIfExists(file.toPath) }
    }
  }

  def uploadJobOnZip(fileInfo: FileInfo, file: Path)(implicit ec: ExecutionContext): Future[JobUploadJobResp] = {
    val req = JobUploadJobReq(
      file,
      fileInfo.fileName,
      fileInfo.contentType.charsetOption.map(_.nioCharset()).getOrElse(StandardCharsets.UTF_8))
    askToJob[JobUploadJobResp](req).andThen { case _ => Files.deleteIfExists(file) }
  }

  def updateTrigger(req: JobUpdateReq): Future[JobSchedulerResp] = askToJob[JobSchedulerResp](req)

  def page(req: JobPageReq): Future[JobPageResp] = askToJob[JobPageResp](req)

  def findItemByKey(key: String): Future[JobSchedulerResp] = askToJob[JobSchedulerResp](JobFindReq(key = key))

  def createJob(req: JobCreateReq): Future[JobCreateResp] = askToJob[JobCreateResp](req)

  def updateJob(req: JobUpdateReq): Future[JobSchedulerResp] = askToJob[JobSchedulerResp](req)

  @inline private def askToJob[RESP](req: JobMessage)(implicit tag: ClassTag[RESP]): Future[RESP] =
    jobActor.ask[JobResponse](replyTo => CommandReply(req, replyTo)).mapTo[RESP]
} 
Example 33
Source File: ES.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package storage.es

import com.sksamuel.elastic4s.{ElasticsearchClientUri, TcpClient}
import com.sksamuel.elastic4s.ElasticDsl._
import com.sksamuel.elastic4s.bulk.RichBulkResponse
import java.io.File
import javax.inject.{Inject, Singleton}
import org.elasticsearch.common.settings.Settings
import org.elasticsearch.common.xcontent.XContentType
import play.api.{Configuration, Logger}
import play.api.inject.ApplicationLifecycle
import scala.io.Source
import scala.concurrent.{Await, Future, ExecutionContext}
import scala.concurrent.duration._
import scala.util.{Try, Success, Failure}



  private def loadMappings(existingMappings: Seq[String] = Seq.empty[String]): Seq[(String, String)] =
    new File("conf/es-mappings").listFiles.toSeq.filter(_.getName.endsWith(".json"))
      .foldLeft(Seq.empty[(Int, (String, String))])((mappings, file)  => {
        val number = file.getName.substring(0, 2).toInt
        val name = file.getName.substring(3, file.getName.lastIndexOf('.'))
        if (existingMappings.contains(name)) {
          mappings
        } else {
          val json = Source.fromFile(file).getLines.mkString("\n")
          mappings :+ (number, (name, json))
        }
      }).sortBy(_._1).map(_._2)
      
  
  def countTotalDocs()(implicit ctx: ExecutionContext): Future[Long] =
    client execute {
      search(ES.RECOGITO) limit 0
    } map { _.totalHits }

} 
Example 34
Source File: AnnotationMigrationUtil.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package storage.es.migration

import com.sksamuel.elastic4s.{Hit, HitReader}
import com.sksamuel.elastic4s.ElasticDsl._
import com.sksamuel.elastic4s.searches.RichSearchResponse
import javax.inject.{Inject, Singleton}
import play.api.libs.json.Json
import scala.concurrent.{ExecutionContext, Future}
import services.annotation.AnnotationService
import services.entity.builtin.EntityService
import storage.es.{ES, HasScrollProcessing}

class AnnotationMigrationUtil @Inject()(
  annotationService: AnnotationService,
  entityService: EntityService,
  implicit val ctx: ExecutionContext,
  implicit val es: ES
) extends HasScrollProcessing {

  implicit object LegacyAnnotationHitReader extends HitReader[LegacyAnnotation] {
    override def read(hit: Hit): Either[Throwable, LegacyAnnotation] =
      Right(Json.fromJson[LegacyAnnotation](Json.parse(hit.sourceAsString)).get)
  }

  private val SOURCE_INDEX_LEGACY = "recogito_v22"

  private val DEST_INDEX_NEW = "recogito"

  private def reindex(response: RichSearchResponse): Future[Boolean] = {
    val hits = response.to[LegacyAnnotation]
    annotationService.upsertAnnotations(
      annotations = hits.map(_.toNewAPI),
      versioned = false
    ).map(_.isEmpty)
  }

  def runMigration: Future[Boolean] =
    es.client execute {
      search(SOURCE_INDEX_LEGACY / ES.ANNOTATION) query matchAllQuery limit 200 scroll "5m"
    } flatMap { scroll(reindex, _) } map { success =>
      if (success) play.api.Logger.info("Migration completed successfully. Yay!")
      else play.api.Logger.info("Migration stopped. Something went wrong.")
      success
    }

} 
Example 35
Source File: DB.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package storage.db

import akka.actor.ActorSystem
import com.google.inject.AbstractModule
import java.sql.Connection
import javax.inject.{ Inject, Singleton }
import services.user.UserService
import services.user.Roles
import org.jooq.impl.DSL
import org.jooq.{ SQLDialect, DSLContext }
import play.api.Logger
import play.api.db.Database
import scala.collection.JavaConversions._
import scala.concurrent.{ ExecutionContext, Future }
import scala.io.Source

object DB {

  val CURRENT_SQLDIALECTT = SQLDialect.POSTGRES_9_4

}


  private def initDB(connection: Connection) = {

    // Splitting by ; is not 100% robust - but should be sufficient for our own schema file
    val statement = connection.createStatement

    Source.fromFile("conf/schema.sql", "UTF-8")
      .getLines().map(_.trim)
      .filter(line => !(line.startsWith("--") || line.isEmpty))
      .mkString(" ").split(";")
      .foreach(s => {
        statement.addBatch(s + ";")
      })

    statement.executeBatch()
    statement.close()
  }
  
  private def createDefaultUserIfEmpty() =
    userService.countUsers.map { count =>
      if (count == 0) {
        Logger.warn("#######################################################")
        Logger.warn("# Empty user table - creating default recogito/recogito")
        Logger.warn("#######################################################")
        
        val f = for {
          _ <- userService.insertUser("recogito", "[email protected]", "recogito", false)
          _ <- userService.insertUserRole("recogito", Roles.Admin)
        } yield()
  
        f.map { _ =>
          Logger.warn("# Done. Make sure to remove this user in production!")
          Logger.warn("#######################################################")
        } recover { case t: Throwable => t.printStackTrace() }
      }
    } recover { case t: Throwable =>
      t.printStackTrace()
    }

} 
Example 36
Source File: JobNotifyApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import akka.actor.ActorSystem
import asura.common.model.ApiRes
import asura.core.es.model.JobNotify
import asura.core.es.service.JobNotifyService
import asura.core.model.QueryJobNotify
import asura.core.notify.JobNotifyManager
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents

import scala.concurrent.ExecutionContext

@Singleton
class JobNotifyApi @Inject()(
                              implicit system: ActorSystem,
                              exec: ExecutionContext,
                              val controllerComponents: SecurityComponents,
                            ) extends BaseApi {

  def all() = Action {
    OkApiRes(ApiRes(data = JobNotifyManager.all()))
  }

  def put() = Action(parse.byteString).async { implicit req =>
    val notify = req.bodyAs(classOf[JobNotify])
    val user = getProfileId()
    notify.fillCommonFields(user)
    JobNotifyService.index(notify).toOkResult
  }

  def update(id: String) = Action(parse.byteString).async { implicit req =>
    val notify = req.bodyAs(classOf[JobNotify])
    JobNotifyService.updateNotify(id, notify).toOkResult
  }

  def delete(id: String) = Action(parse.byteString).async { implicit req =>
    JobNotifyService.deleteDoc(id).toOkResult
  }

  def query() = Action(parse.byteString).async { implicit req =>
    val queryNotify = req.bodyAs(classOf[QueryJobNotify])
    JobNotifyService.querySubscribers(queryNotify).toOkResultByEsList(true)
  }
} 
Example 37
Source File: RestApiApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import asura.core.es.model.RestApi
import asura.core.es.service.ApiService
import asura.core.model.QueryApi
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents

import scala.concurrent.ExecutionContext

@Singleton
class RestApiApi @Inject()(implicit exec: ExecutionContext, val controllerComponents: SecurityComponents)
  extends BaseApi {

  def getById(id: String) = Action.async { implicit req =>
    ApiService.getById(id).toOkResultByEsOneDoc(id)
  }

  def getOne() = Action(parse.byteString).async { implicit req =>
    val api = req.bodyAs(classOf[RestApi])
    ApiService.getOne(api).toOkResultByEsOneDoc(api.generateId())
  }

  def put() = Action(parse.byteString).async { implicit req =>
    val api = req.bodyAs(classOf[RestApi])
    api.fillCommonFields(getProfileId())
    ApiService.index(api).toOkResult
  }

  def query() = Action(parse.byteString).async { implicit req =>
    val query = req.bodyAs(classOf[QueryApi])
    ApiService.queryApi(query).toOkResultByEsList()
  }
} 
Example 38
Source File: ActivityApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import akka.actor.ActorSystem
import asura.common.model.ApiRes
import asura.core.es.model.Activity
import asura.core.es.service._
import asura.core.model.{AggsQuery, SearchAfterActivity}
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents

import scala.concurrent.ExecutionContext

@Singleton
class ActivityApi @Inject()(implicit system: ActorSystem,
                            val exec: ExecutionContext,
                            val controllerComponents: SecurityComponents
                           ) extends BaseApi {

  def trend(groups: Boolean = true) = Action(parse.byteString).async { implicit req =>
    val aggs = req.bodyAs(classOf[AggsQuery])
    aggs.types = Seq(Activity.TYPE_TEST_CASE)
    val res = for {
      trends <- ActivityService.trend(aggs)
    } yield trends
    res.map(trends => {
      OkApiRes(ApiRes(data = Map("trends" -> trends)))
    })
  }

  def aggTerms() = Action(parse.byteString).async { implicit req =>
    val aggs = req.bodyAs(classOf[AggsQuery])
    ActivityService.aggTerms(aggs).toOkResult
  }

  def recent(wd: String = null, discover: Boolean = false) = Action(parse.byteString).async { implicit req =>
    RecommendService.getRecommendProjects(getProfileId(), wd, discover).toOkResult
  }

  def feed() = Action(parse.byteString).async { implicit req =>
    val query = req.bodyAs(classOf[SearchAfterActivity])
    if (query.onlyMe) {
      query.user = getProfileId()
    }
    ActivityService.searchFeed(query).toOkResult
  }
} 
Example 39
Source File: CountApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import asura.core.es.model._
import asura.core.es.service.CountService
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents

import scala.concurrent.ExecutionContext

@Singleton
class CountApi @Inject()(implicit exec: ExecutionContext, val controllerComponents: SecurityComponents)
  extends BaseApi {

  def all() = Action.async { implicit req =>
    val countRes = for {
      http <- CountService.countIndex(HttpCaseRequest.Index)
      dubbo <- CountService.countIndex(DubboRequest.Index)
      sql <- CountService.countIndex(SqlRequest.Index)
      scenario <- CountService.countIndex(Scenario.Index)
      job <- CountService.countIndex(Job.Index)
      webHttp <- CountService.countActivity(Activity.TYPE_TEST_CASE)
      webDubbo <- CountService.countActivity(Activity.TYPE_TEST_DUBBO)
      webSql <- CountService.countActivity(Activity.TYPE_TEST_SQL)
      webScenario <- CountService.countActivity(Activity.TYPE_TEST_SCENARIO)
      webJob <- CountService.countActivity(Activity.TYPE_TEST_JOB)
      ciJob <- CountService.countJob(JobReport.TYPE_CI)
      quartzJob <- CountService.countJob(JobReport.TYPE_QUARTZ)
    } yield (
      http, dubbo, sql, scenario, job,
      webHttp, webDubbo, webSql, webScenario, webJob,
      ciJob, quartzJob,
    )
    countRes.map(tuple => {
      Map(
        "http" -> tuple._1,
        "dubbo" -> tuple._2,
        "sql" -> tuple._3,
        "scenario" -> tuple._4,
        "job" -> tuple._5,
        "webHttp" -> tuple._6,
        "webDubbo" -> tuple._7,
        "webSql" -> tuple._8,
        "webScenario" -> tuple._9,
        "webJob" -> tuple._10,
        "ciJob" -> tuple._11,
        "quartzJob" -> tuple._12,
      )
    }).flatMap(count => {
      val histogramRes = for {
        httpHistogram <- CountService.dateHistogram(HttpCaseRequest.Index)
        dubboHistogram <- CountService.dateHistogram(DubboRequest.Index)
        sqlHistogram <- CountService.dateHistogram(SqlRequest.Index)
        scenarioHistogram <- CountService.dateHistogram(Scenario.Index)
        jobHistogram <- CountService.dateHistogram(Job.Index)
        webHttpHistogram <- CountService.activityDateHistogram(Activity.TYPE_TEST_CASE)
        webDubboHistogram <- CountService.activityDateHistogram(Activity.TYPE_TEST_DUBBO)
        webSqlHistogram <- CountService.activityDateHistogram(Activity.TYPE_TEST_SQL)
        webScenarioHistogram <- CountService.activityDateHistogram(Activity.TYPE_TEST_SCENARIO)
        webJobHistogram <- CountService.activityDateHistogram(Activity.TYPE_TEST_JOB)
        ciJobHistogram <- CountService.jobDateHistogram(JobReport.TYPE_CI)
        quartzJobHistogram <- CountService.jobDateHistogram(JobReport.TYPE_QUARTZ)
      } yield (
        httpHistogram, dubboHistogram, sqlHistogram, scenarioHistogram, jobHistogram,
        webHttpHistogram, webDubboHistogram, webSqlHistogram, webScenarioHistogram, webJobHistogram,
        ciJobHistogram, quartzJobHistogram
      )
      histogramRes.map(tuple => {
        Map(
          "http" -> tuple._1,
          "dubbo" -> tuple._2,
          "sql" -> tuple._3,
          "scenario" -> tuple._4,
          "job" -> tuple._5,
          "webHttp" -> tuple._6,
          "webDubbo" -> tuple._7,
          "webSql" -> tuple._8,
          "webScenario" -> tuple._9,
          "webJob" -> tuple._10,
          "ciJob" -> tuple._11,
          "quartzJob" -> tuple._12,
        )
      }).map(histogram => {
        Map("count" -> count, "histogram" -> histogram)
      })
    }).toOkResult
  }
} 
Example 40
Source File: EnvApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import asura.app.AppErrorMessages
import asura.common.model.{ApiRes, ApiResError}
import asura.core.ErrorMessages
import asura.core.auth.AuthManager
import asura.core.es.EsResponse
import asura.core.es.model.Environment
import asura.core.es.service.{EnvironmentService, HttpCaseRequestService, JobService, ScenarioService}
import asura.core.model.QueryEnv
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class EnvApi @Inject()(implicit exec: ExecutionContext, val controllerComponents: SecurityComponents)
  extends BaseApi {

  def getById(id: String) = Action.async { implicit req =>
    EnvironmentService.getEnvById(id).map(env => {
      if (null != env.auth && env.auth.nonEmpty) {
        env.auth.foreach(authData => {
          AuthManager(authData.`type`).foreach(_.mask(authData))
        })
      }
      env
    }).toOkResult
  }

  def put(group: String, project: String) = Action(parse.byteString).async { implicit req =>
    val env = req.bodyAs(classOf[Environment])
    env.fillCommonFields(getProfileId())
    EnvironmentService.index(env).toOkResult
  }

  def update(group: String, project: String, id: String) = Action(parse.byteString).async { implicit req =>
    val env = req.bodyAs(classOf[Environment])
    env.fillCommonFields(getProfileId())
    EnvironmentService.updateEnv(id, env).toOkResult
  }

  def query() = Action(parse.byteString).async { implicit req =>
    val queryEnv = req.bodyAs(classOf[QueryEnv])
    EnvironmentService.queryEnv(queryEnv).toOkResultByEsList()
  }

  def getAllAuth() = Action {
    OkApiRes(ApiRes(data = AuthManager.getAll()))
  }

  def delete(id: String, preview: Option[Boolean]) = Action.async { implicit req =>
    val ids = Seq(id)
    val res = for {
      c <- HttpCaseRequestService.containEnv(ids)
      s <- ScenarioService.containEnv(ids)
      j <- JobService.containEnv(ids)
    } yield (c, s, j)
    res.flatMap(resTriple => {
      val (caseRes, scenarioRes, jobRes) = resTriple
      if (caseRes.isSuccess && scenarioRes.isSuccess && jobRes.isSuccess) {
        if (preview.nonEmpty && preview.get) {
          Future.successful(toActionResultFromAny(Map(
            "case" -> EsResponse.toApiData(caseRes.result),
            "scenario" -> EsResponse.toApiData(scenarioRes.result),
            "job" -> EsResponse.toApiData(jobRes.result)
          )))
        } else {
          if (caseRes.result.isEmpty && scenarioRes.result.isEmpty && jobRes.result.isEmpty) {
            EnvironmentService.deleteDoc(id).toOkResult
          } else {
            Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_CantDeleteEnv))))
          }
        }
      } else {
        val errorRes = if (!scenarioRes.isSuccess) scenarioRes else jobRes
        ErrorMessages.error_EsRequestFail(errorRes).toFutureFail
      }
    })
  }
} 
Example 41
Source File: UserApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import akka.actor.ActorSystem
import asura.app.AppErrorMessages
import asura.app.api.model.UserProfile
import asura.common.model.{ApiRes, ApiResError}
import asura.common.util.StringUtils
import asura.core.es.actor.ActivitySaveActor
import asura.core.es.model.{Activity, BaseIndex, UserProfile => EsUserProfile}
import asura.core.es.service.UserProfileService
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.core.profile.{CommonProfile, ProfileManager}
import org.pac4j.ldap.profile.LdapProfile
import org.pac4j.play.PlayWebContext
import org.pac4j.play.scala.SecurityComponents
import org.pac4j.play.store.PlaySessionStore
import play.api.Configuration

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class UserApi @Inject()(
                         implicit val system: ActorSystem,
                         val exec: ExecutionContext,
                         val configuration: Configuration,
                         val sessionStore: PlaySessionStore,
                         val controllerComponents: SecurityComponents
                       ) extends BaseApi {

  val administrators = configuration.getOptional[Seq[String]]("asura.admin").getOrElse(Nil).toSet
  val activityActor = system.actorOf(ActivitySaveActor.props())

  def login() = Action.async { implicit request =>
    val webContext = new PlayWebContext(request, sessionStore)
    val profileManager = new ProfileManager[CommonProfile](webContext)
    val profile = profileManager.get(true)
    if (!profile.isPresent) {
      Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_EmptyProfile))))
    } else {
      val commonProfile = profile.get()
      val token = commonProfile.getAttribute("token")
      val email = commonProfile.getAttribute("mail")
      if (null == token) {
        Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_TokenGeneratedError))))
      } else {
        val username = commonProfile.getId
        val emailStr = if (null != email) email.toString else StringUtils.EMPTY
        val apiUserProfile = UserProfile(
          token = token.toString,
          username = username,
          email = emailStr,
          isSysAdmin = administrators.contains(username)
        )
        UserProfileService.getProfileById(username)
          .flatMap(profile => {
            if (null != profile) {
              // already registered
              apiUserProfile.nickname = profile.nickname
              apiUserProfile.avatar = profile.avatar
              apiUserProfile.summary = profile.summary
              apiUserProfile.description = profile.description
              apiUserProfile.email = profile.email
              activityActor ! Activity(StringUtils.EMPTY, StringUtils.EMPTY, username, Activity.TYPE_USER_LOGIN, username)
              Future.successful(OkApiRes(ApiRes(data = apiUserProfile)))
            } else {
              // new user
              val esUserProfile = EsUserProfile(
                username = username,
                email = emailStr
              )
              if (commonProfile.isInstanceOf[LdapProfile]) {
                // first time login by ldap
                esUserProfile.fillCommonFields(BaseIndex.CREATOR_LDAP)
              } else {
                // not by ldap
                esUserProfile.fillCommonFields(BaseIndex.CREATOR_STANDARD)
              }
              UserProfileService.index(esUserProfile).map(indexResponse => {
                activityActor ! Activity(StringUtils.EMPTY, StringUtils.EMPTY, username, Activity.TYPE_NEW_USER, username)
                if (StringUtils.isNotEmpty(indexResponse.id)) {
                  OkApiRes(ApiRes(data = apiUserProfile))
                } else {
                  OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_FailToCreateUser)))
                }
              })
            }
          })
      }
    }
  }

  def get() = Action(parse.byteString).async { implicit req =>
    UserProfileService.getProfileById(getProfileId()).toOkResult
  }

  def update() = Action(parse.byteString).async { implicit req =>
    val userProfile = req.bodyAs(classOf[EsUserProfile])
    UserProfileService.updateProfile(userProfile).toOkResult
  }
} 
Example 42
Source File: ClusterApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import akka.actor.ActorSystem
import akka.pattern.ask
import akka.util.Timeout
import asura.app.AppErrorMessages
import asura.cluster.ClusterManager
import asura.cluster.actor.MemberListenerActor.GetAllMembers
import asura.common.model.ApiResError
import asura.core.CoreConfig
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents
import play.api.Configuration
import play.api.mvc.{RequestHeader, Result}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ClusterApi @Inject()(
                            implicit val system: ActorSystem,
                            val exec: ExecutionContext,
                            val configuration: Configuration,
                            val controllerComponents: SecurityComponents
                          ) extends BaseApi {

  implicit val timeout: Timeout = CoreConfig.DEFAULT_ACTOR_ASK_TIMEOUT

  def getMembers() = Action(parse.byteString).async { implicit req =>
    checkClusterEnabled {
      (ClusterManager.clusterManagerActor ? GetAllMembers).toOkResult
    }
  }

  private def checkClusterEnabled(func: => Future[Result])(implicit request: RequestHeader): Future[Result] = {
    if (ClusterManager.enabled) {
      func
    } else {
      Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_ClusterNotEnabled))))
    }
  }
} 
Example 43
Source File: SwaggerApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents

@Singleton
class SwaggerApi @Inject()(val controllerComponents: SecurityComponents) extends BaseApi {

  def home() = Action {
    Redirect("/openapi/swagger-ui/index.html?url=/assets/swagger.json", MOVED_PERMANENTLY)
  }

  def editor(url: Option[String]) = Action {
    val param = if (url.nonEmpty) s"?url=${url.get}" else ""
    Redirect(s"/openapi/swagger-editor/index.html${param}", MOVED_PERMANENTLY)
  }
} 
Example 44
Source File: HomeApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import asura.common.model.ApiRes
import asura.core.es.model._
import asura.core.es.service.HomeService
import asura.core.model.QueryHome
import asura.play.api.BaseApi.OkApiRes
import controllers.Assets
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents
import play.api.http.HttpErrorHandler
import play.api.mvc.{Action, AnyContent}

import scala.concurrent.ExecutionContext

@Singleton
class HomeApi @Inject()(
                         implicit exec: ExecutionContext,
                         val controllerComponents: SecurityComponents,
                         val assets: Assets,
                         val errorHandler: HttpErrorHandler,
                       )
  extends BaseApi {

  def index() = assets.at("index.html")

  def asset(resource: String): Action[AnyContent] = {
    if (resource.startsWith("api") || resource.startsWith("openapi")) {
      Action.async(r => errorHandler.onClientError(r, NOT_FOUND, "Not found"))
    } else {
      if (resource.contains(".")) assets.at(resource) else index
    }
  }

  def query() = Action(parse.byteString).async { implicit req =>
    val queryHome = req.bodyAs(classOf[QueryHome])
    HomeService.queryDoc(queryHome).map(res => {
      OkApiRes(ApiRes(data = res.result.hits.hits.map(hit => {
        hit.sourceAsMap ++ Seq(
          (FieldKeys.FIELD__ID -> hit.id),
          ("_type" -> getDocType(hit.index))
        )
      })))
    })
  }

  private def getDocType(index: String): String = {
    index match {
      case Group.Index => "group"
      case Project.Index => "project"
      case RestApi.Index => "rest"
      case HttpCaseRequest.Index => "case"
      case DubboRequest.Index => "dubbo"
      case SqlRequest.Index => "sql"
      case Environment.Index => "env"
      case Scenario.Index => "scenario"
      case Job.Index => "job"
      case _ => index
    }
  }
} 
Example 45
Source File: CiApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api.ci

import akka.actor.ActorSystem
import akka.stream.scaladsl.Source
import akka.stream.{Materializer, OverflowStrategy}
import asura.common.actor.SenderMessage
import asura.core.ci.{CiManager, CiTriggerEventMessage}
import asura.core.job.actor.JobCiActor
import asura.play.api.BaseApi
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents
import play.api.http.ContentTypes
import play.api.libs.EventSource
import play.api.libs.streams.ActorFlow
import play.api.mvc.{Codec, WebSocket}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class CiApi @Inject()(
                       implicit val system: ActorSystem,
                       implicit val exec: ExecutionContext,
                       implicit val mat: Materializer,
                       val controllerComponents: SecurityComponents
                     ) extends BaseApi {

  implicit val codec = Codec.utf_8

  def home() = Action {
    Ok("CI")
  }

  def trigger() = Action(parse.byteString).async { implicit req =>
    val msg = req.bodyAs(classOf[CiTriggerEventMessage])
    CiManager.eventSource(msg)
    Future.successful(Ok("OK"))
  }

  def jobWS(id: String) = WebSocket.accept[String, String] { implicit req =>
    ActorFlow.actorRef(out => JobCiActor.props(id, out))
  }

  def jobSSE(id: String) = Action {
    val ciActor = system.actorOf(JobCiActor.props(id))
    val source = Source.actorRef[String](BaseApi.DEFAULT_SOURCE_BUFFER_SIZE, OverflowStrategy.dropHead)
      .mapMaterializedValue(ref => ciActor ! SenderMessage(ref))
    Ok.chunked(source via EventSource.flow)
      .as(ContentTypes.EVENT_STREAM)
      .withHeaders(BaseApi.responseNoCacheHeaders: _*)
  }
} 
Example 46
Source File: LinkerdApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import asura.app.api.model.Dtabs
import asura.app.api.model.Dtabs.DtabItem
import asura.common.exceptions.ErrorMessages.ErrorMessage
import asura.common.model.{ApiRes, ApiResError}
import asura.core.http.HttpEngine
import asura.core.{CoreConfig, ErrorMessages}
import asura.namerd.DtabEntry
import asura.namerd.api.v1.NamerdV1Api
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents
import play.api.Configuration

import scala.collection.mutable.ArrayBuffer
import scala.concurrent.{ExecutionContext, Future}


@Singleton
class LinkerdApi @Inject()(
                            implicit val exec: ExecutionContext,
                            val controllerComponents: SecurityComponents,
                            config: Configuration,
                          ) extends BaseApi {

  val srcPrefix = "/svc/"
  val dstPrefix = "/$/inet/"

  def getProxyServers() = Action { implicit req =>
    if (CoreConfig.linkerdConfig.enabled) {
      OkApiRes(ApiRes(data = CoreConfig.linkerdConfig.servers))
    } else {
      OkApiRes(ApiResError(getI18nMessage(ErrorMessages.error_ProxyDisabled.name)))
    }
  }

  def getHttp(group: String, project: String, server: String) = Action.async { implicit req =>
    if (CoreConfig.linkerdConfig.enabled) {
      val proxyServer = CoreConfig.linkerdConfig.servers.find(_.tag.equals(server)).get
      NamerdV1Api.getNamespaceDtabs(proxyServer.namerd, proxyServer.httpNs)(HttpEngine.http).map(dtabs => {
        val items = ArrayBuffer[DtabItem]()
        dtabs.foreach(entry => {
          val pStrs = entry.prefix.split("/")
          val dStrs = entry.dst.split("/")
          if (pStrs.length == 5 && dStrs.length == 5) {
            items += DtabItem(
              group = pStrs(2),
              project = pStrs(3),
              namespace = pStrs(4),
              host = dStrs(3),
              port = dStrs(4),
              owned = group == pStrs(2) && project == pStrs(3)
            )
          }
        })
        toActionResultFromAny(items)
      })
    } else {
      Future.successful(OkApiRes(ApiResError(getI18nMessage(ErrorMessages.error_ProxyDisabled.name))))
    }
  }

  def putHttp(group: String, project: String, server: String) = Action(parse.byteString).async { implicit req =>
    if (CoreConfig.linkerdConfig.enabled) {
      val proxyServer = CoreConfig.linkerdConfig.servers.find(_.tag.equals(server)).get
      val dtabs = req.bodyAs(classOf[Dtabs])
      if (null != dtabs && null != dtabs.dtabs && dtabs.dtabs.nonEmpty) {
        var error: ErrorMessage = null
        val entries = ArrayBuffer[DtabEntry]()
        for (i <- 0 until dtabs.dtabs.length if null == error) {
          val item = dtabs.dtabs(i)
          error = item.isValid()
          entries += DtabEntry(
            s"${srcPrefix}${item.group}/${item.project}/${item.namespace}",
            s"${dstPrefix}${item.host}/${item.port}"
          )
        }
        if (null == error) {
          NamerdV1Api.updateNamespaceDtabs(proxyServer.namerd, proxyServer.httpNs, entries)(HttpEngine.http).toOkResult
        } else {
          error.toFutureFail
        }
      } else {
        Future.successful(OkApiRes(ApiRes()))
      }
    } else {
      Future.successful(OkApiRes(ApiResError(getI18nMessage(ErrorMessages.error_ProxyDisabled.name))))
    }
  }
} 
Example 47
Source File: ConfigApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import akka.actor.ActorSystem
import asura.common.model.ApiRes
import asura.core.assertion.Assertions
import asura.core.script.function.Functions
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents

import scala.concurrent.ExecutionContext

@Singleton
class ConfigApi @Inject()(implicit system: ActorSystem,
                          val exec: ExecutionContext,
                          val controllerComponents: SecurityComponents
                         ) extends BaseApi {

  def getBasics() = Action {
    OkApiRes(ApiRes(data = Map(
      "assertions" -> Assertions.getAll(),
      "transforms" -> Functions.getAllTransforms(),
    )))
  }

  def getAllAssertions() = Action {
    OkApiRes(ApiRes(data = Assertions.getAll()))
  }

  def getAllTransforms() = Action {
    OkApiRes(ApiRes(data = Functions.getAllTransforms()))
  }
} 
Example 48
Source File: ScenarioApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import akka.actor.ActorSystem
import asura.app.AppErrorMessages
import asura.common.model.ApiResError
import asura.core.ErrorMessages
import asura.core.es.EsResponse
import asura.core.es.actor.ActivitySaveActor
import asura.core.es.model.{Activity, Scenario}
import asura.core.es.service._
import asura.core.model.QueryScenario
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ScenarioApi @Inject()(
                             implicit system: ActorSystem,
                             val exec: ExecutionContext,
                             val controllerComponents: SecurityComponents
                           ) extends BaseApi {

  val activityActor = system.actorOf(ActivitySaveActor.props())

  def getById(id: String) = Action.async { implicit req =>
    ScenarioService.getRelativesById(id).toOkResult
  }

  def copyById(id: String) = Action.async { implicit req =>
    ScenarioService.getScenarioById(id).flatMap(scenario => {
      scenario.fillCommonFields(getProfileId())
      ScenarioService.index(scenario)
    }).toOkResult
  }

  def delete(id: String, preview: Option[Boolean]) = Action.async { implicit req =>
    JobService.containScenario(Seq(id)).flatMap(res => {
      if (res.isSuccess) {
        if (preview.nonEmpty && preview.get) {
          Future.successful(toActionResultFromAny(Map(
            "job" -> EsResponse.toApiData(res.result)
          )))
        } else {
          if (res.result.isEmpty) {
            ScenarioService.deleteDoc(id).toOkResult
          } else {
            Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_CantDeleteScenario))))
          }
        }
      } else {
        ErrorMessages.error_EsRequestFail(res).toFutureFail
      }
    })
  }

  def put() = Action(parse.byteString).async { implicit req =>
    val scenario = req.bodyAs(classOf[Scenario])
    val user = getProfileId()
    scenario.fillCommonFields(user)
    ScenarioService.index(scenario).map(res => {
      activityActor ! Activity(scenario.group, scenario.project, user, Activity.TYPE_NEW_SCENARIO, res.id)
      toActionResultFromAny(res)
    })
  }

  def query() = Action(parse.byteString).async { implicit req =>
    val queryScenario = req.bodyAs(classOf[QueryScenario])
    ScenarioService.queryScenario(queryScenario).toOkResultByEsList()
  }

  def update(id: String) = Action(parse.byteString).async { implicit req =>
    val scenario = req.bodyAs(classOf[Scenario])
    ScenarioService.updateScenario(id, scenario).map(res => {
      activityActor ! Activity(scenario.group, scenario.project, getProfileId(), Activity.TYPE_UPDATE_SCENARIO, id)
      res
    }).toOkResult
  }
} 
Example 49
Source File: ErrorHandler.scala    From asura   with MIT License 5 votes vote down vote up
package asura.play.hook

import asura.common.exceptions.ErrorMessages
import asura.common.exceptions.ErrorMessages.ErrorMessageException
import asura.common.model.{ApiCode, ApiRes, ApiResError}
import asura.common.util.{LogUtils, StringUtils}
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.slf4j.LoggerFactory
import play.api.http.HttpErrorHandler
import play.api.i18n.{Langs, MessagesApi}
import play.api.mvc.{RequestHeader, Result}

import scala.concurrent.Future

@Singleton
class ErrorHandler @Inject()(messagesApi: MessagesApi, langs: Langs) extends HttpErrorHandler with ErrorMessages {

  lazy val logger = LoggerFactory.getLogger(classOf[ErrorHandler])

  override def onClientError(request: RequestHeader, statusCode: Int, message: String): Future[Result] = {
    val msg = s""""${request.method} ${request.uri}" ${statusCode} ${if (StringUtils.isNotEmpty(message)) message else ""}"""
    Future.successful(OkApiRes(ApiResError(msg)))
  }

  override def onServerError(request: RequestHeader, exception: Throwable): Future[Result] = {
    val logStack = LogUtils.stackTraceToString(exception)
    logger.warn(logStack)
    val requestLocal = request.headers.get("Local")
    implicit val lang = if (requestLocal.nonEmpty) {
      langs.availables.find(_.code == requestLocal.get).getOrElse(langs.availables.head)
    } else {
      langs.availables.head
    }
    exception match {
      case errMsgException: ErrorMessageException =>
        val errMsg = messagesApi(errMsgException.error.name, errMsgException.error.errMsg)
        Future.successful(OkApiRes(ApiRes(code = ApiCode.ERROR, msg = errMsg, data = logStack)))
      case _ =>
        val message = if (StringUtils.isNotEmpty(exception.getMessage)) {
          exception.getMessage
        } else {
          messagesApi(error_ServerError.name)
        }
        Future.successful(OkApiRes(ApiRes(code = ApiCode.ERROR, msg = message, data = logStack)))
    }
  }
} 
Example 50
Source File: DBService.scala    From template-site   with MIT License 5 votes vote down vote up
package services.db

import javax.inject.{Inject, Singleton}

import com.google.inject.ImplementedBy
import play.api.db.slick.DatabaseConfigProvider
import slick.dbio.{DBIOAction, NoStream}
import slick.driver.JdbcProfile

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}

@ImplementedBy(classOf[DBServiceImpl])
trait DBService {
  def runAsync[R](a: DBIOAction[R, NoStream, Nothing]): Future[R]

  def run[R](a: DBIOAction[R, NoStream, Nothing]): R
}

@Singleton
class DBServiceImpl @Inject()(val dbConfigProvider: DatabaseConfigProvider) extends DBService {
  private val db = dbConfigProvider.get[JdbcProfile].db

  def runAsync[R](a: DBIOAction[R, NoStream, Nothing]): Future[R] = {
    db.run(a)
  }

  def run[R](a: DBIOAction[R, NoStream, Nothing]): R = {
    Await.result(runAsync(a), Duration.Inf)
  }
} 
Example 51
Source File: HealthController.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package controllers

import javax.inject.{Inject, Singleton}
import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponents}
import vinyldns.core.health.HealthService

@Singleton
class HealthController @Inject() (components: ControllerComponents, healthService: HealthService)
    extends AbstractController(components)
    with CacheHeader {

  def health(): Action[AnyContent] = Action { implicit request =>
    healthService
      .checkHealth()
      .map {
        case Nil => Ok("OK").withHeaders(cacheHeaders: _*)
        case _ =>
          InternalServerError("There was an internal server error.").withHeaders(cacheHeaders: _*)
      }
      .unsafeRunSync()
  }
} 
Example 52
Source File: FrontendController.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package controllers

import actions.SecuritySupport
import javax.inject.{Inject, Singleton}
import models.{CustomLinks, DnsChangeNotices, Meta}
import org.slf4j.LoggerFactory
import play.api.Configuration
import play.api.mvc._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future


@Singleton
class FrontendController @Inject() (
    components: ControllerComponents,
    configuration: Configuration,
    securitySupport: SecuritySupport
) extends AbstractController(components) {

  implicit lazy val customLinks: CustomLinks = CustomLinks(configuration)
  implicit lazy val meta: Meta = Meta(configuration)
  private val logger = LoggerFactory.getLogger(classOf[FrontendController])
  private val userAction = securitySupport.frontendAction

  def loginPage(): Action[AnyContent] = securitySupport.loginPage()

  def noAccess(): Action[AnyContent] = securitySupport.noAccess()

  def logout(): Action[AnyContent] = securitySupport.logout()

  def index(): Action[AnyContent] = userAction.async { implicit request =>
    val canReview = request.user.isSuper || request.user.isSupport
    Future(
      Ok(
        views.html.dnsChanges
          .dnsChanges(request.user.userName, canReview)
      )
    )
  }

  def viewAllGroups(): Action[AnyContent] = userAction.async { implicit request =>
    Future(Ok(views.html.groups.groups(request.user.userName)))
  }

  def viewGroup(groupId: String): Action[AnyContent] = userAction.async { implicit request =>
    logger.info(s"View group for $groupId")
    Future(Ok(views.html.groups.groupDetail(request.user.userName)))
  }

  def viewAllZones(): Action[AnyContent] = userAction.async { implicit request =>
    Future(Ok(views.html.zones.zones(request.user.userName)))
  }

  def viewZone(zoneId: String): Action[AnyContent] = userAction.async { implicit request =>
    Future(Ok(views.html.zones.zoneDetail(request.user.userName, zoneId)))
  }

  def viewRecordSets(): Action[AnyContent] = userAction.async { implicit request =>
    Future(Ok(views.html.recordsets.recordSets(request.user.userName)))
  }

  def viewAllBatchChanges(): Action[AnyContent] = userAction.async { implicit request =>
    val canReview = request.user.isSuper || request.user.isSupport
    Future(
      Ok(
        views.html.dnsChanges
          .dnsChanges(request.user.userName, canReview)
      )
    )
  }

  def viewBatchChange(batchId: String): Action[AnyContent] = userAction.async { implicit request =>
    logger.info(s"View Batch Change for $batchId")
    val canReview = request.user.isSuper || request.user.isSupport
    val dnsChangeNotices = configuration.get[DnsChangeNotices]("dns-change-notices")
    Future(
      Ok(
        views.html.dnsChanges
          .dnsChangeDetail(request.user.userName, canReview, dnsChangeNotices)
      )
    )
  }

  def viewNewBatchChange(): Action[AnyContent] = userAction.async { implicit request =>
    Future(Ok(views.html.dnsChanges.dnsChangeNew(request.user.userName)))
  }
} 
Example 53
Source File: UserAccountAccessor.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package controllers

import cats.effect.{ContextShift, IO}
import cats.implicits._
import javax.inject.{Inject, Singleton}
import org.joda.time.DateTime
import vinyldns.core.domain.membership._

@Singleton
class UserAccountAccessor @Inject() (users: UserRepository, changes: UserChangeRepository) {

  implicit val cs: ContextShift[IO] = IO.contextShift(scala.concurrent.ExecutionContext.global)

  
  def get(identifier: String): IO[Option[User]] =
    users
      .getUser(identifier)
      .flatMap {
        case None => users.getUserByName(identifier)
        case found => IO(found)
      }

  def create(user: User): IO[User] =
    for {
      _ <- users.save(user)
      _ <- changes.save(UserChange.CreateUser(user, "system", DateTime.now))
    } yield user

  def update(user: User, oldUser: User): IO[User] =
    for {
      _ <- users.save(user)
      _ <- changes.save(UserChange.UpdateUser(user, "system", DateTime.now, oldUser))
    } yield user

  def getUserByKey(key: String): IO[Option[User]] =
    users.getUserByAccessKey(key)

  def getAllUsers: IO[List[User]] =
    users.getAllUsers

  def lockUsers(usersToLock: List[User]): IO[List[User]] = {
    val currentTime = DateTime.now
    for {
      lockedUsers <- users.save(usersToLock.map(_.copy(lockStatus = LockStatus.Locked)))
      _ <- usersToLock
        .zip(lockedUsers)
        .map {
          case (oldUser, newUser) =>
            changes.save(UserChange.UpdateUser(newUser, "system", currentTime, oldUser))
        }
        .parSequence
    } yield lockedUsers
  }
} 
Example 54
Source File: AuthorityFileService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.entity

import javax.inject.{Inject, Singleton}
import play.api.libs.json._
import play.api.libs.functional.syntax._
import scala.concurrent.ExecutionContext
import services.BaseService
import services.generated.Tables.AUTHORITY_FILE
import services.generated.tables.records.AuthorityFileRecord
import storage.db.DB

@Singleton
class AuthorityFileService @Inject() (val db: DB, implicit val ctx: ExecutionContext) extends BaseService {
  
  def listAll(eType: Option[EntityType] = None) = db.query { sql =>
    sql.selectFrom(AUTHORITY_FILE).fetchArray().toSeq
  }
  
  def findById(id: String) = db.query { sql =>
    Option(sql.selectFrom(AUTHORITY_FILE).where(AUTHORITY_FILE.ID.equal(id)).fetchOne())
  }
  
  def upsert(
    identifier: String,
    entityType: EntityType,
    shortname: String,
    fullname: Option[String],
    homepage: Option[String],
    shortcode: Option[String],
    color: Option[String],
    urlPatterns: Seq[String]
  ) = db.query { sql =>
    val authorityFile = new AuthorityFileRecord(
      identifier, 
      entityType.toString,
      shortname,
      optString(fullname),
      optString(homepage),
      optString(shortcode),
      optString(color),
      { if (urlPatterns.size > 0) urlPatterns.mkString(",")
         else null })      
    
    sql
      .insertInto(AUTHORITY_FILE)
      .set(authorityFile)
      .onDuplicateKeyUpdate()
      .set(authorityFile)
      .execute()
  }
  
  def delete(identifier: String) = db.query { sql =>
    sql
      .deleteFrom(AUTHORITY_FILE)
      .where(AUTHORITY_FILE.ID.equal(identifier))
      .execute() == 1
  }
  
}

object AuthorityFileService {
  
  implicit val authorityFileRecordWrites: Writes[AuthorityFileRecord] = (
    (JsPath \ "identifier").write[String] and
    (JsPath \ "authority_type").write[String] and
    (JsPath \ "shortname").write[String] and
    (JsPath \ "fullname").writeNullable[String] and
    (JsPath \ "homepage").writeNullable[String] and
    (JsPath \ "shortcode").writeNullable[String] and
    (JsPath \ "color").writeNullable[String] and
    (JsPath \ "url_patterns").writeNullable[Seq[String]]
  )(a => (
      a.getId,
      a.getAuthorityType,
      a.getShortname,
      Option(a.getFullname),
      Option(a.getHomepage),
      Option(a.getShortcode),
      Option(a.getColor),
      Option(a.getUrlPatterns).map(_.split(","))
    ))
  
} 
Example 55
Source File: LoginLogoutController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.landing

import com.mohiva.play.silhouette.api.{LoginInfo, Silhouette}
import controllers.{HasConfig, HasUserService, Security}
import java.util.UUID
import javax.inject.{Inject, Singleton}
import services.announcement.AnnouncementService
import services.user.UserService
import play.api.Configuration
import play.api.data.Form
import play.api.data.Forms._
import play.api.i18n.I18nSupport
import play.api.mvc.{AbstractController, ControllerComponents}
import scala.concurrent.{ ExecutionContext, Future }

case class LoginData(usernameOrPassword: String, password: String)

@Singleton
class LoginLogoutController @Inject() (  
  val announcements: AnnouncementService,
  val components: ControllerComponents,
  val config: Configuration,
  val silhouette: Silhouette[Security.Env],
  val users: UserService,
  implicit val ctx: ExecutionContext
) extends AbstractController(components) with HasConfig with HasUserService with I18nSupport {

  private val MESSAGE = "message"

  private val INVALID_LOGIN = "Invalid Username or Password"
  
  private val auth = silhouette.env.authenticatorService

  val loginForm = Form(
    mapping(
      "username" -> nonEmptyText,
      "password" -> nonEmptyText
    )(LoginData.apply)(LoginData.unapply)
  )

  def showLoginForm(destination: Option[String]) = Action { implicit request =>
    destination match {
      case None => Ok(views.html.landing.login(loginForm))
      case Some(dest) => Ok(views.html.landing.login(loginForm)).withSession("access_uri" -> dest)
    }
  }

  def processLogin = silhouette.UserAwareAction.async { implicit request =>    
    loginForm.bindFromRequest.fold(
      formWithErrors =>
        Future(BadRequest(views.html.landing.login(formWithErrors))),

      loginData =>
        users.validateUser(loginData.usernameOrPassword, loginData.password).flatMap {
          case Some(validUser) =>
            
            val destination = request.session.get("access_uri").getOrElse(routes.LandingController.index.toString)
            users.updateLastLogin(validUser.getUsername)
            
            val fAuthentication = auth.create(LoginInfo(Security.PROVIDER_ID, validUser.getUsername))
              .flatMap(auth.init(_))
                          
            fAuthentication.flatMap { authentication =>               
                auth.embed(authentication,
                  Redirect(destination).withSession(request.session - "access_uri"))
            }
          
          case None => Future(Redirect(routes.LoginLogoutController.showLoginForm()).flashing(MESSAGE -> INVALID_LOGIN))
        }
    )
  }

  def confirmServiceAnnouncement(id: UUID, response: String, destination: Option[String]) = silhouette.SecuredAction.async { implicit request =>
    announcements.confirm(id, request.identity.username, response).map { success =>
      if (success) destination.map(Redirect(_)).getOrElse(Redirect(routes.LandingController.index))
      else InternalServerError
    }
  }

  def logout = silhouette.SecuredAction.async { implicit request =>
    auth.discard(request.authenticator, Redirect(routes.LandingController.index))
  }

} 
Example 56
Source File: ResetPasswordController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.landing

import javax.inject.{Inject, Singleton}
import services.user.UserService
import services.generated.tables.records.UserRecord
import play.api.data.Form
import play.api.data.Forms._
import play.api.i18n.I18nSupport
import play.api.libs.mailer._
import play.api.mvc.{Action, AbstractController, ControllerComponents}
import scala.concurrent.{ExecutionContext, Future}

case class ResetPasswordData(email: String)

@Singleton
class ResetPasswordController @Inject() (
    val components: ControllerComponents,
    val users: UserService,
    val mailerClient: MailerClient,
    implicit val ctx: ExecutionContext
  ) extends AbstractController(components) with I18nSupport {
  
  val resetPasswordForm = Form(
    mapping("email" -> email)(ResetPasswordData.apply)(ResetPasswordData.unapply)
  )

  
  private def sendMail(user: UserRecord, newPassword: String) = Future {
    val name = Option(user.getRealName).getOrElse(user.getUsername)
    
    val message =
      s"""Dear $name,
        |
        |Your Recogito password was reset to
        |
        |   $newPassword
        |
        |Please log in to Recogito with this password. You can change it
        |in your personal Account Settings.
        |
        |Cheers,
        |the Recogito Team""".stripMargin
    
    // TODO this now hard-wires "[email protected]" as reply address
    // TODO see if we can take this directly from the config file instead
    val email = Email(
      "Your Recogito password was reset",
      "Recogito Team <[email protected]>",
      Seq(users.decryptEmail(user.getEmail)),
      Some(message)
    )
    
    mailerClient.send(email)
  } recover { case t: Throwable =>
    t.printStackTrace
  }
  
  def showResetForm = Action { implicit request =>
    Ok(views.html.landing.resetPassword(resetPasswordForm))
  }
  
  def resetPassword = Action.async { implicit request =>
    resetPasswordForm.bindFromRequest.fold(
      formWithErrors =>
        Future.successful(BadRequest(views.html.landing.resetPassword(formWithErrors))),

      resetData => 
        users.findByEmail(resetData.email).flatMap {
          case Some(user) => 
            users.resetPassword(user.getUsername).map { password =>
              sendMail(user, password)
              Ok(views.html.landing.resetPasswordOk())
            }
                       
          case None =>
            Future.successful(Redirect(routes.ResetPasswordController.showResetForm()).flashing("error" -> "Can't find that e-mail, sorry."))
        }
    )
  }
  
} 
Example 57
Source File: HelpController.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package controllers.help

import controllers.HasVisitLogging
import javax.inject.{Inject, Singleton}
import services.visit.VisitService
import org.webjars.play.WebJarsUtil
import play.api.{Configuration, Environment}
import play.api.mvc.{Action, AbstractController, ControllerComponents, RequestHeader}
import play.twirl.api.HtmlFormat
import scala.concurrent.ExecutionContext
import scala.io.Source
import scala.util.Try
import services.entity.{AuthorityFileService, EntityType}

@Singleton
class HelpController @Inject() (
  val authorities: AuthorityFileService,
  val components: ControllerComponents,
  val config: Configuration,
  val env: Environment,
  implicit val ctx: ExecutionContext,
  implicit val visits: VisitService,
  implicit val webjars: WebJarsUtil
) extends AbstractController(components) with HasVisitLogging {

  private val adminEmail = config.get[String]("admin.email")
  private val imprint =
    Try(Source.fromFile(env.getFile("conf/imprint"))).toOption.map { _.getLines.mkString("\n") }

  private def result(template: HtmlFormat.Appendable)(implicit request: RequestHeader) = {
    logPageView()
    Ok(template)
  }

  def localizedTutorial(lang: String) = Action { implicit request =>
    lang.toUpperCase match {
      case "DE" => result(views.html.help.tutorial.tutorial_de())
      case "ES" => result(views.html.help.tutorial.tutorial_es())
      case "FA" => result(views.html.help.tutorial.tutorial_fa())
      case "FR" => result(views.html.help.tutorial.tutorial_fr())
      case "IT" => result(views.html.help.tutorial.tutorial_it())
      case "NL" => result(views.html.help.tutorial.tutorial_nl())
      case "TR" => result(views.html.help.tutorial.tutorial_tr())
      case _ => NotFound(views.html.error404())
    }
  }

  def faq = Action.async { implicit request => 
    authorities.listAll(Some(EntityType.PLACE)).map { gazetteers =>
      result(views.html.help.faq(gazetteers)) 
    }
  }

  def index = Action { implicit request => result(views.html.help.index()) }

  def about        = Action { implicit request => result(views.html.help.general.about(imprint, adminEmail)) }
  def privacy      = Action { implicit request => result(views.html.help.general.privacy(adminEmail)) }
  def relations    = Action { implicit request => result(views.html.help.relations()) }
  def cloning      = Action { implicit request => result(views.html.help.cloning()) }
  def sharingLinks = Action { implicit request => result(views.html.help.sharing_links()) }
  def terms        = Action { implicit request => result(views.html.help.general.terms()) }
  def tutorial     = Action { implicit request => result(views.html.help.tutorial.tutorial()) }
  def workspace    = Action { implicit request => result(views.html.help.workspace()) }

  def swaggerUi = Action {
    Redirect(url = "/webjars/swagger-ui/2.2.0/index.html", queryString = Map("url" -> Seq("/swagger.json")))
  }

} 
Example 58
Source File: DocumentService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.document

import java.util.UUID
import javax.inject.{Inject, Singleton}
import services.BaseService
import services.generated.Tables.DOCUMENT
import scala.concurrent.ExecutionContext
import storage.db.DB
import storage.uploads.Uploads

@Singleton
class DocumentService @Inject() (
  implicit val uploads: Uploads, 
  implicit val db: DB
) extends BaseService 
  with create.CreateOps
  with read.DocumentReadOps
  with read.FilepartReadOps
  with read.ReadFromFolderOps
  with read.CollaboratorReadOps
  with read.SharedWithMeReadOps
  with read.AccessibleDocumentOps
  with search.SearchOps
  with network.NetworkOps
  with update.DocumentUpdateOps
  with update.CollaboratorUpdateOps
  with delete.DeleteOps {

  private val SORTABLE_FIELDS = 
    DOCUMENT.fields.toSeq.map(_.getName)

  
  def listIds(folder: Option[UUID], loggedInAs: String)(implicit ctx: ExecutionContext) =
    folder match {
      case Some(folderId) => 
        listDocumentsInFolder(folderId, loggedInAs)
          .map { _.map { case (doc, _) => 
            doc.getId
          }}

      case None => 
        listRootIdsByOwner(loggedInAs)
    }
      
} 
Example 59
Source File: VisitService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.visit

import com.sksamuel.elastic4s.{Hit, HitReader, Indexable}
import com.sksamuel.elastic4s.searches.{RichSearchResponse, RichSearchHit}
import com.sksamuel.elastic4s.ElasticDsl._
import java.nio.file.Path
import javax.inject.{Inject, Singleton}
import org.joda.time.DateTime
import play.api.Configuration
import play.api.libs.json.Json
import play.api.libs.Files.{TemporaryFile, TemporaryFileCreator}
import scala.concurrent.{Future, ExecutionContext}
import scala.util.Try
import services.{HasDate, HasTryToEither}
import storage.es.{ES, HasScrollProcessing}

@Singleton
class VisitService @Inject() (implicit val es: ES, val ctx: ExecutionContext, val config: Configuration) extends HasScrollProcessing with HasDate {
 
  implicit object VisitIndexable extends Indexable[Visit] {
    override def json(v: Visit): String = Json.stringify(Json.toJson(v))
  }

  implicit object VisitHitReader extends HitReader[Visit] with HasTryToEither {
    override def read(hit: Hit): Either[Throwable, Visit] =
      Try(Json.fromJson[Visit](Json.parse(hit.sourceAsString)).get)
  }
  
  def insertVisit(visit: Visit): Future[Unit] =
    es.client execute {
      indexInto(ES.RECOGITO / ES.VISIT).doc(visit)
    } map { _ =>
    } recover { case t: Throwable =>
      t.printStackTrace
    }
    
  def countTotal(): Future[Long] =
    es.client execute {
      search(ES.RECOGITO / ES.VISIT) limit 0
    } map { _.totalHits }
    
  def countSince(date: DateTime): Future[Long] =
    es.client execute {
      search(ES.RECOGITO / ES.VISIT) query {
        rangeQuery("visited_at").gt(formatDate(date))
      } limit 0
    } map { _.totalHits }
    
  def scrollExport()(implicit creator: TemporaryFileCreator): Future[Path] = {
    val exporter = CsvExporter.createNew()
    
    def writeToFile(response: RichSearchResponse): Future[Boolean] = 
      Future {
        val visits = response.to[Visit]
        exporter.writeBatch(visits)
      } map { _ => true 
      } recover { case t: Throwable =>
        t.printStackTrace()
        false
      }

    es.client execute {
      search(ES.RECOGITO / ES.VISIT) query matchAllQuery limit 200 scroll "5m"
    } flatMap { scroll(writeToFile, _) } map { success =>
      exporter.close()
      if (success) exporter.path else throw new RuntimeException()
    } recover { case t: Throwable =>
      Try(exporter.close())
      throw t
    }
  }
  
  def deleteOlderThan(date: DateTime): Future[Boolean] =
    es.client execute {
      deleteIn(ES.RECOGITO / ES.VISIT) by {
        rangeQuery("visited_at").lt(formatDate(date))
      }
    } map { _ => true
    } recover { case t: Throwable =>
      t.printStackTrace()
      false
    }
  
} 
Example 60
Source File: SimilarityService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.similarity

import javax.inject.{Inject, Singleton}
import scala.concurrent.ExecutionContext
import services.document.DocumentService
import services.generated.Tables.SIMILARITY
import services.generated.tables.records.SimilarityRecord
import storage.db.DB


  def findSimilar(docId: String, loggedInAs: Option[String], n: Int = 10) = {
    val f = for {
      similarities <- fetchSimilarityMetrics(docId, n)
      docsAndAccesslevels <- documents.getDocumentRecordsByIdWithAccessLevel(similarities.map(_.docId), loggedInAs)
    } yield (similarities, docsAndAccesslevels)

    f.map { case (similarities, docsAndAccessLevels) => 
      docsAndAccessLevels.map { case (doc, accesslevel) => 
        (doc, accesslevel, similarities.find(_.docId == doc.getId).get)
      } filter { _._2.canReadData } // Only expose docs with at least READ_DATA permission
    }
  }

} 
Example 61
Source File: AnnotationStatsService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.annotation.stats

import collection.JavaConverters._
import com.sksamuel.elastic4s.ElasticDsl._
import javax.inject.{Inject, Singleton}
import org.elasticsearch.search.aggregations.bucket.nested.InternalNested
import scala.collection.JavaConverters._
import scala.concurrent.{ExecutionContext, Future}
import services.annotation.HasAnnotationIndexing
import storage.es.ES
import services.annotation.{AnnotationService, AnnotationBody, AnnotationStatus}
import org.elasticsearch.search.aggregations.bucket.filter.InternalFilter
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms

case class StatusRatio(verified: Long, unverified: Long, notIdentifiable: Long)

@Singleton
trait AnnotationStatsService { self: AnnotationService =>
  
  def getTagStats(documentId: String, size: Integer = ES.MAX_SIZE) =
    es.client execute {
      search (ES.RECOGITO / ES.ANNOTATION) query {
        termQuery("annotates.document_id" -> documentId)
      } aggregations (
        nestedAggregation("per_body", "bodies") subaggs (
          filterAggregation("tags_only").query(termQuery("bodies.type" -> AnnotationBody.TAG.toString)) subaggs (
            termsAggregation("by_tag") field ("bodies.value.raw") size size
          )
        )
      ) size 0 
    } map { _.aggregations
      .getAs[InternalNested]("per_body").getAggregations
      .get[InternalFilter]("tags_only").getAggregations
      .get[StringTerms]("by_tag").getBuckets.asScala
      .map(b => (b.getKeyAsString, b.getDocCount))
    }

  def getStatusRatios(documentIds: Seq[String]): Future[Map[String, StatusRatio]] =
    es.client execute {
      search (ES.RECOGITO / ES.ANNOTATION) query {
        boolQuery
          should {
            documentIds.map(id => termQuery("annotates.document_id" -> id))
          }
      } aggregations (
        termsAggregation("per_document") field ("annotates.document_id") subaggs (
          nestedAggregation("per_body", "bodies") subaggs (
            termsAggregation("by_status_value") field ("bodies.status.value")
          )
        )
      ) size 0
    } map { _.aggregations
      .termsResult("per_document")
      .getBuckets.asScala.map { docBucket => 
        val docId = docBucket.getKeyAsString
        val statusValues = docBucket
          .getAggregations.get[InternalNested]("per_body")
          .getAggregations.get[StringTerms]("by_status_value")
          .getBuckets.asScala.map { statusBucket =>
            val status = AnnotationStatus.withName(statusBucket.getKeyAsString)
            val count = statusBucket.getDocCount
            (status, count)
          }.toMap
        
        val ratio = StatusRatio(
          statusValues.get(AnnotationStatus.VERIFIED).getOrElse(0l),
          statusValues.get(AnnotationStatus.UNVERIFIED).getOrElse(0l),
          statusValues.get(AnnotationStatus.NOT_IDENTIFIABLE).getOrElse(0l)
        )

        (docId, ratio)
      }.toMap
    }
  
} 
Example 62
Source File: AnnouncementService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.announcement

import java.sql.Timestamp
import java.util.Date
import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}
import services.BaseService
import services.generated.Tables.SERVICE_ANNOUNCEMENT
import services.generated.tables.records.ServiceAnnouncementRecord
import storage.db.DB
import services.user.UserService
import java.util.UUID

@Singleton
class AnnouncementService @Inject() (val db: DB, users: UserService, implicit val ctx: ExecutionContext) extends BaseService {
  
  def findLatestUnread(username: String): Future[Option[ServiceAnnouncementRecord]] = db.query { sql =>
    Option(sql.selectFrom(SERVICE_ANNOUNCEMENT)
              .where(SERVICE_ANNOUNCEMENT.FOR_USER.equal(username)
                .and(SERVICE_ANNOUNCEMENT.RESPONSE.isNull))
              .orderBy(SERVICE_ANNOUNCEMENT.CREATED_AT.desc())
              .fetchOne())
  }
  
  def confirm(uuid: UUID, username: String, response: String): Future[Boolean] = db.query { sql =>
    val result =
      sql.update(SERVICE_ANNOUNCEMENT)
         .set(SERVICE_ANNOUNCEMENT.VIEWED_AT, new Timestamp(new Date().getTime))
         .set(SERVICE_ANNOUNCEMENT.RESPONSE, response)
         .where(SERVICE_ANNOUNCEMENT.ID.equal(uuid).and(SERVICE_ANNOUNCEMENT.FOR_USER.equal(username)))
         .execute()
         
    result == 1
  }
  
  def clearAll(): Future[Boolean] = db.query { sql =>
    sql.deleteFrom(SERVICE_ANNOUNCEMENT).execute()
    true
  } recover { case t: Throwable =>
    t.printStackTrace()
    false
  }
  
  def deleteForUser(username: String) = db.query { sql =>
    sql.deleteFrom(SERVICE_ANNOUNCEMENT)
       .where(SERVICE_ANNOUNCEMENT.FOR_USER.equal(username)).execute()
  }
  
  def insertBroadcastAnnouncement(content: String): Future[Boolean] =  {
    val BATCH_SIZE = 200
    
    def insertOneBatch(users: Seq[String]): Future[_] = db.query { sql =>
      sql.batch(users.map { user =>
        sql.insertInto(SERVICE_ANNOUNCEMENT,
          SERVICE_ANNOUNCEMENT.ID, 
          SERVICE_ANNOUNCEMENT.FOR_USER,
          SERVICE_ANNOUNCEMENT.CONTENT,
          SERVICE_ANNOUNCEMENT.CREATED_AT,
          SERVICE_ANNOUNCEMENT.VIEWED_AT,
          SERVICE_ANNOUNCEMENT.RESPONSE
        ).values(
          UUID.randomUUID(),
          user,
          content,
          new Timestamp(new Date().getTime),
          null,
          null)
      }:_*).execute()
    }
    
    def insertBatchesRecursive(offset: Int, numUsers: Int): Future[Boolean] =
      users.listUsers(offset, BATCH_SIZE, None, None).flatMap { users =>
        insertOneBatch(users.items.map(_._1.getUsername))
      } flatMap { _ =>
        if (offset + BATCH_SIZE >= numUsers)
          Future.successful(true)
        else
          insertBatchesRecursive(offset + BATCH_SIZE, numUsers)
      }
      
    val f = for {
      numUsers <- users.countUsers()
      success <- insertBatchesRecursive(0, numUsers)
    } yield (success)
    
    f.recover { case t: Throwable =>
      play.api.Logger.info(t.getMessage)
      t.printStackTrace()
      false
    }
  }
  
} 
Example 63
Source File: MyController.scala    From play-grpc   with Apache License 2.0 5 votes vote down vote up
// #using-client
package controllers

import example.myapp.helloworld.grpc.helloworld.GreeterServiceClient
import example.myapp.helloworld.grpc.helloworld.HelloRequest
import javax.inject.Inject
import javax.inject.Singleton
import play.api.mvc.AbstractController
import play.api.mvc.ControllerComponents

import scala.concurrent.ExecutionContext

@Singleton
class MyController @Inject() (
    implicit greeterClient: GreeterServiceClient,
    cc: ControllerComponents,
    exec: ExecutionContext,
) extends AbstractController(cc) {

  def sayHello(name: String) = Action.async {
    greeterClient
      .sayHello(HelloRequest(name))
      .map { reply =>
        Ok(s"response: ${reply.message}")
      }
  }

}
// #using-client 
Example 64
Source File: EntityImporterFactory.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package services.entity.builtin.importer

import javax.inject.{Inject, Singleton}
import scala.concurrent.ExecutionContext
import services.entity.EntityType
import services.entity.builtin.EntityService
import storage.es.ES


@Singleton
class EntityImporterFactory @Inject()(
  ctx           : ExecutionContext,
  entityService : EntityService,
  es            : ES,
  rewriter      : ReferenceRewriter
) {

  def createImporter(eType: EntityType) =
    new EntityImporter(entityService, rewriter, eType, es, ctx)

} 
Example 65
Source File: NERService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package transform.ner

import akka.actor.ActorSystem
import akka.routing.RoundRobinPool
import javax.inject.{Inject, Singleton}
import org.pelagios.recogito.sdk.PluginEnvironment
import org.pelagios.recogito.sdk.ner.Entity
import play.api.{Configuration, Logger}
import scala.collection.JavaConverters._
import services.annotation.AnnotationService
import services.entity.builtin.EntityService
import services.task.{TaskService, TaskType}
import storage.uploads.Uploads
import transform.WorkerService

@Singleton
class NERService @Inject() (
  annotationService: AnnotationService,
  entityService: EntityService,
  taskService: TaskService,
  uploads: Uploads,
  config: Configuration,
  system: ActorSystem
) extends WorkerService(
  system, uploads,
  NERActor.props(taskService, annotationService, entityService, config), 3  
)

object NERService extends HasTeiNER {

  val TASK_TYPE = TaskType("NER")

  private def getEnvironment(config: Configuration) = {
    // Not the nicest way to handle this - suggestions welcome!
    val userDir = if (System.getProperty("user.dir").contains("/target/universal/stage"))
      System.getProperty("user.dir").replace("/target/universal/stage", "")
    else 
      System.getProperty("user.dir")

    val pluginsDir = s"${userDir}/plugins"

    val asMap = config.entrySet
      .filter(_._1.startsWith("plugins"))
      .toSeq
      .map { case(key, value) =>
        (key -> value.unwrapped.toString)
      }.toMap.asJava

    new PluginEnvironment(pluginsDir, asMap)
  }
  
  
  private[ner] def parseText(text: String, engine: Option[String], config: Configuration): Seq[Entity] = {
    val ner = engine match {
      case Some(identifier) => NERPluginManager.getEngine(identifier).get
      case None => NERPluginManager.getDefaultEngine
    }

    Logger.info(s"Running NER with engine ${ner.getName}")

    val entities = ner.parse(text, getEnvironment(config))
    entities.asScala
  }
     
} 
Example 66
Source File: GeoresolutionService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package transform.georesolution

import akka.actor.ActorSystem
import akka.routing.RoundRobinPool
import javax.inject.{Inject, Singleton}
import services.annotation.AnnotationService
import services.entity.builtin.EntityService
import services.generated.tables.records.{DocumentRecord, DocumentFilepartRecord}
import services.task.{TaskService, TaskType}
import storage.uploads.Uploads
import transform.{WorkerActor, WorkerService}

@Singleton
class GeoresolutionService @Inject() (
  annotationService: AnnotationService,
  entityService: EntityService,
  taskService: TaskService,
  uploads: Uploads,
  system: ActorSystem
) extends WorkerService (
  system, uploads,
  GeoresolutionActor.props(taskService, annotationService, entityService), 4
)

object GeoresolutionService {
  
  val TASK_TYPE = TaskType("GEORESOLUTION")

} 
Example 67
Source File: TEIParserService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package transform.tei

import akka.actor.ActorSystem
import akka.routing.RoundRobinPool
import java.io.{File, PrintWriter}
import javax.inject.{Inject, Singleton}
import org.joox.JOOX._
import org.w3c.dom.ranges.DocumentRange
import scala.collection.JavaConversions._
import services.annotation.{Annotation, AnnotationService}
import services.generated.tables.records.{DocumentRecord, DocumentFilepartRecord}
import services.task.{TaskService, TaskType}
import storage.uploads.Uploads
import transform.{WorkerActor, WorkerService}

@Singleton
class TEIParserService @Inject() (
  uploads: Uploads,
  annotationService: AnnotationService,
  taskService: TaskService, 
  system: ActorSystem
) extends WorkerService(
  system, uploads,
  TEIParserActor.props(taskService, annotationService), 10
)

object TEIParserService {

  val TASK_TYPE = TaskType("TEI_PARSING")
  
  private[tei] def extractEntities(
    part: DocumentFilepartRecord,
    file: File,
    replaceOriginalFile: Boolean = true
  ): Seq[Annotation] = {    
    val teiXML = $(file).document()
    val ranges = teiXML.asInstanceOf[DocumentRange]

    val places = $(teiXML).find("placeName").get
    val people = $(teiXML).find("persName").get
    val spans  = $(teiXML).find("span").get

    val annotations = (places ++ people ++ spans).map(TEITag.convert(part, _, ranges))

    if (replaceOriginalFile)
      new PrintWriter(file.getAbsolutePath)  {
        write($(teiXML).toString)
        close
      }

    annotations
  }
} 
Example 68
Source File: TilingService.scala    From recogito2   with Apache License 2.0 5 votes vote down vote up
package transform.tiling

import akka.actor.ActorSystem
import akka.routing.RoundRobinPool
import java.io.File
import javax.inject.{Inject, Singleton}
import scala.language.postfixOps
import services.generated.tables.records.{DocumentRecord, DocumentFilepartRecord}
import services.task.{TaskService, TaskType}
import storage.uploads.Uploads
import sys.process._
import transform.{WorkerActor, WorkerService}

@Singleton
class TilingService @Inject() (
  uploads: Uploads,
  taskService: TaskService, 
  system: ActorSystem
) extends WorkerService(
  system, uploads,
  TilingActor.props(taskService), 4
)      

object TilingService {

  val TASK_TYPE = TaskType("IMAGE_TILING")
  
  private[tiling] def createZoomify(file: File, destFolder: File) = {
    
    val result =  s"vips dzsave $file $destFolder --layout zoomify" !
    
    if (result != 0)
      throw new Exception("Image tiling failed for " + file.getAbsolutePath + " to " + destFolder.getAbsolutePath)
  }
  
} 
Example 69
Source File: ExampleBootstrap.scala    From asura   with MIT License 5 votes vote down vote up
package com.example.asura

import akka.actor.ActorSystem
import asura.core.auth.AuthManager
import asura.core.assertion.Assertions
import asura.core.notify.JobNotifyManager
import com.example.asura.assertion.ExampleAssertion
import com.example.asura.auth.ExampleAuth
import com.example.asura.notify.ExampleNotification
import javax.inject.{Inject, Singleton}
import play.api.Configuration
import play.api.inject.ApplicationLifecycle

@Singleton
class ExampleBootstrap @Inject()(
                                  lifecycle: ApplicationLifecycle,
                                  system: ActorSystem,
                                  configuration: Configuration, // https://www.playframework.com/documentation/2.6.x/ConfigFile
                                ) {

  AuthManager.register(new ExampleAuth(configuration))

  JobNotifyManager.register(new ExampleNotification(configuration))

  Assertions.register(ExampleAssertion)
} 
Example 70
Source File: GroupApi.scala    From asura   with MIT License 5 votes vote down vote up
package asura.app.api

import akka.actor.ActorSystem
import asura.app.AppErrorMessages
import asura.app.api.auth.Reserved
import asura.common.model.ApiResError
import asura.common.util.StringUtils
import asura.core.es.actor.ActivitySaveActor
import asura.core.es.model.{Activity, Group}
import asura.core.es.service.GroupService
import asura.core.model.QueryGroup
import asura.play.api.BaseApi.OkApiRes
import javax.inject.{Inject, Singleton}
import org.pac4j.play.scala.SecurityComponents
import play.api.Configuration
import play.api.mvc.{RequestHeader, Result}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class GroupApi @Inject()(
                          implicit val system: ActorSystem,
                          val exec: ExecutionContext,
                          val configuration: Configuration,
                          val controllerComponents: SecurityComponents,
                        ) extends BaseApi {

  val administrators = configuration.getOptional[Seq[String]]("asura.admin").getOrElse(Nil).toSet
  val activityActor = system.actorOf(ActivitySaveActor.props())

  def getById(id: String) = Action.async { implicit req =>
    GroupService.getById(id).toOkResultByEsOneDoc(id)
  }

  def delete(id: String) = Action.async { implicit req =>
    checkPrivilege { user =>
      activityActor ! Activity(id, StringUtils.EMPTY, user, Activity.TYPE_DELETE_GROUP, id)
      GroupService.deleteGroup(id).toOkResult
    }
  }

  def put() = Action(parse.byteString).async { implicit req =>
    val group = req.bodyAs(classOf[Group])
    val user = getProfileId()
    group.fillCommonFields(user)
    if (Reserved.isReservedGroup(group.id)) {
      Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_CanNotUseReservedGroup))))
    } else {
      GroupService.index(group).map(res => {
        activityActor ! Activity(group.id, StringUtils.EMPTY, user, Activity.TYPE_NEW_GROUP, group.id)
        toActionResultFromAny(res)
      })
    }
  }

  def query() = Action(parse.byteString).async { implicit req =>
    val queryGroup = req.bodyAs(classOf[QueryGroup])
    GroupService.queryGroup(queryGroup).toOkResultByEsList(false)
  }

  def update() = Action(parse.byteString).async { implicit req =>
    val group = req.bodyAs(classOf[Group])
    GroupService.updateGroup(group).toOkResult
  }

  private def checkPrivilege(func: String => Future[Result])(implicit request: RequestHeader): Future[Result] = {
    val user = getProfileId()
    val isAllowed = if (administrators.nonEmpty) administrators.contains(user) else true
    if (isAllowed) {
      func(user)
    } else {
      Future.successful(OkApiRes(ApiResError(getI18nMessage(AppErrorMessages.error_NotAllowedContactAdministrator, administrators.mkString(",")))))
    }
  }
} 
Example 71
Source File: AppDatabase.scala    From phantom-activator-template   with Apache License 2.0 5 votes vote down vote up
package models

import javax.inject.{Inject, Singleton}

import com.outworkers.phantom.builder.query.CreateQuery
import com.outworkers.phantom.dsl._

import scala.concurrent.Future
import scala.concurrent.duration._

@Singleton
class AppDatabase @Inject()(
  env: play.api.Environment,
  override val connector: CassandraConnection
) extends Database[AppDatabase](connector) {


  object beers extends Beers with Connector {
    override def autocreate(space: KeySpace): CreateQuery.Default[Beers, Beer] = {
      create.ifNotExists()(space)
        .option(default_time_to_live eqs 10)
        .and(gc_grace_seconds eqs 10.seconds)
        .and(read_repair_chance eqs 0.2)
    }
  }

  def initialize(): Future[List[ResultSet]] = {
    val beerList = List(
      Beer(company = "budhizer", style = "white", name = "Summer Bud"),
      Beer(company = "budhizer", style = "dark", name = "Winter Bud"),
      Beer(company = "budhizer", style = "wheat", name = "Spring Bud"),
      Beer(company = "budhizer", style = "pumpkin", name = "Fall Bud")
    )

    for {
      init <- beers.autocreate(space).future()

      // https://github.com/outworkers/phantom/blob/develop/docs/basics/tables.md#automatically-derived-store-method
      records <- beers.storeRecords(beerList)
    } yield records
  }

  // Runs in constructor when the application is started.  Because this is @Singleton,
  // it runs only once, only one instance of this class is created.
  env.mode match {
    case play.api.Mode.Test => initialize()
    case other@_ => Seq.empty
  }
} 
Example 72
Source File: Module.scala    From phantom-activator-template   with Apache License 2.0 5 votes vote down vote up
import javax.inject.{Inject, Provider, Singleton}

import com.google.inject.AbstractModule
import com.outworkers.phantom.connectors.{CassandraConnection, ContactPoint}
import models.AppDatabase
import net.codingwell.scalaguice.ScalaModule

class Module extends AbstractModule  with ScalaModule {
  override def configure(): Unit = {
    bind[CassandraConnection].toProvider[ConnectionProvider]
    bind[AppDatabase].asEagerSingleton()
  }
}

@Singleton
class ConnectionProvider @Inject()(env: play.api.Environment) extends Provider[CassandraConnection] {
  lazy val get: CassandraConnection = {
    val builder = env.mode match {
      case play.api.Mode.Test => ContactPoint.embedded
      case _ => ContactPoint.local
    }
    builder.keySpace("outworkers")
  }
} 
Example 73
Source File: ClientsModule.scala    From daf-semantics   with Apache License 2.0 5 votes vote down vote up
package modules

import com.google.inject.ImplementedBy
import play.api.inject.ApplicationLifecycle
import javax.inject.Singleton
import javax.inject.Inject
import play.api.libs.ws.WSClient
import play.api.Application
import play.api.Environment
import play.api.Configuration
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import play.Logger
import clients.OntonetHubClient
import com.typesafe.config.ConfigFactory
import com.typesafe.config.ConfigRenderOptions

@ImplementedBy(classOf[ClientsModuleBase])
trait ClientsModule

@Singleton
class ClientsModuleBase @Inject() (lifecycle: ApplicationLifecycle,
                                   ws: WSClient,
                                   configuration: Configuration) extends ClientsModule {

  val conf_clients = configuration.underlying
    .getConfig("clients")

  val ontonethub_config = conf_clients.getConfig("ontonethub")

  // TODO: verify if default configurations are needed here
  val ontonethub = new OntonetHubClient(ws, ontonethub_config)

  // TESTING ................................................
  val options = ConfigRenderOptions.concise()
    .setComments(false).setOriginComments(false)
    .setFormatted(true).setJson(true)
  val json = ontonethub_config.root().render(options)
  // TESTING ................................................

  // when application starts...
  @Inject
  def onStart(
    app: Application,
    env: Environment)(implicit ec: ExecutionContext) {

    Logger.info("ClientsModuleBase START")

    println("\n\n\n\n\n\n")
    println(json)

  }

  // when application stops...
  lifecycle.addStopHook({ () =>

    Future.successful {

      Logger.info("ClientsModuleBase STOP")

    }

  })

} 
Example 74
Source File: CatalogStandardizationService.scala    From daf-semantics   with Apache License 2.0 5 votes vote down vote up
package it.almawave.kb.http.endpoints

import javax.inject.Singleton
import javax.ws.rs.Path
import org.slf4j.LoggerFactory
import it.almawave.kb.http.models.OntologyMetaModel
import com.typesafe.config.ConfigFactory
import java.nio.file.Paths
import it.almawave.linkeddata.kb.catalog.CatalogBox
import it.almawave.linkeddata.kb.utils.JSONHelper
import it.almawave.daf.standardization.refactoring.CatalogStandardizer

@Singleton
@Path("conf://api-catalog-config")
class CatalogStandardizationService {

  private val logger = LoggerFactory.getLogger(this.getClass)

  val conf = ConfigFactory.parseFile(Paths.get("./conf/catalog.conf").normalize().toFile())
  val catalog = new CatalogBox(conf)
  catalog.start()

  val _standardizer = CatalogStandardizer(catalog)
  _standardizer.start

  def stardardizer = _standardizer

  //  TODO: STOP?

} 
Example 75
Source File: MetricsController.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package controllers

import java.io.Writer
import javax.inject.Singleton

import akka.util.ByteString
import io.prometheus.client._
import io.prometheus.client.exporter.common.TextFormat
import io.prometheus.client.hotspot.DefaultExports
import play.api.http.HttpEntity
import play.api.mvc._

@Singleton
class MetricsController extends Controller {
  //export default jvm metrics
  DefaultExports.initialize()

  def index = Action {
    val samples = new StringBuilder()
    val writer = new WriterAdapter(samples)

    TextFormat.write004(writer, CollectorRegistry.defaultRegistry.metricFamilySamples())
    writer.close()

    Result(
      header = ResponseHeader(200, Map.empty),
      body = HttpEntity.Strict(ByteString(samples.toString), Some(TextFormat.CONTENT_TYPE_004))
    )
  }
}

class WriterAdapter(buffer: StringBuilder) extends Writer {
  override def write(charArray: Array[Char], offset: Int, length: Int): Unit = {
    buffer ++= new String(new String(charArray, offset, length).getBytes("UTF-8"), "UTF-8")
  }
  override def flush(): Unit = {}
  override def close(): Unit = {}
} 
Example 76
Source File: MetricsController.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package controllers
import java.io.Writer
import javax.inject.Singleton

import akka.util.ByteString
import io.prometheus.client._
import io.prometheus.client.exporter.common.TextFormat
import io.prometheus.client.hotspot.DefaultExports
import play.api.http.HttpEntity
import play.api.mvc._


@Singleton
class MetricsController extends Controller {
  //export default jvm metrics
  DefaultExports.initialize()

  def index = Action {
    val samples = new StringBuilder()
    val writer = new WriterAdapter(samples)

    TextFormat.write004(writer, CollectorRegistry.defaultRegistry.metricFamilySamples())
    writer.close()

    Result(
      header = ResponseHeader(200, Map.empty),
      body = HttpEntity.Strict(ByteString(samples.toString), Some(TextFormat.CONTENT_TYPE_004))
    )
  }
}

class WriterAdapter(buffer: StringBuilder) extends Writer {
  override def write(charArray: Array[Char], offset: Int, length: Int): Unit = {
    val b = buffer.append(new String(new String(charArray, offset, length).getBytes("UTF-8"), "UTF-8"))
  }
  override def flush(): Unit = {}
  override def close(): Unit = {}
} 
Example 77
Source File: MetricsController.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package controllers

import java.io.Writer
import javax.inject.Singleton

import akka.util.ByteString
import io.prometheus.client._
import io.prometheus.client.exporter.common.TextFormat
import io.prometheus.client.hotspot.DefaultExports
import play.api.http.HttpEntity
import play.api.mvc._


@Singleton
class MetricsController extends Controller {
  //export default jvm metrics
  DefaultExports.initialize()

  def index = Action {
    val samples = new StringBuilder()
    val writer = new WriterAdapter(samples)

    TextFormat.write004(writer, CollectorRegistry.defaultRegistry.metricFamilySamples())
    writer.close()

    Result(
      header = ResponseHeader(200, Map.empty),
      body = HttpEntity.Strict(ByteString(samples.toString), Some(TextFormat.CONTENT_TYPE_004))
    )
  }
}

class WriterAdapter(buffer: StringBuilder) extends Writer {
  override def write(charArray: Array[Char], offset: Int, length: Int): Unit = {
    buffer ++= new String(new String(charArray, offset, length).getBytes("UTF-8"), "UTF-8")

  }
  override def flush(): Unit = {}
  override def close(): Unit = {}
} 
Example 78
Source File: MetricsController.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package controllers

import java.io.Writer
import javax.inject.Singleton

import akka.util.ByteString
import io.prometheus.client._
import io.prometheus.client.exporter.common.TextFormat
import io.prometheus.client.hotspot.DefaultExports
import play.api.http.HttpEntity
import play.api.mvc._


@Singleton
class MetricsController extends Controller {
  //export default jvm metrics
  DefaultExports.initialize()

  def index = Action {
    val samples = new StringBuilder()
    val writer = new WriterAdapter(samples)

    TextFormat.write004(writer, CollectorRegistry.defaultRegistry.metricFamilySamples())
    writer.close()

    Result(
      header = ResponseHeader(200, Map.empty),
      body = HttpEntity.Strict(ByteString(samples.toString), Some(TextFormat.CONTENT_TYPE_004))
    )
  }
}

class WriterAdapter(buffer: StringBuilder) extends Writer {
  override def write(charArray: Array[Char], offset: Int, length: Int): Unit = {
    buffer ++= new String(new String(charArray, offset, length).getBytes("UTF-8"), "UTF-8")
  }
  override def flush(): Unit = {}
  override def close(): Unit = {}
} 
Example 79
Source File: SecurityFilter.scala    From daf   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package it.gov.daf.common.filters.authentication

import javax.inject.{Inject, Singleton}

import akka.stream.Materializer
import org.pac4j.core.config.Config
import org.pac4j.play.store.PlaySessionStore
import play.api.Configuration
import play.api.mvc._
import play.libs.concurrent.HttpExecutionContext

import scala.concurrent.Future

@SuppressWarnings(
  Array(
    "org.wartremover.warts.Overloading"
  )
)
@Singleton
class SecurityFilter @Inject()(mat: Materializer, configuration: Configuration, playSessionStore: PlaySessionStore, config: Config, ec: HttpExecutionContext) extends org.pac4j.play.filters.SecurityFilter(mat, configuration, playSessionStore, config, ec) {

  override def apply(nextFilter: (RequestHeader) => Future[play.api.mvc.Result])
                    (request: RequestHeader): Future[play.api.mvc.Result] = {
    super.apply(nextFilter)(request)
  }
} 
Example 80
Source File: ParSeqTraceRenderer.scala    From play-parseq   with Apache License 2.0 5 votes vote down vote up
package com.linkedin.playparseq.trace.s.renderers

import com.linkedin.parseq.trace.{ShallowTrace, Trace, TraceRelationship}
import com.linkedin.playparseq.s.stores.ParSeqTaskStore
import com.linkedin.playparseq.trace.utils.ParSeqTraceBaseVisualizer
import javax.inject.{Inject, Singleton}
import play.api.Environment
import play.api.http.HttpConfiguration
import play.api.mvc.{RequestHeader, Result, Results}
import scala.collection.JavaConverters._
import scala.concurrent.{ExecutionContext, Future}



  override def render(parSeqTaskStore: ParSeqTaskStore)(implicit requestHeader: RequestHeader): Future[Result] =
    Future {
      val traces: Set[Trace] = parSeqTaskStore.get.map(_.getTrace)
      val traceMap: Map[java.lang.Long, ShallowTrace] = traces.foldLeft(Map[java.lang.Long, ShallowTrace]())(_ ++ _.getTraceMap.asScala)
      val relationships: Set[TraceRelationship] = traces.foldLeft(Set[TraceRelationship]())(_ ++ _.getRelationships.asScala)
      // Generate Result of ParSeq Trace
      Option(showTrace(new Trace(traceMap.asJava, relationships.asJava), environment, httpConfiguration)).map(Results.Ok(_).as("text/html"))
        .getOrElse(Results.InternalServerError("Can't show Trace."))
    }

} 
Example 81
Source File: PlayParSeq.scala    From play-parseq   with Apache License 2.0 5 votes vote down vote up
package com.linkedin.playparseq.s

import com.linkedin.parseq.{Engine, Task}
import com.linkedin.parseq.promise.Promises
import com.linkedin.playparseq.s.PlayParSeqImplicits._
import com.linkedin.playparseq.s.stores.ParSeqTaskStore
import com.linkedin.playparseq.utils.PlayParSeqHelper
import javax.inject.{Inject, Singleton}
import play.api.mvc.RequestHeader
import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success}



  override def runTask[T](task: Task[T])(implicit requestHeader: RequestHeader): Future[T] = {
    // Bind a Future to the ParSeq Task
    val future: Future[T] = bindTaskToFuture(task)
    // Put the ParSeq Task into store
    parSeqTaskStore.put(task)
    // Run the ParSeq Task
    engine.run(task)
    // Return the Future
    future
  }

} 
Example 82
Source File: ExceptionTranslationFilter.scala    From finatra-activator-thrift-seed   with Apache License 2.0 5 votes vote down vote up
package com.example

import com.twitter.finagle.{Service, TimeoutException}
import com.twitter.finatra.thrift.thriftscala.ClientErrorCause.RequestTimeout
import com.twitter.finatra.thrift.thriftscala.ServerErrorCause.InternalServerError
import com.twitter.finatra.thrift.thriftscala.{ClientError, ServerError}
import com.twitter.finatra.thrift.{ThriftFilter, ThriftRequest}
import com.twitter.inject.Logging
import com.twitter.util.{Future, NonFatal}
import javax.inject.Singleton

@Singleton
class ExceptionTranslationFilter
  extends ThriftFilter
  with Logging {

  override def apply[T, U](request: ThriftRequest[T], service: Service[ThriftRequest[T], U]): Future[U] = {
    service(request).rescue {
      case e: TimeoutException =>
        Future.exception(
          ClientError(RequestTimeout, e.getMessage))
      case e: ClientError =>
        Future.exception(e)
      case NonFatal(e) =>
        error("Unhandled exception", e)
        Future.exception(
          ServerError(InternalServerError, e.getMessage))
    }
  }
} 
Example 83
Source File: ErrorHandler.scala    From play-table-of-contents   with MIT License 5 votes vote down vote up
import javax.inject.{Inject, Provider, Singleton}

import play.api._
import play.api.http.DefaultHttpErrorHandler
import play.api.mvc.Results._
import play.api.mvc._
import play.api.routing.Router

import scala.concurrent._


@Singleton
class ErrorHandler @Inject() (
   env: Environment,
   config: Configuration,
   sourceMapper: OptionalSourceMapper,
   router: Provider[Router]
  ) extends DefaultHttpErrorHandler(env, config, sourceMapper, router) {

  override def onProdServerError(request: RequestHeader, exception: UsefulException) = {
    Future.successful(
      InternalServerError("A server error occurred: " + exception.getMessage)
    )
  }

  override def onForbidden(request: RequestHeader, message: String) = {
    Future.successful(
      Forbidden("You're not allowed to access this resource.")
    )
  }
} 
Example 84
Source File: CacheManagerTokenStore.scala    From meteorite-core   with Apache License 2.0 5 votes vote down vote up
package bi.meteorite.core.security.tokenprovider

import com.hazelcast.core.HazelcastInstance
import org.ops4j.pax.cdi.api.OsgiService
import org.osgi.framework.BundleContext
import org.osgi.framework.wiring.BundleWiring
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import javax.annotation.PostConstruct
import javax.inject.{Named, Inject, Singleton}


@Singleton
@Named("CManager")
object CacheManagerTokenStore {
  private var logger: Logger = LoggerFactory.getLogger(classOf[CacheManagerTokenStore])
}

@Singleton class CacheManagerTokenStore extends TokenStorageProvider {
  @OsgiService
  @Inject private var cacheManager: HazelcastInstance = null
  @Inject private var bcontext: BundleContext = null

  @PostConstruct def init {
    CacheManagerTokenStore.logger.debug("*** Activating CacheManager")
    val c: CompositeClassLoader = new CompositeClassLoader
    val tccl: ClassLoader = Thread.currentThread.getContextClassLoader
    try {
      cacheManager.getConfig.setClassLoader(c)
    } finally {
      cacheManager.getConfig.setClassLoader(c)
    }
  }

  def addToken(token: Token) {
    addInvokerClassLoader(this.getClass.getClassLoader)
    cacheManager.getMap("tokens").put(token.getToken, token)
  }

  def updateToken(token: Token) {
  }

  def getToken(token: String): Token = {
    addInvokerClassLoader(getInvokerClassLoader)
    cacheManager.getMap("tokens").get(token).asInstanceOf[Token]
  }

  def hasToken(token: String): Boolean = {
    addInvokerClassLoader(getInvokerClassLoader)
    cacheManager.getMap("tokens").get(token) != null
  }

  def removeToken(token: Token) {
  }

  def setCacheManagerService(hazel: HazelcastInstance) {
    this.cacheManager = hazel
  }

  protected def addInvokerClassLoader(cl: ClassLoader) {
    getInstance.getConfig.getClassLoader.asInstanceOf[CompositeClassLoader].add(cl)
  }

  protected def getInvokerClassLoader: ClassLoader = {
    bcontext.getBundle.adapt(classOf[BundleWiring]).getClassLoader
  }

  def setBcontext(bcontext: BundleContext) {
    this.bcontext = bcontext
  }

  def getInstance: HazelcastInstance = {
    cacheManager
  }
} 
Example 85
Source File: SecurityFilter.scala    From meteorite-core   with Apache License 2.0 5 votes vote down vote up
package bi.meteorite.core.security

import javax.inject.{Inject, Named, Singleton}
import javax.servlet.http.{HttpServletRequest, HttpServletResponse}
import javax.servlet.{Filter, FilterChain, FilterConfig, ServletRequest, ServletResponse}

import bi.meteorite.core.api.security.AdminLoginService
import bi.meteorite.core.api.security.exceptions.TokenProviderException
import bi.meteorite.core.api.security.tokenprovider.TokenProvider
import org.ops4j.pax.cdi.api.OsgiService


@Singleton
@Named("securityFilter")
class SecurityFilter extends Filter {

  @Inject
  @OsgiService
  private var tokenProvider: TokenProvider = _

  @Inject
  @OsgiService
  private var adminLoginService: AdminLoginService = _

  override def doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
    val servletRequest = request.asInstanceOf[HttpServletRequest]
    val servletResponse = response.asInstanceOf[HttpServletResponse]
    var s = servletRequest.getPathInfo
    val s2 = servletRequest.getServletPath
    if (s != null && s2 != null) {
      s = s2 + s
    } else if (s == null) {
      s = s2
    }
    if (s.startsWith("/admin/ui/") || s == "/rest/core/auth/login") {
      chain.doFilter(request, response)
    } else if (servletRequest.getPathInfo.startsWith("/rest/core/admin")) {
      val token = tokenProvider.getTokenFromRequest(servletRequest)
      var isAdmin = false
      try {
        val userDetails = tokenProvider.verifyToken(token)

        if (adminLoginService.getUsername ==
          userDetails.get(TokenProvider.USERNAME).get) {
          isAdmin = true
        }
      } catch {
        case e: TokenProviderException =>
      }
      if (isAdmin) {
        chain.doFilter(request, response)
      } else {
        servletResponse.sendRedirect("/admin/ui/index.html")
      }
    } else {
      chain.doFilter(request, response)
    }
  }

  override def init(arg0: FilterConfig) {
  }

  override def destroy() {
  }

  def setTokenProvider(tokenProvider: TokenProvider) = this.tokenProvider = tokenProvider

  def setAdminLoginService(adminLoginService: AdminLoginService) = this.adminLoginService = adminLoginService
} 
Example 86
Source File: TokenResponseFilter.scala    From meteorite-core   with Apache License 2.0 5 votes vote down vote up
package bi.meteorite.core.security.authentication

import javax.inject.{Named, Singleton}
import javax.ws.rs.container.{ContainerRequestContext, ContainerResponseContext, ContainerResponseFilter}
import javax.ws.rs.core.{HttpHeaders, NewCookie}

import bi.meteorite.core.api.security.tokenprovider.TokenProvider


@Singleton
@Named("tokenResponseFilter")
class TokenResponseFilter extends ContainerResponseFilter {

  override def filter(requestContext: ContainerRequestContext, responseContext: ContainerResponseContext) {
    val value = requestContext.getProperty("token").asInstanceOf[String]
    if (value != null) {
      val newcookie = new NewCookie(TokenProvider.TOKEN_COOKIE_NAME, value)
      responseContext.getHeaders.putSingle(HttpHeaders.SET_COOKIE, newcookie)
    }
  }
} 
Example 87
Source File: TokenAuthorizingFilter.scala    From meteorite-core   with Apache License 2.0 5 votes vote down vote up
package bi.meteorite.core.security.authorization

import javax.annotation.Priority
import javax.inject.{Inject, Named, Singleton}
import javax.ws.rs.Priorities
import javax.ws.rs.container.{ContainerRequestContext, ContainerRequestFilter}
import javax.ws.rs.core.Response

import org.apache.cxf.interceptor.security.AccessDeniedException
import org.apache.cxf.jaxrs.utils.JAXRSUtils


@Priority(Priorities.AUTHORIZATION)
@Singleton
@Named("authorizationFilter")
class TokenAuthorizingFilter extends ContainerRequestFilter {

  @Inject
  @Named("authorizationInterceptor")
  private var interceptor: TokenAuthorizingInterceptor = null

  def filter(context: ContainerRequestContext) = {
    try {
      interceptor.handleMessage(JAXRSUtils.getCurrentMessage)
    }
    catch {
      case _: AccessDeniedException => context.abortWith(Response.status(Response.Status.FORBIDDEN).build)
    }

  }

  def setInterceptor(in: TokenAuthorizingInterceptor) = interceptor = in
} 
Example 88
Source File: UserAuthenticationImpl.scala    From meteorite-core   with Apache License 2.0 5 votes vote down vote up
package bi.meteorite.core.security.rest

import javax.inject.{Inject, Singleton}
import javax.ws.rs.core.Response

import bi.meteorite.core.api.security.AdminLoginService
import bi.meteorite.core.api.security.rest.{UserAuthentication, UserService}
import org.ops4j.pax.cdi.api.{OsgiService, OsgiServiceProvider}


@OsgiServiceProvider(classes = Array(classOf[UserAuthentication]))
@Singleton class UserAuthenticationImpl extends UserAuthentication {

  @Inject
  @volatile
  @OsgiService
  private var adminLoginService: AdminLoginService = null

  override def logout(username: String) : Response = {
    if(adminLoginService.logout(username)){
      Response.ok().build()
    }
    else{
      Response.serverError().build()
    }
  }

  def setAdminLoginService(adminLoginService: AdminLoginService) = this.adminLoginService = adminLoginService
} 
Example 89
Source File: WSConfigParser.scala    From play-ws   with Apache License 2.0 5 votes vote down vote up
package play.api.libs.ws

import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton

import com.typesafe.config.Config
import com.typesafe.config.ConfigException
import com.typesafe.sslconfig.ssl.SSLConfigParser
import com.typesafe.sslconfig.util.EnrichedConfig

import scala.concurrent.duration.Duration


@Singleton
class WSConfigParser @Inject() (config: Config, classLoader: ClassLoader) extends Provider[WSClientConfig] {

  def parse(): WSClientConfig = {
    val wsConfig = config.getConfig("play.ws")

    val connectionTimeout = Duration(wsConfig.getString("timeout.connection"))
    val idleTimeout       = Duration(wsConfig.getString("timeout.idle"))
    val requestTimeout    = Duration(wsConfig.getString("timeout.request"))

    val followRedirects    = wsConfig.getBoolean("followRedirects")
    val useProxyProperties = wsConfig.getBoolean("useProxyProperties")

    val userAgent = {
      try {
        Some(wsConfig.getString("useragent"))
      } catch {
        case e: ConfigException.Null =>
          None
      }
    }

    val compressionEnabled = wsConfig.getBoolean("compressionEnabled")

    val sslConfig = new SSLConfigParser(EnrichedConfig(wsConfig.getConfig("ssl")), classLoader).parse()

    WSClientConfig(
      connectionTimeout = connectionTimeout,
      idleTimeout = idleTimeout,
      requestTimeout = requestTimeout,
      followRedirects = followRedirects,
      useProxyProperties = useProxyProperties,
      userAgent = userAgent,
      compressionEnabled = compressionEnabled,
      ssl = sslConfig
    )
  }

  override lazy val get: WSClientConfig = parse()
} 
Example 90
Source File: WebSocket.scala    From trucking-iot   with Apache License 2.0 5 votes vote down vote up
package controllers

import javax.inject.{Inject, Singleton}

import akka.actor.{Actor, ActorRef, ActorSystem, Props}
import akka.kafka.scaladsl.Consumer
import akka.kafka.{ConsumerSettings, Subscriptions}
import akka.stream.scaladsl.Sink
import akka.stream.{Materializer, ThrottleMode}
import com.typesafe.config.ConfigFactory
import org.apache.kafka.clients.consumer.ConsumerConfig
import org.apache.kafka.common.serialization.{ByteArrayDeserializer, StringDeserializer}
import play.api.libs.streams.ActorFlow
import play.api.mvc.{Controller, WebSocket}

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.concurrent.duration._


//@Singleton
class KafkaWebSocket @Inject() (implicit system: ActorSystem, materializer: Materializer) extends Controller {

  def kafkaWS = WebSocket.accept[String, String] { request =>
    ActorFlow.actorRef(out => KafkaWSActor.props(out))
  }

  object KafkaWSActor {
    def props(outRef: ActorRef) = Props(new KafkaWSActor(outRef))
  }

  class KafkaWSActor(outRef: ActorRef) extends Actor {

    val config = ConfigFactory.load()
    val combinedConfig = ConfigFactory.defaultOverrides()
      .withFallback(config)
      .withFallback(ConfigFactory.defaultApplication())
      .getConfig("trucking-web-application.backend")

    val consumerSettings = ConsumerSettings(system, new ByteArrayDeserializer, new StringDeserializer)
      //.withBootstrapServers("sandbox-hdf.hortonworks.com:6667")
      .withBootstrapServers(combinedConfig.getString("kafka.bootstrap-servers"))
      .withGroupId("group1")
      .withProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest")

    Consumer.committableSource(consumerSettings, Subscriptions.topics("trucking_data_joined"))
      .mapAsync(1) { msg => Future(outRef ! msg.record.value).map(_ => msg) }
      //.mapAsync(1) { msg => msg.committableOffset.commitScaladsl() } // TODO: Disabling commits for debug
      .throttle(1, 250.milliseconds, 1, ThrottleMode.Shaping)
      .runWith(Sink.ignore)

    def receive = {
      case msg: String => outRef ! s"Ack: $msg"
    }
  }

} 
Example 91
Source File: ObligationsService.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.services

import cats.data.EitherT
import cats.implicits._
import javax.inject.{Inject, Singleton}
import play.api.Logger
import uk.gov.hmrc.http.HeaderCarrier
import utils.{EndpointLogContext, Logging}
import v1.connectors.ObligationsConnector
import v1.models.errors._
import v1.models.request.obligations.ObligationsRequest
import v1.models.response.obligations.ObligationsResponse
import v1.support.DesResponseMappingSupport

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ObligationsService @Inject()(connector: ObligationsConnector) extends DesResponseMappingSupport with Logging {

  def retrieveObligations(request: ObligationsRequest)(
    implicit hc: HeaderCarrier,
    ec: ExecutionContext,
    logContext: EndpointLogContext): Future[ServiceOutcome[ObligationsResponse]] = {

    val result = for {
      desResponseWrapper <- EitherT(connector.retrieveObligations(request)).leftMap(mapDesErrors(desErrorMap))
    } yield desResponseWrapper

    result.value
  }

  private def desErrorMap: Map[String, MtdError] =
    Map(
      "INVALID_IDTYPE" -> DownstreamError,
      "INVALID_IDNUMBER" -> VrnFormatErrorDes,
      "INVALID_STATUS" -> InvalidStatusErrorDes,
      "INVALID_REGIME" -> DownstreamError,
      "INVALID_DATE_FROM" -> InvalidDateFromErrorDes,
      "INVALID_DATE_TO" -> InvalidDateToErrorDes,
      "INVALID_DATE_RANGE" -> RuleOBLDateRangeTooLargeError,
      "NOT_FOUND_BP_KEY" -> {
        Logger.warn("[ObligationsService] [desErrorMap] - Backend returned NOT_FOUND_BPKEY error")
        DownstreamError
      },
      "NOT_FOUND" -> LegacyNotFoundError,
      "SERVICE_ERROR" -> DownstreamError,
      "SERVICE_UNAVAILABLE" -> DownstreamError
    )
} 
Example 92
Source File: ViewReturnService.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.services

import cats.data.EitherT
import cats.implicits._
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.http.HeaderCarrier
import utils.{EndpointLogContext, Logging}
import v1.connectors.ViewReturnConnector
import v1.models.errors._
import v1.models.request.viewReturn.ViewRequest
import v1.models.response.viewReturn.ViewReturnResponse
import v1.support.DesResponseMappingSupport

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ViewReturnService @Inject()(connector: ViewReturnConnector) extends DesResponseMappingSupport with Logging {

  def viewReturn(request: ViewRequest)(
    implicit hc: HeaderCarrier,
    ec: ExecutionContext,
    logContext: EndpointLogContext): Future[ServiceOutcome[ViewReturnResponse]] = {

    val result = for {
      desResponseWrapper <- EitherT(connector.viewReturn(request)).leftMap(mapDesErrors(desErrorMap))
    } yield desResponseWrapper

    result.value
  }

  private def desErrorMap: Map[String, MtdError] =
    Map(
      "INVALID_VRN" -> VrnFormatErrorDes,
      "INVALID_PERIODKEY" -> PeriodKeyFormatErrorDes,
      "INVALID_IDENTIFIER" -> PeriodKeyFormatErrorDesNotFound,
      "NOT_FOUND_VRN" -> DownstreamError,
      "DATE_RANGE_TOO_LARGE" -> RuleDateRangeTooLargeError,
      "INVALID_INPUTDATA" -> InvalidInputDataError,
      "NOT_FOUND" -> EmptyNotFoundError,
      "SERVICE_ERROR" -> DownstreamError,
      "SERVICE_UNAVAILABLE" -> DownstreamError
    )
} 
Example 93
Source File: SubmitReturnService.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.services

import cats.data.EitherT
import cats.implicits._
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.http.HeaderCarrier
import utils.{EndpointLogContext, Logging}
import v1.connectors.SubmitReturnConnector
import v1.models.errors._
import v1.models.request.submit.SubmitRequest
import v1.models.response.submit.SubmitResponse
import v1.support.DesResponseMappingSupport

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class SubmitReturnService @Inject()(connector: SubmitReturnConnector) extends DesResponseMappingSupport with Logging {

  def submitReturn(request: SubmitRequest)(
    implicit hc: HeaderCarrier,
    ec: ExecutionContext,
    logContext: EndpointLogContext): Future[ServiceOutcome[SubmitResponse]] = {

    val result = for {
      desResponseWrapper <- EitherT(connector.submitReturn(request)).leftMap(mapDesErrors(desErrorMap))
    } yield desResponseWrapper

    result.value
  }

  private def desErrorMap: Map[String, MtdError] =
    Map(
      "INVALID_VRN" -> VrnFormatErrorDes,
      "INVALID_PERIODKEY" -> PeriodKeyFormatErrorDes,
      "INVALID_PAYLOAD" -> BadRequestError,
      "TAX_PERIOD_NOT_ENDED" -> TaxPeriodNotEnded,
      "DUPLICATE_SUBMISSION" -> DuplicateVatSubmission,
      "NOT_FOUND_VRN" -> DownstreamError,
      "INVALID_SUBMISSION" -> DownstreamError,
      "INVALID_ORIGINATOR_ID" -> DownstreamError,
      "SERVICE_ERROR" -> DownstreamError,
      "SERVICE_UNAVAILABLE" -> DownstreamError
    )
} 
Example 94
Source File: AuditService.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.services

import javax.inject.{Inject, Singleton}
import play.api.libs.json.{Json, Writes}
import play.api.{Configuration, Logger}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.play.audit.AuditExtensions
import uk.gov.hmrc.play.audit.http.connector.{AuditConnector, AuditResult}
import uk.gov.hmrc.play.audit.model.ExtendedDataEvent
import uk.gov.hmrc.play.bootstrap.config.AppName
import v1.models.audit.AuditEvent

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class AuditService @Inject()(auditConnector: AuditConnector,
                             appNameConfiguration: Configuration) {

  val logger: Logger = Logger(this.getClass)

  def auditEvent[T](event: AuditEvent[T])(implicit hc: HeaderCarrier, ec: ExecutionContext, writer: Writes[T]): Future[AuditResult] = {

    val eventTags = AuditExtensions.auditHeaderCarrier(hc).toAuditTags() +
      ("transactionName" -> event.transactionName)

    val dataEvent = ExtendedDataEvent(
      auditSource = AppName.fromConfiguration(appNameConfiguration),
      auditType = event.auditType,
      detail = Json.toJson(event.detail),
      tags = eventTags
    )
    logger.info(s"Audit event :- dataEvent.tags :: ${dataEvent.tags} --  auditSource:: ${dataEvent.auditSource}" +
      s" --- detail :: ${dataEvent.detail}")
    auditConnector.sendExtendedEvent(dataEvent)
  }
} 
Example 95
Source File: LiabilitiesService.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.services

import cats.data.EitherT
import cats.implicits._
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.http.HeaderCarrier
import utils.{EndpointLogContext, Logging}
import v1.connectors.LiabilitiesConnector
import v1.models.errors._
import v1.models.request.liabilities.LiabilitiesRequest
import v1.models.response.liabilities.LiabilitiesResponse
import v1.support.DesResponseMappingSupport

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class LiabilitiesService @Inject()(connector: LiabilitiesConnector) extends DesResponseMappingSupport with Logging {

  def retrieveLiabilities(request: LiabilitiesRequest)(
    implicit hc: HeaderCarrier,
    ec: ExecutionContext,
    logContext: EndpointLogContext): Future[ServiceOutcome[LiabilitiesResponse]] = {

    val result = for {
      desResponseWrapper <- EitherT(connector.retrieveLiabilities(request)).leftMap(mapDesErrors(desErrorMap))
      mtdResponseWrapper <- EitherT.fromEither[Future](validateLiabilitiesSuccessResponse(desResponseWrapper))
    } yield mtdResponseWrapper

    result.value
  }

  private def desErrorMap: Map[String, MtdError] =
    Map(
      "INVALID_IDTYPE" -> DownstreamError,
      "INVALID_IDNUMBER" -> VrnFormatErrorDes,
      "INVALID_REGIMETYPE" -> DownstreamError,
      "INVALID_ONLYOPENITEMS" -> DownstreamError,
      "INVALID_INCLUDELOCKS" -> DownstreamError,
      "INVALID_CALCULATEACCRUEDINTEREST" -> DownstreamError,
      "INVALID_CUSTOMERPAYMENTINFORMATION" -> DownstreamError,
      "INVALID_DATEFROM" -> InvalidDateFromErrorDes,
      "INVALID_DATETO" -> InvalidDateToErrorDes,
      "NOT_FOUND" -> LegacyNotFoundError,
      "INVALID_DATA" -> InvalidDataError,
      "SERVER_ERROR" -> DownstreamError,
      "SERVICE_UNAVAILABLE" -> DownstreamError
    )
} 
Example 96
Source File: PaymentsService.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.services

import cats.data.EitherT
import cats.implicits._
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.http.HeaderCarrier
import utils.{EndpointLogContext, Logging}
import v1.connectors.PaymentsConnector
import v1.models.errors._
import v1.models.request.payments.PaymentsRequest
import v1.models.response.payments.PaymentsResponse
import v1.support.DesResponseMappingSupport

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class PaymentsService @Inject()(connector: PaymentsConnector) extends DesResponseMappingSupport with Logging {

  def retrievePayments(request: PaymentsRequest)(
    implicit hc: HeaderCarrier,
    ec: ExecutionContext,
    logContext: EndpointLogContext): Future[ServiceOutcome[PaymentsResponse]] = {

    val result = for {
      desResponseWrapper <- EitherT(connector.retrievePayments(request)).leftMap(mapDesErrors(desErrorMap))
      mtdResponseWrapper <- EitherT.fromEither[Future](validatePaymentsSuccessResponse(desResponseWrapper))
    } yield mtdResponseWrapper

    result.value
  }

  private def desErrorMap: Map[String, MtdError] =
    Map(
      "INVALID_IDTYPE" -> DownstreamError,
      "INVALID_IDNUMBER" -> VrnFormatErrorDes,
      "INVALID_REGIMETYPE" -> DownstreamError,
      "INVALID_ONLYOPENITEMS" -> DownstreamError,
      "INVALID_INCLUDELOCKS" -> DownstreamError,
      "INVALID_CALCULATEACCRUEDINTEREST" -> DownstreamError,
      "INVALID_CUSTOMERPAYMENTINFORMATION" -> DownstreamError,
      "INVALID_DATEFROM" -> InvalidDateFromErrorDes,
      "INVALID_DATETO" -> InvalidDateToErrorDes,
      "INVALID_DATA" -> InvalidDataError,
      "NOT_FOUND" -> LegacyNotFoundError,
      "SERVER_ERROR" -> DownstreamError,
      "SERVICE_UNAVAILABLE" -> DownstreamError
    )
} 
Example 97
Source File: PaymentsController.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.controllers

import cats.data.EitherT
import cats.implicits._
import javax.inject.{Inject, Singleton}
import play.api.http.MimeTypes
import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent, ControllerComponents, Result}
import utils.{EndpointLogContext, Logging}
import v1.audit.AuditEvents
import v1.controllers.requestParsers.PaymentsRequestParser
import v1.models.audit.AuditResponse
import v1.models.errors._
import v1.models.request.payments.PaymentsRawData
import v1.services.{AuditService, EnrolmentsAuthService, PaymentsService}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class PaymentsController @Inject()(val authService: EnrolmentsAuthService,
                                   requestParser: PaymentsRequestParser,
                                   service: PaymentsService,
                                   auditService: AuditService,
                                   cc: ControllerComponents)(implicit ec: ExecutionContext)
extends AuthorisedController(cc) with BaseController with Logging {

  implicit val endpointLogContext: EndpointLogContext =
    EndpointLogContext(
      controllerName = "PaymentsController",
      endpointName = "retrievePayments"
    )

  def retrievePayments(vrn: String, from: Option[String], to: Option[String]): Action[AnyContent] =
    authorisedAction(vrn).async{ implicit request =>
      logger.info(s"[${endpointLogContext.controllerName}][${endpointLogContext.endpointName}] " +
        s"Successfully retrieved Payments from DES")

      val rawRequest: PaymentsRawData =
        PaymentsRawData(
          vrn = vrn,
          from = from,
          to = to
        )

      val result =
        for {
          parsedRequest <- EitherT.fromEither[Future](requestParser.parseRequest(rawRequest))
          serviceResponse <- EitherT(service.retrievePayments(parsedRequest))
        } yield {
          logger.info(s"[${endpointLogContext.controllerName}][${endpointLogContext.endpointName}] " +
            s"Successfully retrieved Payments from DES")

          auditService.auditEvent(AuditEvents.auditPayments(serviceResponse.correlationId,
            request.userDetails, AuditResponse(OK, Right(Some(Json.toJson(serviceResponse.responseData))))))

          Ok(Json.toJson(serviceResponse.responseData))
            .withApiHeaders(serviceResponse.correlationId)
            .as(MimeTypes.JSON)
        }

      result.leftMap{errorWrapper =>
        val correlationId = getCorrelationId(errorWrapper)
        val result = errorResult(errorWrapper).withApiHeaders(correlationId)
        logger.warn(ControllerError(endpointLogContext ,vrn, request, result.header.status, errorWrapper.error.message))

        auditService.auditEvent(AuditEvents.auditPayments(correlationId,
          request.userDetails, AuditResponse(httpStatus = result.header.status, Left(errorWrapper.auditErrors))))

        result
      }.merge

    }

  private def errorResult(errorWrapper: ErrorWrapper): Result = {
    (errorWrapper.error: @unchecked) match {
      case VrnFormatError | VrnFormatErrorDes |
           FinancialDataInvalidDateFromError | InvalidDateFromErrorDes |
           FinancialDataInvalidDateToError | InvalidDateToErrorDes |
           FinancialDataInvalidDateRangeError | InvalidDataError
      => BadRequest(Json.toJson(errorWrapper))
      case LegacyNotFoundError => NotFound(Json.toJson(errorWrapper))
      case DownstreamError => InternalServerError(Json.toJson(errorWrapper))
    }
  }
} 
Example 98
Source File: LiabilitiesController.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.controllers

import cats.data.EitherT
import cats.implicits._
import javax.inject.{Inject, Singleton}
import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent, ControllerComponents}
import play.mvc.Http.MimeTypes
import utils.{EndpointLogContext, Logging}
import v1.audit.AuditEvents
import v1.controllers.requestParsers.LiabilitiesRequestParser
import v1.models.audit.AuditResponse
import v1.models.errors.ControllerError._
import v1.models.errors._
import v1.models.request.liabilities.LiabilitiesRawData
import v1.services.{AuditService, EnrolmentsAuthService, LiabilitiesService}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class LiabilitiesController @Inject()(val authService: EnrolmentsAuthService,
                                      requestParser: LiabilitiesRequestParser,
                                      service: LiabilitiesService,
                                      auditService: AuditService,
                                      cc: ControllerComponents)(implicit ec: ExecutionContext)
  extends AuthorisedController(cc) with BaseController with Logging {

  implicit val endpointLogContext: EndpointLogContext =
    EndpointLogContext(
      controllerName = "LiabilitiesController",
      endpointName = "retrieveLiabilities"
    )

  def retrieveLiabilities(vrn: String, from: Option[String], to: Option[String]): Action[AnyContent] =
    authorisedAction(vrn).async { implicit request =>
      logger.info(message = s"[${endpointLogContext.controllerName}][${endpointLogContext.endpointName}] " +
        s"Retrieving Liabilities from DES")

      val rawRequest: LiabilitiesRawData = LiabilitiesRawData(vrn, from, to)

      val result = for {
        parsedRequest <- EitherT.fromEither[Future](requestParser.parseRequest(rawRequest))
        serviceResponse <- EitherT(service.retrieveLiabilities(parsedRequest))
      } yield {
        logger.info(message = s"[${endpointLogContext.controllerName}][${endpointLogContext.endpointName}] " +
          s"Successfully retrieved Liabilities from DES")

        auditService.auditEvent(AuditEvents.auditLiabilities(serviceResponse.correlationId,
          request.userDetails, AuditResponse(OK, Right(Some(Json.toJson(serviceResponse.responseData))))))

        Ok(Json.toJson(serviceResponse.responseData))
          .withApiHeaders(serviceResponse.correlationId)
          .as(MimeTypes.JSON)
      }

      result.leftMap { errorWrapper =>
        val correlationId = getCorrelationId(errorWrapper)
        val result = errorResult(errorWrapper).withApiHeaders(correlationId)
        logger.warn(ControllerError(endpointLogContext ,vrn, request, result.header.status, errorWrapper.error.message))

        auditService.auditEvent(AuditEvents.auditLiabilities(correlationId,
          request.userDetails, AuditResponse(httpStatus = result.header.status, Left(errorWrapper.auditErrors))))

        result
      }.merge

    }

  private def errorResult(errorWrapper: ErrorWrapper) = {
    (errorWrapper.error: @unchecked) match {
      case VrnFormatError | VrnFormatErrorDes | BadRequestError |
           FinancialDataInvalidDateFromError | InvalidDateFromErrorDes |
           FinancialDataInvalidDateToError | InvalidDateToErrorDes |
           FinancialDataInvalidDateRangeError | InvalidDataError
      => BadRequest(Json.toJson(errorWrapper))
      case LegacyNotFoundError => NotFound(Json.toJson(errorWrapper))
      case DownstreamError => InternalServerError(Json.toJson(errorWrapper))
    }
  }
} 
Example 99
Source File: ObligationsController.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.controllers

import cats.data.EitherT
import cats.implicits._
import javax.inject.{Inject, Singleton}
import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent, ControllerComponents}
import play.mvc.Http.MimeTypes
import utils.{EndpointLogContext, Logging}
import v1.audit.AuditEvents
import v1.controllers.requestParsers.ObligationsRequestParser
import v1.models.audit.AuditResponse
import v1.models.errors._
import v1.models.request.obligations.ObligationsRawData
import v1.services.{AuditService, EnrolmentsAuthService, ObligationsService}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ObligationsController @Inject()(val authService: EnrolmentsAuthService,
                                      requestParser: ObligationsRequestParser,
                                      service: ObligationsService,
                                      auditService: AuditService,
                                      cc: ControllerComponents)(implicit ec: ExecutionContext)
  extends AuthorisedController(cc) with BaseController with Logging {

  implicit val endpointLogContext: EndpointLogContext =
    EndpointLogContext(
      controllerName = "ObligationsController",
      endpointName = "retrieveObligations"
    )

  def retrieveObligations(vrn: String, from: Option[String], to: Option[String], status: Option[String]): Action[AnyContent] =
    authorisedAction(vrn).async{ implicit request =>
      logger.info(message = s"[${endpointLogContext.controllerName}][${endpointLogContext.endpointName}] Retrieve obligations for VRN : $vrn")

      val rawRequest: ObligationsRawData =
        ObligationsRawData(
          vrn = vrn,
          from = from,
          to = to,
          status = status
        )

      val result =
        for {
          parsedRequest <- EitherT.fromEither[Future](requestParser.parseRequest(rawRequest))
          serviceResponse <- EitherT(service.retrieveObligations(parsedRequest))
        } yield {
          logger.info(message = s"[${endpointLogContext.controllerName}][${endpointLogContext.endpointName}] Successfully retrieved Obligations from DES")

          auditService.auditEvent(AuditEvents.auditObligations(serviceResponse.correlationId,
            request.userDetails, AuditResponse(OK, Right(Some(Json.toJson(serviceResponse.responseData))))))

          Ok(Json.toJson(serviceResponse.responseData))
            .withApiHeaders(serviceResponse.correlationId)
            .as(MimeTypes.JSON)
        }

      result.leftMap { errorWrapper =>
        val correlationId = getCorrelationId(errorWrapper)
        val result = errorResult(errorWrapper).withApiHeaders(correlationId)
        logger.warn(ControllerError(endpointLogContext ,vrn, request, result.header.status, errorWrapper.error.message))

        auditService.auditEvent(AuditEvents.auditObligations(correlationId,
          request.userDetails, AuditResponse(httpStatus = result.header.status, Left(errorWrapper.auditErrors))))

        result
      }.merge

    }

  private def errorResult(errorWrapper: ErrorWrapper) = {
    (errorWrapper.error: @unchecked) match {
      case VrnFormatError | VrnFormatErrorDes |
           InvalidFromError | InvalidToError |
           InvalidStatusError | InvalidDateFromErrorDes |
           InvalidDateToErrorDes | InvalidStatusErrorDes |
           RuleDateRangeInvalidError | RuleOBLDateRangeTooLargeError |
           RuleMissingDateRangeError | BadRequestError => BadRequest(Json.toJson(errorWrapper))
      case LegacyNotFoundError => NotFound(Json.toJson(errorWrapper))
      case DownstreamError => InternalServerError(Json.toJson(errorWrapper))
    }
  }
} 
Example 100
Source File: ViewReturnController.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.controllers

import cats.data.EitherT
import cats.implicits._
import javax.inject.{Inject, Singleton}
import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent, ControllerComponents}
import play.mvc.Http.MimeTypes
import utils.{EndpointLogContext, Logging}
import v1.audit.AuditEvents
import v1.controllers.requestParsers.ViewReturnRequestParser
import v1.models.audit.AuditResponse
import v1.models.errors._
import v1.models.request.viewReturn.ViewRawData
import v1.services.{AuditService, EnrolmentsAuthService, ViewReturnService}

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ViewReturnController @Inject()(val authService: EnrolmentsAuthService,
                                    requestParser: ViewReturnRequestParser,
                                    service: ViewReturnService,
                                    auditService: AuditService,
                                    cc: ControllerComponents)(implicit ec: ExecutionContext)
  extends AuthorisedController(cc) with BaseController with Logging {

  implicit val endpointLogContext: EndpointLogContext =
    EndpointLogContext(
      controllerName = "ViewReturnController",
      endpointName = "viewReturn"
    )

  def viewReturn(vrn: String, periodKey: String): Action[AnyContent] =
    authorisedAction(vrn).async{ implicit request =>
      logger.info(message = s"[${endpointLogContext.controllerName}][${endpointLogContext.endpointName}] " +
        s"Retrieve VAT returns for VRN : $vrn")

      val rawRequest: ViewRawData =
        ViewRawData(
          vrn = vrn,
          periodKey = periodKey
        )

      val result =
        for {
          parsedRequest <- EitherT.fromEither[Future](requestParser.parseRequest(rawRequest))
          serviceResponse <- EitherT(service.viewReturn(parsedRequest))
        } yield {
          logger.info(message = s"[${endpointLogContext.controllerName}][${endpointLogContext.endpointName}] " +
            s"Successfully retrieved Vat Return from DES")

          auditService.auditEvent(AuditEvents.auditReturns(serviceResponse.correlationId,
            request.userDetails, AuditResponse(OK, Right(Some(Json.toJson(serviceResponse.responseData))))))

          Ok(Json.toJson(serviceResponse.responseData))
            .withApiHeaders(serviceResponse.correlationId)
            .as(MimeTypes.JSON)
        }

      result.leftMap { errorWrapper =>
        val correlationId = getCorrelationId(errorWrapper)
        val result = errorResult(errorWrapper).withApiHeaders(correlationId)
        logger.warn(ControllerError(endpointLogContext ,vrn, request, result.header.status, errorWrapper.error.message))

        auditService.auditEvent(AuditEvents.auditReturns(correlationId,
          request.userDetails, AuditResponse(httpStatus = result.header.status, Left(errorWrapper.auditErrors))))

        result
      }.merge

    }

  private def errorResult(errorWrapper: ErrorWrapper) = {
    (errorWrapper.error: @unchecked) match {
      case VrnFormatError | VrnFormatErrorDes |
           PeriodKeyFormatError | PeriodKeyFormatErrorDes |
           BadRequestError => BadRequest(Json.toJson(errorWrapper))
      case RuleDateRangeTooLargeError | InvalidInputDataError => Forbidden(Json.toJson(errorWrapper))
      case PeriodKeyFormatErrorDesNotFound => NotFound(Json.toJson(errorWrapper))
      case EmptyNotFoundError => NotFound
      case DownstreamError => InternalServerError(Json.toJson(errorWrapper))
    }
  }
} 
Example 101
Source File: LiabilitiesConnector.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.connectors

import config.AppConfig
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import v1.models.errors.{ConnectorError, ControllerError}
import v1.models.request.liabilities.LiabilitiesRequest
import v1.models.response.liabilities.LiabilitiesResponse

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class LiabilitiesConnector @Inject()(val http: HttpClient,
                                     val appConfig: AppConfig) extends BaseDesConnector {

  def retrieveLiabilities(request: LiabilitiesRequest)(implicit hc: HeaderCarrier,
                                                       ec: ExecutionContext): Future[DesOutcome[LiabilitiesResponse]] = {

    import v1.connectors.httpparsers.StandardDesHttpParser._
    implicit val requestToDate: String = request.to
    implicit val connectorError: ConnectorError =
      ConnectorError(request.vrn.vrn, hc.requestId.fold(""){ requestId => requestId.value})

    val queryParams: Seq[(String, String)] = Seq(
      ("dateFrom", request.from),
      ("dateTo", request.to),
      ("onlyOpenItems", "false"),
      ("includeLocks", "false"),
      ("calculateAccruedInterest", "true"),
      ("customerPaymentInformation", "true")
    )

    get(
      uri = DesUri[LiabilitiesResponse](s"enterprise/financial-data/VRN/${request.vrn.vrn}/VATC"),
      queryParams = queryParams
    )
  }
} 
Example 102
Source File: PaymentsConnector.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.connectors

import config.AppConfig
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import v1.models.errors.ConnectorError
import v1.models.request.payments.PaymentsRequest
import v1.models.response.payments.PaymentsResponse

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class PaymentsConnector @Inject()(val http: HttpClient,
                                  val appConfig: AppConfig) extends BaseDesConnector {

  def retrievePayments(request: PaymentsRequest)(implicit hc: HeaderCarrier,
                                                 ec: ExecutionContext): Future[DesOutcome[PaymentsResponse]] = {

    import v1.connectors.httpparsers.StandardDesHttpParser._
    implicit val requestToDate: String = request.to
    implicit val connectorError: ConnectorError =
      ConnectorError(request.vrn.vrn, hc.requestId.fold(""){ requestId => requestId.value})

    val queryParams: Seq[(String, String)] = Seq(
      ("dateFrom", request.from),
      ("dateTo", request.to),
      ("onlyOpenItems", "false"),
      ("includeLocks", "false"),
      ("calculateAccruedInterest", "true"),
      ("customerPaymentInformation", "true")
    )

    get(
      uri = DesUri[PaymentsResponse](s"enterprise/financial-data/VRN/${request.vrn.vrn}/VATC"),
      queryParams = queryParams
    )
  }
} 
Example 103
Source File: SubmitReturnConnector.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.connectors

import config.AppConfig
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import v1.models.errors.ConnectorError
import v1.models.request.submit.SubmitRequest
import v1.models.response.submit.SubmitResponse

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class SubmitReturnConnector @Inject()(val http: HttpClient,
                                      val appConfig: AppConfig) extends BaseDesConnector {

  def submitReturn(request: SubmitRequest)(
    implicit hc: HeaderCarrier,
    ec: ExecutionContext): Future[DesOutcome[SubmitResponse]] = {

    import v1.connectors.httpparsers.StandardDesHttpParser._

    val vrn = request.vrn.vrn
    implicit val connectorError: ConnectorError =
      ConnectorError(vrn, hc.requestId.fold(""){ requestId => requestId.value})

    post(
      body = request.body,
      uri = DesUri[SubmitResponse](s"enterprise/return/vat/$vrn")
    )
  }
} 
Example 104
Source File: ViewReturnConnector.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.connectors

import config.AppConfig
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import v1.models.errors.ConnectorError
import v1.models.request.viewReturn.ViewRequest
import v1.models.response.viewReturn.ViewReturnResponse

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ViewReturnConnector @Inject()(val http: HttpClient,
                                    val appConfig: AppConfig) extends BaseDesConnector {

  def viewReturn(request: ViewRequest)(
    implicit hc: HeaderCarrier,
    ec: ExecutionContext): Future[DesOutcome[ViewReturnResponse]] = {

    import v1.connectors.httpparsers.StandardDesHttpParser._

    val vrn = request.vrn.vrn
    implicit val connectorError: ConnectorError =
      ConnectorError(vrn, hc.requestId.fold(""){ requestId => requestId.value})

    val queryParams: Seq[(String, String)] =
      Seq(
        "period-key" -> request.periodKey
      )

    get(
      uri = DesUri[ViewReturnResponse](s"vat/returns/vrn/$vrn"),
      queryParams = queryParams
    )
  }
} 
Example 105
Source File: ObligationsConnector.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.connectors

import config.AppConfig
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import v1.models.errors.ConnectorError
import v1.models.request.obligations.ObligationsRequest
import v1.models.response.obligations.ObligationsResponse

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class ObligationsConnector @Inject()(val http: HttpClient,
                                     val appConfig: AppConfig) extends BaseDesConnector {

  def retrieveObligations(request: ObligationsRequest)(
    implicit hc: HeaderCarrier,
    ec: ExecutionContext): Future[DesOutcome[ObligationsResponse]] = {

    import v1.connectors.httpparsers.StandardDesHttpParser._

    val vrn = request.vrn.vrn

    implicit val connectorError: ConnectorError =
      ConnectorError(vrn, hc.requestId.fold(""){ requestId => requestId.value})

    val queryParams: Seq[(String, String)] =
      Seq(
        "from" -> request.from,
        "to" -> request.to,
        "status" -> request.status
      ) collect {
        case (key, Some(value)) => key -> value
      }

    get(
      uri = DesUri[ObligationsResponse](s"enterprise/obligation-data/vrn/$vrn/VATC"),
      queryParams = queryParams
    )
  }
} 
Example 106
Source File: NrsConnector.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package v1.connectors

import config.AppConfig
import javax.inject.{Inject, Singleton}
import play.api.libs.ws.WSClient
import uk.gov.hmrc.http.HeaderCarrier
import v1.models.nrs.request.NrsSubmission
import v1.models.nrs.response.NrsResponse

import scala.concurrent.{ExecutionContext, Future}

@Singleton
class NrsConnector @Inject()(val ws: WSClient,
                             val appConfig: AppConfig) extends BaseNrsConnector {

  def submitNrs(body: NrsSubmission)(
    implicit hc: HeaderCarrier,
    ec: ExecutionContext): Future[NrsOutcome[NrsResponse]] = {

    import v1.connectors.httpparsers.StandardNrsWsParser._

    nrsPost[NrsSubmission, NrsResponse](
      uri = NrsUri[NrsResponse](s"submission"),
      body = body,
      defaultResult = Right(NrsResponse.empty)
    )
  }
} 
Example 107
Source File: VersionRoutingRequestHandler.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package routing

import config.{AppConfig, FeatureSwitch}
import definition.Versions
import javax.inject.{Inject, Singleton}
import play.api.http.{DefaultHttpRequestHandler, HttpConfiguration, HttpErrorHandler, HttpFilters}
import play.api.libs.json.Json
import play.api.mvc.{DefaultActionBuilder, Handler, RequestHeader, Results}
import play.api.routing.Router
import v1.controllers.requestParsers.validators.validations.VrnValidation
import v1.models.errors.{InvalidAcceptHeaderError, UnsupportedVersionError, VrnFormatError}

@Singleton
class VersionRoutingRequestHandler @Inject()(versionRoutingMap: VersionRoutingMap,
                                             errorHandler: HttpErrorHandler,
                                             httpConfiguration: HttpConfiguration,
                                             config: AppConfig,
                                             filters: HttpFilters,
                                             action: DefaultActionBuilder)
  extends DefaultHttpRequestHandler(versionRoutingMap.defaultRouter, errorHandler, httpConfiguration, filters) {

  private val featureSwitch = FeatureSwitch(config.featureSwitch)

  private val unsupportedVersionAction = action(Results.NotFound(Json.toJson(UnsupportedVersionError)))

  private val invalidAcceptHeaderError = action(Results.NotAcceptable(Json.toJson(InvalidAcceptHeaderError)))

  override def routeRequest(request: RequestHeader): Option[Handler] = {

    def documentHandler = routeWith(versionRoutingMap.defaultRouter)(request)

    def apiHandler = Versions.getFromRequest(request) match {
      case Some(version) =>
        versionRoutingMap.versionRouter(version) match {
          case Some(versionRouter) if featureSwitch.isVersionEnabled(version) =>
            routeWith(versionRouter)(request)
          case Some(_) => Some(unsupportedVersionAction)
          case None => Some(unsupportedVersionAction)
        }
      case None => Some(invalidAcceptHeaderError)
    }

    documentHandler orElse apiHandler
  }

  private def routeWith(router: Router)(request: RequestHeader) =
    router
      .handlerFor(request)
      .orElse {
        if (validatePath(request.path)) {
          if (request.path.endsWith("/")) {
            val pathWithoutSlash = request.path.dropRight(1)
            val requestWithModifiedPath = request.withTarget(request.target.withPath(pathWithoutSlash))
            router.handlerFor(requestWithModifiedPath)
          }
          else None
        }
        else {
          Some(action(Results.BadRequest(Json.toJson(VrnFormatError))))
        }
      }

  private def validatePath(path: String) = {
    val vrn = path.split("/")(1)
    if(VrnValidation.validate(vrn) == Nil)
      true
    else false
  }
} 
Example 108
Source File: ApiDefinitionFactory.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package definition

import config.{AppConfig, FeatureSwitch}
import javax.inject.{Inject, Singleton}
import play.api.Logger

@Singleton
class ApiDefinitionFactory @Inject()(appConfig: AppConfig) {

  private val readScope = "read:vat"
  private val writeScope = "write:vat"

  lazy val definition: Definition =
    Definition(
      scopes = Seq(
        Scope(
          key = readScope,
          name = "View your VAT information",
          description = "Allow read access to VAT data"
        ),
        Scope(
          key = writeScope,
          name = "Change your VAT information",
          description = "Allow write access to VAT data"
        )
      ),
      api = APIDefinition(
        name = "VAT (MTD)",
        description =
          "An API for providing VAT data",
        context = appConfig.apiGatewayContext,
        categories = Seq("VAT_MTD"),
        versions = Seq(
          APIVersion(
            version = "1.0",
            access = buildWhiteListingAccess(),
            status = buildAPIStatus("1.0"),
            endpointsEnabled = true
          )
        ),
        requiresTrust = None
      )
    )

  private[definition] def buildAPIStatus(version: String): APIStatus = {
    APIStatus.parser.lift(appConfig.apiStatus(version))
      .getOrElse {
        Logger.error(s"[ApiDefinition][buildApiStatus] no API Status found in config.  Reverting to Alpha")
        APIStatus.ALPHA
      }
  }

  private[definition] def buildWhiteListingAccess(): Option[Access] = {
    val featureSwitch = FeatureSwitch(appConfig.featureSwitch)
    if (featureSwitch.isWhiteListingEnabled) Some(Access("PRIVATE", featureSwitch.whiteListedApplicationIds)) else None
  }
} 
Example 109
Source File: DocumentationController.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package config

import controllers.Assets
import definition.ApiDefinitionFactory
import javax.inject.{Inject, Singleton}
import play.api.http.HttpErrorHandler
import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent, ControllerComponents}
import uk.gov.hmrc.api.controllers.{DocumentationController => HmrcDocumentationController}

@Singleton
class DocumentationController @Inject()(vatApiDefinition: ApiDefinitionFactory,
                                        cc: ControllerComponents, assets: Assets, errorHandler: HttpErrorHandler)
  extends HmrcDocumentationController(cc,assets , errorHandler ) {

  override def definition(): Action[AnyContent] = Action {
    Ok(Json.toJson(vatApiDefinition.definition))
  }

  def raml(version: String, file: String): Action[AnyContent] = {
    assets.at(s"/public/api/conf/$version", file)
  }
} 
Example 110
Source File: ObligationsResource.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.vatapi.resources

import javax.inject.{Inject, Singleton}
import play.api.mvc.{Action, AnyContent, ControllerComponents}
import uk.gov.hmrc.domain.Vrn
import uk.gov.hmrc.vatapi.audit.AuditEvents
import uk.gov.hmrc.vatapi.connectors.ObligationsConnector
import uk.gov.hmrc.vatapi.models.{Errors, ObligationsQueryParams}
import uk.gov.hmrc.vatapi.resources.wrappers.Response
import uk.gov.hmrc.vatapi.services.{AuditService, AuthorisationService}
import uk.gov.hmrc.vatapi.utils.pagerDutyLogging.Endpoint

import scala.concurrent.ExecutionContext

@Singleton
class ObligationsResource @Inject()(
                                     connector: ObligationsConnector,
                                     val authService: AuthorisationService,
                                     auditService: AuditService,
                                     cc: ControllerComponents
                                   )(implicit ec: ExecutionContext) extends BaseResource(cc) {

  def retrieveObligations(vrn: Vrn, params: ObligationsQueryParams): Action[AnyContent] = APIAction(vrn).async { implicit request =>
    logger.debug(s"[ObligationsResource][retrieveObligations] - Retrieve Obligations for VRN : $vrn")

    val arn = getArn
    val clientId = getClientId

    implicit val endpoint: Endpoint = Endpoint.RetrieveObligations

    def audit(vatResult: VatResult, correlationId: String) =
      auditService.audit(AuditEvents.retrieveVatObligationsAudit(correlationId,
        request.authContext.affinityGroup, arn, clientId, vatResult.auditResponse))

    val result =
      for {
        desResponse <- connector.get(vrn, params)
      } yield {
        val result = desResponse.filter {
          case OK =>
            desResponse.obligations(vrn) match {
              case Right(Some(obligations)) =>
                logger.debug(s"[ObligationsResource][retrieveObligations] Successfully retrieved Obligations from DES")
                VatResult.Success(OK, obligations)
              case Right(None) =>
                VatResult.Failure(NOT_FOUND, Errors.NotFound)
              case Left(ex) =>
                logger.error(s"[ObligationsResource][retrieveObligations] Json format from DES doesn't match the Obligations model: ${ex.msg}")
                VatResult.Failure(INTERNAL_SERVER_ERROR, Errors.InternalServerError)
            }
        }
        audit(result, desResponse.getCorrelationId)
        result
      }

    result.recover {
      case ex =>
        logger.warn(s"[ObligationsResource][retrieveObligations] Unexpected downstream error thrown ${ex.getMessage}")
        val result = VatResult.Failure(INTERNAL_SERVER_ERROR, Errors.InternalServerError)
        audit(result, Response.defaultCorrelationId)
        result
    }.map(_.result)
  }
} 
Example 111
Source File: DocumentationController.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.vatapi.controllers.definition

import controllers.Assets
import javax.inject.{Inject, Singleton}
import play.api.http.HttpErrorHandler
import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent, ControllerComponents}
import uk.gov.hmrc.api.controllers.{DocumentationController => HmrcDocumentationController}
import uk.gov.hmrc.vatapi.controllers.definition.JsonFormatters._

@Singleton
class DocumentationController @Inject()(vatApiDefinition: VatApiDefinition,
                                        cc: ControllerComponents, assets: Assets, errorHandler: HttpErrorHandler)
  extends HmrcDocumentationController(cc, assets , errorHandler ) {

  override def definition() = Action {
    Ok(Json.toJson(vatApiDefinition.definition))
  }

  def raml(version: String, file: String): Action[AnyContent] = {
    assets.at(s"/public/api/conf/$version", file)
  }
} 
Example 112
Source File: VatApiDefinition.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.vatapi.controllers.definition

import javax.inject.{Inject, Singleton}
import play.api.Logger
import uk.gov.hmrc.vatapi.config.AppContext
import uk.gov.hmrc.vatapi.controllers.definition.APIStatus.APIStatus

@Singleton
class VatApiDefinition @Inject()(appContext: AppContext) {

  lazy val definition: Definition =
    Definition(
      scopes = Seq(
        Scope(
          key = readScope,
          name = "View your VAT information",
          description = "Allow read access to VAT data"
        ),
        Scope(
          key = writeScope,
          name = "Change your VAT information",
          description = "Allow write access to VAT data"
        )
      ),
      api = OldAPIDefinition(
        name = "VAT (MTD)",
        description =
          "An API for providing VAT data",
        context = appContext.apiGatewayRegistrationContext,
        versions = Seq(
          APIVersion(
            version = "1.0",
            status = buildAPIStatus("1.0"),
            endpointsEnabled = true
          )
        ),
        requiresTrust = None
      )
    )
  val logger: Logger = Logger(this.getClass)

  private val readScope = "read:vat"
  private val writeScope = "write:vat"

  private def buildAPIStatus(version: String): APIStatus = {
    appContext.apiStatus(version) match {
      case "ALPHA" => APIStatus.ALPHA
      case "BETA" => APIStatus.BETA
      case "STABLE" => APIStatus.STABLE
      case "DEPRECATED" => APIStatus.DEPRECATED
      case "RETIRED" => APIStatus.RETIRED
      case _ => logger.error(s"[ApiDefinition][buildApiStatus] no API status found in config. Reverting to alpha")
        APIStatus.ALPHA
    }
  }

} 
Example 113
Source File: AppContext.scala    From vat-api   with Apache License 2.0 5 votes vote down vote up
package uk.gov.hmrc.vatapi.config

import com.typesafe.config.ConfigFactory
import javax.inject.{Inject, Singleton}
import play.api.Application
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
import uk.gov.hmrc.vatapi.auth.VATAuthEnrolments

@Singleton
class AppContext @Inject()(config: ServicesConfig, application: Application) extends FixedConfig {


  //API Platform Config
  lazy val appName: String = config.getString("appName")
  lazy val appUrl: String = config.getString("appUrl")
  lazy val apiGatewayContext: String = config.getString("api.gateway.context")
  lazy val apiGatewayRegistrationContext: String = apiGatewayContext
  lazy val apiGatewayLinkContext: String = apiGatewayContext
  lazy val registrationEnabled: Boolean = application.configuration.getOptional[Boolean](s"microservice.services.service-locator.enabled").getOrElse(true)
  lazy val serviceLocatorUrl: String = config.baseUrl("service-locator")

  //DES Config
  lazy val desEnv: String = config.getString(s"microservice.services.des.env")
  lazy val desToken: String = config.getString(s"microservice.services.des.token")
  lazy val desUrl: String = config.baseUrl("des")
  //NRS Config
  lazy val nrsServiceUrl: String = config.baseUrl("non-repudiation")
  lazy val xApiKey: String = config.getString(s"access-keys.xApiKey")
  lazy val nrsMaxTimeoutMillis: Int = config.getInt(s"microservice.services.non-repudiation.maxTimeout")

  lazy val featureSwitch: String = config.getString(s"feature-switch")

  lazy val vatAuthEnrolments: VATAuthEnrolments = VATAuthEnrolments(config.getString(s"enrolments.key"),
    config.getString(s"enrolments.identifier"),
    config.getConfString(s"enrolments.authRule", "mtd-vat-auth"))

  def apiStatus(version: String): String = config.getString(s"api.$version.status")
}

trait FixedConfig {
  val mtdDate = ConfigFactory.load().getString("mtd-date")
} 
Example 114
Source File: DatabaseModule.scala    From dr-cla   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package modules

import com.github.mauricio.async.db.SSLConfiguration
import com.github.mauricio.async.db.pool.{PartitionedConnectionPool, PoolConfiguration}
import com.github.mauricio.async.db.postgresql.pool.PostgreSQLConnectionFactory
import com.github.mauricio.async.db.postgresql.util.URLParser
import io.getquill.{PostgresAsyncContext, SnakeCase}
import javax.inject.{Inject, Singleton}
import org.slf4j.LoggerFactory
import play.api.inject.{ApplicationLifecycle, Binding, Module}
import play.api.{Configuration, Environment}

import scala.concurrent.ExecutionContext

class DatabaseModule extends Module {
  def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = {
    Seq(
      bind[Database].to[DatabaseImpl]
    )
  }
}

trait Database {
  val ctx: PostgresAsyncContext[SnakeCase]
}

@Singleton
class DatabaseImpl @Inject()(lifecycle: ApplicationLifecycle, playConfig: Configuration) (implicit ec: ExecutionContext) extends Database {

  private val log = LoggerFactory.getLogger(this.getClass)

  private val maybeDbUrl = playConfig.getOptional[String]("db.default.url")

  private val config = maybeDbUrl.map(URLParser.parse(_)).getOrElse(URLParser.DEFAULT)

  private val configWithMaybeSsl = playConfig.getOptional[String]("db.default.sslmode").fold(config) { sslmode =>
    val sslConfig = SSLConfiguration(Map("sslmode" -> sslmode))
    config.copy(ssl = sslConfig)
  }

  private val connectionFactory = new PostgreSQLConnectionFactory(configWithMaybeSsl)

  private val defaultPoolConfig = PoolConfiguration.Default

  private val maxObjects = playConfig.getOptional[Int]("db.default.max-objects").getOrElse(defaultPoolConfig.maxObjects)
  private val maxIdleMillis = playConfig.getOptional[Long]("db.default.max-idle-millis").getOrElse(defaultPoolConfig.maxIdle)
  private val maxQueueSize = playConfig.getOptional[Int]("db.default.max-queue-size").getOrElse(defaultPoolConfig.maxQueueSize)
  private val validationInterval = playConfig.getOptional[Long]("db.default.max-queue-size").getOrElse(defaultPoolConfig.validationInterval)

  private val poolConfig = new PoolConfiguration(maxObjects, maxIdleMillis, maxQueueSize, validationInterval)

  private val numberOfPartitions = playConfig.getOptional[Int]("db.default.number-of-partitions").getOrElse(4)

  private val pool = new PartitionedConnectionPool(
    connectionFactory,
    poolConfig,
    numberOfPartitions,
    ec
  )

  lifecycle.addStopHook { () =>
    pool.close
  }

  val ctx = new PostgresAsyncContext(SnakeCase, pool)

} 
Example 115
Source File: Migration.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.models

import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}
import scala.util.Success

import play.api.Logger
import play.api.libs.json.{JsNull, JsNumber, JsString, JsValue, Json}

import org.thp.cortex.services.{OrganizationSrv, UserSrv, WorkerSrv}

import org.elastic4play.controllers.Fields
import org.elastic4play.services.Operation._
import org.elastic4play.services.{DatabaseState, IndexType, MigrationOperations, Operation}
import org.elastic4play.utils.Hasher

@Singleton
class Migration @Inject()(userSrv: UserSrv, organizationSrv: OrganizationSrv, workerSrv: WorkerSrv, implicit val ec: ExecutionContext)
    extends MigrationOperations {

  lazy val logger                                = Logger(getClass)
  def beginMigration(version: Int): Future[Unit] = Future.successful(())

  def endMigration(version: Int): Future[Unit] =
    userSrv.inInitAuthContext { implicit authContext ⇒
      organizationSrv
        .create(Fields(Json.obj("name" → "cortex", "description" → "Default organization", "status" → "Active")))
        .transform(_ ⇒ Success(())) // ignore errors (already exist)
    }

  override def indexType(version: Int): IndexType.Value = if (version > 3) IndexType.indexWithoutMappingTypes else IndexType.indexWithMappingTypes

  val operations: PartialFunction[DatabaseState, Seq[Operation]] = {
    case DatabaseState(1) ⇒
      val hasher = Hasher("MD5")
      Seq(
        // add type to analyzer
        addAttribute("analyzer", "type" → JsString("analyzer")),
        renameAttribute("job", "workerDefinitionId", "analyzerDefinitionId"),
        renameAttribute("job", "workerId", "analyzerId"),
        renameAttribute("job", "workerName", "analyzerName"),
        addAttribute("job", "type"          → JsString(WorkerType.analyzer.toString)),
        addAttribute("report", "operations" → JsString("[]")),
        renameEntity("analyzer", "worker"),
        renameAttribute("worker", "workerDefinitionId", "analyzerDefinitionId"),
        addAttribute("worker", "type" → JsString(WorkerType.analyzer.toString)),
        mapEntity("worker") { worker ⇒
          val id = for {
            organizationId ← (worker \ "_parent").asOpt[String]
            name           ← (worker \ "name").asOpt[String]
            tpe            ← (worker \ "type").asOpt[String]
          } yield hasher.fromString(s"${organizationId}_${name}_$tpe").head.toString
          worker + ("_id" → JsString(id.getOrElse("<null>")))
        },
        renameEntity("analyzerConfig", "workerConfig"),
        addAttribute("workerConfig", "type" → JsString(WorkerType.analyzer.toString))
      )

    case DatabaseState(2) ⇒
      Seq(mapEntity("worker") { worker ⇒
        val definitionId = (worker \ "workerDefinitionId").asOpt[String]
        definitionId
          .flatMap(workerSrv.getDefinition(_).toOption)
          .fold {
            logger.warn(s"no definition found for worker ${definitionId.getOrElse(worker)}. You should probably have to disable and re-enable it")
            worker
          } { definition ⇒
            worker +
              ("version"     → JsString(definition.version)) +
              ("author"      → JsString(definition.author)) +
              ("url"         → JsString(definition.url)) +
              ("license"     → JsString(definition.license)) +
              ("command"     → definition.command.fold[JsValue](JsNull)(c ⇒ JsString(c.toString))) +
              ("dockerImage" → definition.dockerImage.fold[JsValue](JsNull)(JsString.apply)) +
              ("baseConfig"  → definition.baseConfiguration.fold[JsValue](JsNull)(JsString.apply))
          }
      })

    case DatabaseState(3) ⇒
      Seq(
        mapEntity("sequence") { seq ⇒
          val oldId   = (seq \ "_id").as[String]
          val counter = (seq \ "counter").as[JsNumber]
          seq - "counter" - "_routing" +
            ("_id"             → JsString("sequence_" + oldId)) +
            ("sequenceCounter" → counter)
        }
      )
  }
} 
Example 116
Source File: Worker.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.models

import javax.inject.{Inject, Singleton}
import org.elastic4play.models.JsonFormat.enumFormat
import org.elastic4play.models.{AttributeDef, BaseEntity, ChildModelDef, EntityDef, HiveEnumeration, AttributeFormat ⇒ F, AttributeOption ⇒ O}
import org.elastic4play.utils.Hasher
import org.thp.cortex.models.JsonFormat.workerTypeFormat
import play.api.libs.json.{JsObject, JsString, Json}

import scala.concurrent.Future
import scala.util.Try

object RateUnit extends Enumeration with HiveEnumeration {
  type Type = Value
  val Second         = Value(1)
  val Minute         = Value(60)
  val Hour           = Value(60 * 60)
  val Day            = Value(60 * 60 * 24)
  val Month          = Value(60 * 60 * 24 * 30)
  implicit val reads = enumFormat(this)
}

object WorkerType extends Enumeration with HiveEnumeration {
  type Type = Value
  val analyzer, responder = Value
}

trait WorkerAttributes { _: AttributeDef ⇒
  val workerId           = attribute("_id", F.stringFmt, "Worker id", O.model)
  val name               = attribute("name", F.stringFmt, "Worker name")
  val vers               = attribute("version", F.stringFmt, "Worker version", O.readonly)
  val workerDefinitionId = attribute("workerDefinitionId", F.stringFmt, "Worker definition id", O.readonly)
  val description        = attribute("description", F.textFmt, "Worker description", O.readonly)
  val author             = attribute("author", F.textFmt, "Worker author", O.readonly)
  val url                = attribute("url", F.textFmt, "Worker url", O.readonly)
  val license            = attribute("license", F.textFmt, "Worker license", O.readonly)
  val command            = optionalAttribute("command", F.textFmt, "Worker command", O.readonly)
  val dockerImage        = optionalAttribute("dockerImage", F.textFmt, "Worker docker image", O.readonly)
  val dataTypeList       = multiAttribute("dataTypeList", F.stringFmt, "List of data type this worker can manage")
  val configuration      = attribute("configuration", F.rawFmt, "Configuration of the worker", O.sensitive)
  val baseConfig         = attribute("baseConfig", F.stringFmt, "Base configuration key", O.readonly)
  val rate               = optionalAttribute("rate", F.numberFmt, "Number ")
  val rateUnit           = optionalAttribute("rateUnit", F.enumFmt(RateUnit), "")
  val jobCache           = optionalAttribute("jobCache", F.numberFmt, "")
  val jobTimeout         = optionalAttribute("jobTimeout", F.numberFmt, "")
  val tpe                = attribute("type", F.enumFmt(WorkerType), "", O.readonly)
}

@Singleton
class WorkerModel @Inject()(organizationModel: OrganizationModel)
    extends ChildModelDef[WorkerModel, Worker, OrganizationModel, Organization](organizationModel, "worker", "Worker", "/worker")
    with WorkerAttributes
    with AuditedModel {
  override def creationHook(parent: Option[BaseEntity], attrs: JsObject): Future[JsObject] = {
    val hasher = Hasher("md5")
    val id = for {
      organizationId ← parent.map(_.id)
      name           ← (attrs \ "name").asOpt[String]
      tpe            ← (attrs \ "type").asOpt[String]
    } yield hasher.fromString(s"${organizationId}_${name}_$tpe").head.toString
    Future.successful(attrs + ("_id" → JsString(id.getOrElse("<null>"))))
  }
}

class Worker(model: WorkerModel, attributes: JsObject) extends EntityDef[WorkerModel, Worker](model, attributes) with WorkerAttributes {
  def config: JsObject = Try(Json.parse(configuration()).as[JsObject]).getOrElse(JsObject.empty)
  def organization     = parentId.get
} 
Example 117
Source File: Artifact.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.models

import javax.inject.{Inject, Singleton}

import play.api.libs.json.JsObject

import org.elastic4play.models.{AttributeDef, EntityDef, AttributeFormat ⇒ F, AttributeOption ⇒ O, ChildModelDef}

trait ArtifactAttributes { _: AttributeDef ⇒
  val dataType   = attribute("dataType", F.stringFmt, "Type of the artifact", O.readonly)
  val data       = optionalAttribute("data", F.rawFmt, "Content of the artifact", O.readonly)
  val attachment = optionalAttribute("attachment", F.attachmentFmt, "Artifact file content", O.readonly)
  val tlp        = attribute("tlp", TlpAttributeFormat, "TLP level", 2L)
  val tags       = multiAttribute("tags", F.stringFmt, "Artifact tags")
  val message    = optionalAttribute("message", F.textFmt, "Message associated to the analysis")
}

@Singleton
class ArtifactModel @Inject()(reportModel: ReportModel)
    extends ChildModelDef[ArtifactModel, Artifact, ReportModel, Report](reportModel, "artifact", "Artifact", "/artifact")
    with ArtifactAttributes {}

class Artifact(model: ArtifactModel, attributes: JsObject) extends EntityDef[ArtifactModel, Artifact](model, attributes) with ArtifactAttributes 
Example 118
Source File: Organization.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.models

import javax.inject.{Inject, Provider, Singleton}

import scala.concurrent.{ExecutionContext, Future}

import play.api.Logger
import play.api.libs.json.{JsNumber, JsObject, JsString, Json}

import org.elastic4play.models.JsonFormat.enumFormat
import org.elastic4play.models.{AttributeDef, BaseEntity, EntityDef, HiveEnumeration, ModelDef, AttributeFormat ⇒ F, AttributeOption ⇒ O}
import org.elastic4play.services.FindSrv

object OrganizationStatus extends Enumeration with HiveEnumeration {
  type Type = Value
  val Active, Locked = Value
  implicit val reads = enumFormat(this)
}

trait OrganizationAttributes { _: AttributeDef ⇒
  val name        = attribute("name", F.stringFmt, "Organization name", O.form)
  val _id         = attribute("_id", F.stringFmt, "Organization name", O.model)
  val description = attribute("description", F.textFmt, "Organization description")
  val status      = attribute("status", F.enumFmt(OrganizationStatus), "Status of the organization", OrganizationStatus.Active)
}

@Singleton
class OrganizationModel @Inject()(
    findSrv: FindSrv,
    userModelProvider: Provider[UserModel],
    workerModelProvider: Provider[WorkerModel],
    implicit val ec: ExecutionContext
) extends ModelDef[OrganizationModel, Organization]("organization", "Organization", "/organization")
    with OrganizationAttributes
    with AuditedModel {

  private lazy val logger      = Logger(getClass)
  lazy val userModel           = userModelProvider.get
  lazy val workerModel         = workerModelProvider.get
  override def removeAttribute = Json.obj("status" → "Locked")

  override def creationHook(parent: Option[BaseEntity], attrs: JsObject): Future[JsObject] =
    Future.successful {
      (attrs \ "name").asOpt[JsString].fold(attrs) { orgName ⇒
        attrs - "name" + ("_id" → orgName)
      }
    }

  private def buildUserStats(organization: Organization): Future[JsObject] = {
    import org.elastic4play.services.QueryDSL._
    findSrv(userModel, "organization" ~= organization.id, groupByField("status", selectCount))
      .map { userStatsJson ⇒
        val (userCount, userStats) = userStatsJson.value.foldLeft((0L, JsObject.empty)) {
          case ((total, s), (key, value)) ⇒
            val count = (value \ "count").as[Long]
            (total + count, s + (key → JsNumber(count)))
        }
        Json.obj("users" → (userStats + ("total" → JsNumber(userCount))))
      }
  }

  private def buildWorkerStats(organization: Organization): Future[JsObject] = {
    import org.elastic4play.services.QueryDSL._
    findSrv(workerModel, withParent(organization), groupByField("status", selectCount))
      .map { workerStatsJson ⇒
        val (workerCount, workerStats) = workerStatsJson.value.foldLeft((0L, JsObject.empty)) {
          case ((total, s), (key, value)) ⇒
            val count = (value \ "count").as[Long]
            (total + count, s + (key → JsNumber(count)))
        }
        Json.obj("workers" → (workerStats + ("total" → JsNumber(workerCount))))
      }
  }

  override def getStats(entity: BaseEntity): Future[JsObject] =
    entity match {
      case organization: Organization ⇒
        for {
          userStats   ← buildUserStats(organization)
          workerStats ← buildWorkerStats(organization)
        } yield userStats ++ workerStats
      case other ⇒
        logger.warn(s"Request caseStats from a non-case entity ?! ${other.getClass}:$other")
        Future.successful(Json.obj())
    }

}

class Organization(model: OrganizationModel, attributes: JsObject)
    extends EntityDef[OrganizationModel, Organization](model, attributes)
    with OrganizationAttributes {
  override def toJson: JsObject = super.toJson + ("name" → JsString(id))
} 
Example 119
Source File: WorkerConfig.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.models

import javax.inject.{Inject, Singleton}

import play.api.libs.json.{JsObject, Json}

import org.elastic4play.models.{AttributeDef, ChildModelDef, EntityDef, AttributeFormat ⇒ F, AttributeOption ⇒ O}

import org.thp.cortex.models.JsonFormat.workerTypeFormat

trait WorkerConfigAttributes { _: AttributeDef ⇒
  val name   = attribute("name", F.stringFmt, "Worker name")
  val config = attribute("config", F.rawFmt, "Configuration of worker", O.sensitive)
  val tpe    = attribute("type", F.enumFmt(WorkerType), "", O.readonly)
}

@Singleton
class WorkerConfigModel @Inject()(organizationModel: OrganizationModel)
    extends ChildModelDef[WorkerConfigModel, WorkerConfig, OrganizationModel, Organization](
      organizationModel,
      "workerConfig",
      "WorkerConfig",
      "/worker/config"
    )
    with WorkerConfigAttributes {}

class WorkerConfig(model: WorkerConfigModel, attributes: JsObject)
    extends EntityDef[WorkerConfigModel, WorkerConfig](model, attributes)
    with WorkerConfigAttributes {
  def organization = parentId.get
  def jsonConfig   = Json.parse(config()).as[JsObject]
} 
Example 120
Source File: Job.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.models

import scala.util.Try

import play.api.libs.json.{JsObject, JsString, Json}

import javax.inject.{Inject, Singleton}
import org.thp.cortex.models.JsonFormat.workerTypeFormat

import org.elastic4play.models.JsonFormat.enumFormat
import org.elastic4play.models.{AttributeDef, EntityDef, HiveEnumeration, ModelDef, AttributeFormat ⇒ F, AttributeOption ⇒ O}

object JobStatus extends Enumeration with HiveEnumeration {
  type Type = Value
  val Waiting, InProgress, Success, Failure, Deleted = Value
  implicit val reads                                 = enumFormat(this)
}

trait JobAttributes {
  _: AttributeDef ⇒
  val workerDefinitionId = attribute("workerDefinitionId", F.stringFmt, "Worker definition id", O.readonly)
  val workerId           = attribute("workerId", F.stringFmt, "Worker id", O.readonly)
  val workerName         = attribute("workerName", F.stringFmt, "Worker name", O.readonly)
  val organization       = attribute("organization", F.stringFmt, "Organization ID", O.readonly)
  val status             = attribute("status", F.enumFmt(JobStatus), "Status of the job")
  val startDate          = optionalAttribute("startDate", F.dateFmt, "Analysis start date")
  val endDate            = optionalAttribute("endDate", F.dateFmt, "Analysis end date")
  val dataType           = attribute("dataType", F.stringFmt, "Type of the artifact", O.readonly)
  val data               = optionalAttribute("data", F.rawFmt, "Content of the artifact", O.readonly)
  val attachment         = optionalAttribute("attachment", F.attachmentFmt, "Artifact file content", O.readonly)
  val tlp                = attribute("tlp", TlpAttributeFormat, "TLP level", 2L)
  val pap                = attribute("pap", TlpAttributeFormat, "PAP level", 2L)
  val message            = optionalAttribute("message", F.textFmt, "Message associated to the analysis")
  val errorMessage       = optionalAttribute("errorMessage", F.textFmt, "Message returned by the worker when it fails")
  val parameters         = attribute("parameters", F.rawFmt, "Parameters for this job", "{}")
  val input              = optionalAttribute("input", F.rawFmt, "Data sent to worker")
  val fromCache          = optionalAttribute("fromCache", F.booleanFmt, "Indicates if cache is used", O.form)
  val tpe                = attribute("type", F.enumFmt(WorkerType), "", O.readonly)
  val lbel               = optionalAttribute("label", F.stringFmt, "Label of the job")
  val cacheTag           = optionalAttribute("cacheTag", F.stringFmt, "hash of job discriminant, used for cache", O.readonly)
}

@Singleton
class JobModel @Inject()() extends ModelDef[JobModel, Job]("job", "Job", "/job") with JobAttributes with AuditedModel {

  override val removeAttribute: JsObject = Json.obj("status" → JobStatus.Deleted)

  override def defaultSortBy: Seq[String] = Seq("-createdAt")
}

class Job(model: JobModel, attributes: JsObject) extends EntityDef[JobModel, Job](model, attributes) with JobAttributes {
  val params: JsObject = Try(Json.parse(parameters()).as[JsObject]).getOrElse(JsObject.empty)

  override def toJson: JsObject = {
    val output = input().fold(super.toJson)(
      i ⇒
        super.toJson +
          ("input" → Json.parse(i))
    ) +
      ("parameters"           → params) +
      ("analyzerId"           → JsString(workerId())) +
      ("analyzerName"         → JsString(workerName())) +
      ("analyzerDefinitionId" → JsString(workerDefinitionId())) +
      ("date"                 → Json.toJson(createdAt))
    data() match {
      case Some(d) if tpe() == WorkerType.responder ⇒ output + ("data" → Json.parse(d))
      case _                                        ⇒ output
    }
  }
} 
Example 121
Source File: AuditSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import javax.inject.{Inject, Singleton}

import scala.concurrent.ExecutionContext
import scala.concurrent.duration.FiniteDuration

import play.api.Logger

import akka.actor.{Actor, ActorRef}
import org.thp.cortex.models.JobStatus

import org.elastic4play.models.BaseEntity
import org.elastic4play.services._

object AuditActor {
  case class Register(jobId: String, timeout: FiniteDuration)
  case class Unregister(jobId: String, actorRef: ActorRef)
  case class JobEnded(jobId: String, status: JobStatus.Type)
}

@Singleton
class AuditActor @Inject()(eventSrv: EventSrv, implicit val ec: ExecutionContext) extends Actor {

  import AuditActor._

  object EntityExtractor {
    def unapply(e: BaseEntity) = Some((e.model, e.id, e.routing))
  }
  var registration                    = Map.empty[String, Seq[ActorRef]]
  private[AuditActor] lazy val logger = Logger(getClass)

  override def preStart(): Unit = {
    eventSrv.subscribe(self, classOf[EventMessage])
    super.preStart()
  }

  override def postStop(): Unit = {
    eventSrv.unsubscribe(self)
    super.postStop()
  }

  override def receive: Receive = {
    case Register(jobId, timeout) ⇒
      logger.info(s"Register new listener for job $jobId ($sender)")
      val newActorList = registration.getOrElse(jobId, Nil) :+ sender
      registration += (jobId → newActorList)
      context.system.scheduler.scheduleOnce(timeout, self, Unregister(jobId, sender))

    case Unregister(jobId, actorRef) ⇒
      logger.info(s"Unregister listener for job $jobId ($actorRef)")
      val newActorList = registration.getOrElse(jobId, Nil).filterNot(_ == actorRef)
      registration += (jobId → newActorList)

    case AuditOperation(EntityExtractor(model, id, routing), action, details, authContext, date) ⇒
      if (model.modelName == "job" && action == AuditableAction.Update) {
        logger.info(s"Job $id has be updated (${details \ "status"})")
        val status = (details \ "status").asOpt[JobStatus.Type].getOrElse(JobStatus.InProgress)
        if (status != JobStatus.InProgress) registration.getOrElse(id, Nil).foreach { aref ⇒
          aref ! JobEnded(id, status)
        }
      }
  }
} 
Example 122
Source File: CSRFFilter.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import javax.inject.{Inject, Provider, Singleton}

import play.api.Logger
import play.api.http.SessionConfiguration
import play.api.libs.crypto.CSRFTokenSigner
import play.filters.csrf.{CSRFFilter ⇒ PCSRFFilter}
import play.api.mvc.RequestHeader
import play.filters.csrf.CSRF.{ErrorHandler ⇒ CSRFErrorHandler, TokenProvider}
import play.filters.csrf.CSRFConfig

import akka.stream.Materializer

object CSRFFilter {
  private[CSRFFilter] lazy val logger = Logger(getClass)

  def shouldProtect(request: RequestHeader): Boolean = {
    val isLogin     = request.uri.startsWith("/api/login")
    val isApi       = request.uri.startsWith("/api")
    val isInSession = request.session.data.nonEmpty
    val check       = !isLogin && isApi && isInSession
    logger.debug(s"[csrf] uri ${request.uri} (isLogin=$isLogin, isApi=$isApi, isInSession=$isInSession): ${if (check) "" else "don't"} check")
    check
  }

}

@Singleton
class CSRFFilter @Inject()(
    config: Provider[CSRFConfig],
    tokenSignerProvider: Provider[CSRFTokenSigner],
    sessionConfiguration: SessionConfiguration,
    tokenProvider: TokenProvider,
    errorHandler: CSRFErrorHandler
)(mat: Materializer)
    extends PCSRFFilter(
      config.get.copy(shouldProtect = CSRFFilter.shouldProtect),
      tokenSignerProvider.get,
      sessionConfiguration,
      tokenProvider,
      errorHandler
    )(mat) 
Example 123
Source File: OrganizationSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import javax.inject.{Inject, Singleton}

import scala.concurrent.Future
import scala.concurrent.duration.Duration

import play.api.Configuration
import play.api.cache.AsyncCacheApi
import play.api.libs.json.JsObject

import akka.NotUsed
import akka.stream.scaladsl.Source
import org.thp.cortex.models.{Organization, OrganizationModel}

import org.elastic4play.controllers.Fields
import org.elastic4play.database.ModifyConfig
import org.elastic4play.services._

@Singleton
class OrganizationSrv(
    cacheExpiration: Duration,
    organizationModel: OrganizationModel,
    getSrv: GetSrv,
    updateSrv: UpdateSrv,
    findSrv: FindSrv,
    deleteSrv: DeleteSrv,
    createSrv: CreateSrv,
    cache: AsyncCacheApi
) {

  @Inject() def this(
      config: Configuration,
      organizationModel: OrganizationModel,
      getSrv: GetSrv,
      updateSrv: UpdateSrv,
      findSrv: FindSrv,
      deleteSrv: DeleteSrv,
      createSrv: CreateSrv,
      cache: AsyncCacheApi
  ) = this(config.get[Duration]("cache.organization"), organizationModel, getSrv, updateSrv, findSrv, deleteSrv, createSrv, cache)

  def create(fields: Fields)(implicit authContext: AuthContext): Future[Organization] =
    createSrv[OrganizationModel, Organization](organizationModel, fields)

  def get(orgId: String): Future[Organization] = cache.getOrElseUpdate(s"org-$orgId", cacheExpiration) {
    getSrv[OrganizationModel, Organization](organizationModel, orgId)
  }

  def update(orgId: String, fields: Fields)(implicit Context: AuthContext): Future[Organization] =
    update(orgId, fields, ModifyConfig.default)

  def update(orgId: String, fields: Fields, modifyConfig: ModifyConfig)(implicit Context: AuthContext): Future[Organization] = {
    cache.remove(s"org-$orgId")
    updateSrv[OrganizationModel, Organization](organizationModel, orgId, fields, modifyConfig)
  }

  def update(organization: Organization, fields: Fields)(implicit Context: AuthContext): Future[Organization] =
    update(organization, fields, ModifyConfig.default)

  def update(organization: Organization, fields: Fields, modifyConfig: ModifyConfig)(implicit Context: AuthContext): Future[Organization] = {
    cache.remove(s"org-${organization.id}")
    updateSrv(organization, fields, modifyConfig)
  }

  def delete(orgId: String)(implicit Context: AuthContext): Future[Organization] = {
    cache.remove(s"org-$orgId")
    deleteSrv[OrganizationModel, Organization](organizationModel, orgId)
  }

  def find(queryDef: QueryDef, range: Option[String], sortBy: Seq[String]): (Source[Organization, NotUsed], Future[Long]) =
    findSrv[OrganizationModel, Organization](organizationModel, queryDef, range, sortBy)

  def stats(queryDef: QueryDef, aggs: Seq[Agg]): Future[JsObject] = findSrv(organizationModel, queryDef, aggs: _*)
} 
Example 124
Source File: AnalyzerConfigSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import scala.concurrent.{ExecutionContext, Future}

import play.api.Configuration

import akka.stream.Materializer
import javax.inject.{Inject, Singleton}
import org.thp.cortex.models.{BaseConfig, WorkerConfigModel, WorkerType}

import org.elastic4play.services.{CreateSrv, FindSrv, UpdateSrv}

@Singleton
class AnalyzerConfigSrv @Inject()(
    val configuration: Configuration,
    val workerConfigModel: WorkerConfigModel,
    val userSrv: UserSrv,
    val organizationSrv: OrganizationSrv,
    val workerSrv: WorkerSrv,
    val createSrv: CreateSrv,
    val updateSrv: UpdateSrv,
    val findSrv: FindSrv,
    implicit val ec: ExecutionContext,
    implicit val mat: Materializer
) extends WorkerConfigSrv {

  override val workerType: WorkerType.Type = WorkerType.analyzer

  def definitions: Future[Map[String, BaseConfig]] =
    buildDefinitionMap(workerSrv.listAnalyzerDefinitions._1)
} 
Example 125
Source File: CortexAuthSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import javax.inject.{Inject, Singleton}

import scala.collection.immutable
import scala.concurrent.ExecutionContext

import play.api.{Configuration, Logger}

import org.elastic4play.services.AuthSrv
import org.elastic4play.services.auth.MultiAuthSrv

object CortexAuthSrv {
  private[CortexAuthSrv] lazy val logger = Logger(getClass)

  def getAuthSrv(authTypes: Seq[String], authModules: immutable.Set[AuthSrv]): Seq[AuthSrv] =
    ("key" +: authTypes.filterNot(_ == "key"))
      .flatMap { authType ⇒
        authModules
          .find(_.name == authType)
          .orElse {
            logger.error(s"Authentication module $authType not found")
            None
          }
      }
}

@Singleton
class CortexAuthSrv @Inject()(
    configuration: Configuration,
    authModules: immutable.Set[AuthSrv],
    userSrv: UserSrv,
    implicit override val ec: ExecutionContext
) extends MultiAuthSrv(
      CortexAuthSrv.getAuthSrv(configuration.getDeprecated[Option[Seq[String]]]("auth.provider", "auth.type").getOrElse(Seq("local")), authModules),
      ec
    ) {

  // Uncomment the following lines if you want to prevent user with key to use password to authenticate
  //  override def authenticate(username: String, password: String)(implicit request: RequestHeader): Future[AuthContext] =
  //    userSrv.get(username)
  //      .transformWith {
  //        case Success(user) if user.key().isDefined ⇒ Future.failed(AuthenticationError("Authentication by password is not permitted for user with key"))
  //        case _: Success[_]                         ⇒ super.authenticate(username, password)
  //        case _: Failure[_]                         ⇒ Future.failed(AuthenticationError("Authentication failure"))
  //      }
} 
Example 126
Source File: ProcessJobRunnerSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Path, Paths}

import akka.actor.ActorSystem
import javax.inject.{Inject, Singleton}
import org.elastic4play.utils.RichFuture
import org.thp.cortex.models._
import play.api.Logger
import play.api.libs.json.Json

import scala.concurrent.duration.FiniteDuration
import scala.concurrent.{ExecutionContext, Future}
import scala.sys.process.{Process, ProcessLogger, _}
import scala.util.Try

@Singleton
class ProcessJobRunnerSrv @Inject()(implicit val system: ActorSystem) {

  lazy val logger = Logger(getClass)

  private val pythonPackageVersionRegex = "^Version: ([0-9]*)\\.([0-9]*)\\.([0-9]*)".r

  def checkCortexUtilsVersion(pythonVersion: String): Option[(Int, Int, Int)] =
    Try {
      (s"pip$pythonVersion" :: "show" :: "cortexutils" :: Nil)
        .lineStream
        .collectFirst {
          case pythonPackageVersionRegex(major, minor, patch) ⇒ (major.toInt, minor.toInt, patch.toInt)
        }
    }.getOrElse(None)

  def run(jobDirectory: Path, command: String, job: Job, timeout: Option[FiniteDuration])(implicit ec: ExecutionContext): Future[Unit] = {
    val baseDirectory = Paths.get(command).getParent.getParent
    val output        = StringBuilder.newBuilder
    logger.info(s"Execute $command in $baseDirectory, timeout is ${timeout.fold("none")(_.toString)}")
    val process = Process(Seq(command, jobDirectory.toString), baseDirectory.toFile)
      .run(ProcessLogger { s ⇒
        logger.info(s"  Job ${job.id}: $s")
        output ++= s
      })
    val execution = Future
      .apply {
        process.exitValue()
        ()
      }
      .map { _ ⇒
        val outputFile = jobDirectory.resolve("output").resolve("output.json")
        if (!Files.exists(outputFile) || Files.size(outputFile) == 0) {
          val report = Json.obj("success" → false, "errorMessage" → output.toString)
          Files.write(outputFile, report.toString.getBytes(StandardCharsets.UTF_8))
        }
        ()
      }
      .recoverWith {
        case error ⇒
          logger.error(s"Execution of command $command failed", error)
          Future.apply {
            val report = Json.obj("success" → false, "errorMessage" → s"${error.getMessage}\n$output")
            Files.write(jobDirectory.resolve("output").resolve("output.json"), report.toString.getBytes(StandardCharsets.UTF_8))
            ()
          }
      }
    timeout.fold(execution)(t ⇒ execution.withTimeout(t, killProcess(process)))
  }

  def killProcess(process: Process): Unit = {
    logger.info("Timeout reached, killing process")
    process.destroy()
  }
} 
Example 127
Source File: LocalAuthSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import javax.inject.{Inject, Singleton}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Random

import play.api.mvc.RequestHeader

import akka.stream.Materializer
import org.thp.cortex.models.User

import org.elastic4play.controllers.Fields
import org.elastic4play.services.{AuthCapability, AuthContext, AuthSrv}
import org.elastic4play.utils.Hasher
import org.elastic4play.{AuthenticationError, AuthorizationError}

@Singleton
class LocalAuthSrv @Inject()(userSrv: UserSrv, implicit val ec: ExecutionContext, implicit val mat: Materializer) extends AuthSrv {

  val name                  = "local"
  override val capabilities = Set(AuthCapability.changePassword, AuthCapability.setPassword)

  private[services] def doAuthenticate(user: User, password: String): Boolean =
    user.password().map(_.split(",", 2)).fold(false) {
      case Array(seed, pwd) ⇒
        val hash = Hasher("SHA-256").fromString(seed + password).head.toString
        hash == pwd
      case _ ⇒ false
    }

  override def authenticate(username: String, password: String)(implicit request: RequestHeader): Future[AuthContext] =
    userSrv.get(username).flatMap { user ⇒
      if (doAuthenticate(user, password)) userSrv.getFromUser(request, user, name)
      else Future.failed(AuthenticationError("Authentication failure"))
    }

  override def changePassword(username: String, oldPassword: String, newPassword: String)(implicit authContext: AuthContext): Future[Unit] =
    userSrv.get(username).flatMap { user ⇒
      if (doAuthenticate(user, oldPassword)) setPassword(username, newPassword)
      else Future.failed(AuthorizationError("Authentication failure"))
    }

  override def setPassword(username: String, newPassword: String)(implicit authContext: AuthContext): Future[Unit] = {
    val seed    = Random.nextString(10).replace(',', '!')
    val newHash = seed + "," + Hasher("SHA-256").fromString(seed + newPassword).head.toString
    userSrv.update(username, Fields.empty.set("password", newHash)).map(_ ⇒ ())
  }
} 
Example 128
Source File: KeyAuthSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import java.util.Base64
import javax.inject.{Inject, Singleton}

import scala.concurrent.{ExecutionContext, Future}
import scala.util.Random

import play.api.libs.json.JsArray
import play.api.mvc.RequestHeader

import akka.stream.Materializer
import akka.stream.scaladsl.Sink

import org.elastic4play.controllers.Fields
import org.elastic4play.services.{AuthCapability, AuthContext, AuthSrv}
import org.elastic4play.{AuthenticationError, BadRequestError}

@Singleton
class KeyAuthSrv @Inject()(userSrv: UserSrv, implicit val ec: ExecutionContext, implicit val mat: Materializer) extends AuthSrv {
  override val name = "key"

  final protected def generateKey(): String = {
    val bytes = Array.ofDim[Byte](24)
    Random.nextBytes(bytes)
    Base64.getEncoder.encodeToString(bytes)
  }

  override val capabilities = Set(AuthCapability.authByKey)

  override def authenticate(key: String)(implicit request: RequestHeader): Future[AuthContext] = {
    import org.elastic4play.services.QueryDSL._
    // key attribute is sensitive so it is not possible to search on that field
    userSrv
      .find("status" ~= "Ok", Some("all"), Nil)
      ._1
      .filter(_.key().contains(key))
      .runWith(Sink.headOption)
      .flatMap {
        case Some(user) ⇒ userSrv.getFromUser(request, user, name)
        case None       ⇒ Future.failed(AuthenticationError("Authentication failure"))
      }
  }

  override def renewKey(username: String)(implicit authContext: AuthContext): Future[String] = {
    val newKey = generateKey()
    userSrv.update(username, Fields.empty.set("key", newKey)).map(_ ⇒ newKey)
  }

  override def getKey(username: String)(implicit authContext: AuthContext): Future[String] =
    userSrv.get(username).map(_.key().getOrElse(throw BadRequestError(s"User $username hasn't key")))

  override def removeKey(username: String)(implicit authContext: AuthContext): Future[Unit] =
    userSrv.update(username, Fields.empty.set("key", JsArray())).map(_ ⇒ ())
} 
Example 129
Source File: ResponderConfigSrv.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.services

import scala.concurrent.{ExecutionContext, Future}

import play.api.Configuration

import akka.stream.Materializer
import javax.inject.{Inject, Singleton}
import org.thp.cortex.models.{BaseConfig, WorkerConfigModel, WorkerType}

import org.elastic4play.services.{CreateSrv, FindSrv, UpdateSrv}

@Singleton
class ResponderConfigSrv @Inject()(
    val configuration: Configuration,
    val workerConfigModel: WorkerConfigModel,
    val userSrv: UserSrv,
    val organizationSrv: OrganizationSrv,
    val workerSrv: WorkerSrv,
    val createSrv: CreateSrv,
    val updateSrv: UpdateSrv,
    val findSrv: FindSrv,
    implicit val ec: ExecutionContext,
    implicit val mat: Materializer
) extends WorkerConfigSrv {

  override val workerType: WorkerType.Type         = WorkerType.responder
  def definitions: Future[Map[String, BaseConfig]] = buildDefinitionMap(workerSrv.listResponderDefinitions._1)
} 
Example 130
Source File: StatusCtrl.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.controllers

import scala.concurrent.ExecutionContext

import play.api.Configuration
import play.api.http.Status
import play.api.libs.json.Json.toJsFieldJsValueWrapper
import play.api.libs.json.{JsBoolean, JsString, Json}
import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponents}

import com.sksamuel.elastic4s.http.ElasticDsl
import javax.inject.{Inject, Singleton}
import org.elasticsearch.client.Node
import org.thp.cortex.models.Worker

import org.elastic4play.database.DBIndex
import org.elastic4play.services.AuthSrv
import org.elastic4play.services.auth.MultiAuthSrv

@Singleton
class StatusCtrl @Inject()(
    configuration: Configuration,
    authSrv: AuthSrv,
    dbIndex: DBIndex,
    components: ControllerComponents,
    implicit val ec: ExecutionContext
) extends AbstractController(components)
    with Status {

  private[controllers] def getVersion(c: Class[_]) = Option(c.getPackage.getImplementationVersion).getOrElse("SNAPSHOT")

  def get: Action[AnyContent] = Action {
    Ok(
      Json.obj(
        "versions" → Json.obj(
          "Cortex"               → getVersion(classOf[Worker]),
          "Elastic4Play"         → getVersion(classOf[AuthSrv]),
          "Play"                 → getVersion(classOf[AbstractController]),
          "Elastic4s"            → getVersion(classOf[ElasticDsl]),
          "ElasticSearch client" → getVersion(classOf[Node])
        ),
        "config" → Json.obj(
          "protectDownloadsWith" → configuration.get[String]("datastore.attachment.password"),
          "authType" → (authSrv match {
            case multiAuthSrv: MultiAuthSrv ⇒
              multiAuthSrv.authProviders.map { a ⇒
                JsString(a.name)
              }
            case _ ⇒ JsString(authSrv.name)
          }),
          "capabilities" → authSrv.capabilities.map(c ⇒ JsString(c.toString)),
          "ssoAutoLogin" → JsBoolean(configuration.getOptional[Boolean]("auth.sso.autologin").getOrElse(false))
        )
      )
    )
  }

  def health: Action[AnyContent] = TODO
} 
Example 131
Source File: AnalyzerConfigCtrl.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.controllers

import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

import play.api.libs.json.JsObject
import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponents}

import org.thp.cortex.models.{BaseConfig, Roles}
import org.thp.cortex.services.{AnalyzerConfigSrv, UserSrv}

import org.elastic4play.BadRequestError
import org.elastic4play.controllers.{Authenticated, Fields, FieldsBodyParser, Renderer}

@Singleton
class AnalyzerConfigCtrl @Inject()(
    analyzerConfigSrv: AnalyzerConfigSrv,
    userSrv: UserSrv,
    authenticated: Authenticated,
    fieldsBodyParser: FieldsBodyParser,
    renderer: Renderer,
    components: ControllerComponents,
    implicit val ec: ExecutionContext
) extends AbstractController(components) {

  def get(analyzerConfigName: String): Action[AnyContent] = authenticated(Roles.orgAdmin).async { request ⇒
    analyzerConfigSrv
      .getForUser(request.userId, analyzerConfigName)
      .map(renderer.toOutput(OK, _))
  }

  def list(): Action[AnyContent] = authenticated(Roles.orgAdmin).async { request ⇒
    analyzerConfigSrv
      .listConfigForUser(request.userId)
      .map { bc ⇒
        renderer.toOutput(
          OK,
          bc.sortWith {
            case (BaseConfig("global", _, _, _), _)               ⇒ true
            case (_, BaseConfig("global", _, _, _))               ⇒ false
            case (BaseConfig(a, _, _, _), BaseConfig(b, _, _, _)) ⇒ a.compareTo(b) < 0
          }
        )
      }
  }

  def update(analyzerConfigName: String): Action[Fields] = authenticated(Roles.orgAdmin).async(fieldsBodyParser) { implicit request ⇒
    request.body.getValue("config").flatMap(_.asOpt[JsObject]) match {
      case Some(config) ⇒
        analyzerConfigSrv
          .updateOrCreate(request.userId, analyzerConfigName, config)
          .map(renderer.toOutput(OK, _))
      case None ⇒ Future.failed(BadRequestError("attribute config has invalid format"))
    }
  }
} 
Example 132
Source File: AnalyzerCtrl.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.controllers

import scala.concurrent.{ExecutionContext, Future}

import play.api.libs.json.{JsObject, JsString, Json}
import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponents}

import akka.stream.Materializer
import javax.inject.{Inject, Singleton}
import org.thp.cortex.models.{Roles, Worker}
import org.thp.cortex.services.{UserSrv, WorkerSrv}

import org.elastic4play.controllers.{Authenticated, Fields, FieldsBodyParser, Renderer}
import org.elastic4play.services.JsonFormat.queryReads
import org.elastic4play.services.{QueryDSL, QueryDef}

@Singleton
class AnalyzerCtrl @Inject()(
    workerSrv: WorkerSrv,
    userSrv: UserSrv,
    authenticated: Authenticated,
    fieldsBodyParser: FieldsBodyParser,
    renderer: Renderer,
    components: ControllerComponents,
    implicit val ec: ExecutionContext,
    implicit val mat: Materializer
) extends AbstractController(components) {

  def find: Action[Fields] = authenticated(Roles.read).async(fieldsBodyParser) { request ⇒
    val query                      = request.body.getValue("query").fold[QueryDef](QueryDSL.any)(_.as[QueryDef])
    val range                      = request.body.getString("range")
    val sort                       = request.body.getStrings("sort").getOrElse(Nil)
    val isAdmin                    = request.roles.contains(Roles.orgAdmin)
    val (analyzers, analyzerTotal) = workerSrv.findAnalyzersForUser(request.userId, query, range, sort)
    renderer.toOutput(OK, analyzers.map(analyzerJson(isAdmin)), analyzerTotal)
  }

  def get(analyzerId: String): Action[AnyContent] = authenticated(Roles.read).async { request ⇒
    val isAdmin = request.roles.contains(Roles.orgAdmin)
    workerSrv
      .getForUser(request.userId, analyzerId)
      .map(a ⇒ renderer.toOutput(OK, analyzerJson(isAdmin)(a)))
  }

  private def analyzerJson(isAdmin: Boolean)(analyzer: Worker): JsObject =
    if (isAdmin)
      analyzer.toJson + ("configuration" → Json.parse(analyzer.configuration())) + ("analyzerDefinitionId" → JsString(analyzer.workerDefinitionId()))
    else
      analyzer.toJson + ("analyzerDefinitionId" → JsString(analyzer.workerDefinitionId()))

  def listForType(dataType: String): Action[AnyContent] = authenticated(Roles.read).async { request ⇒
    import org.elastic4play.services.QueryDSL._
    val (responderList, responderCount) = workerSrv.findAnalyzersForUser(request.userId, "dataTypeList" ~= dataType, Some("all"), Nil)
    renderer.toOutput(OK, responderList.map(analyzerJson(isAdmin = false)), responderCount)
  }

  def create(analyzerDefinitionId: String): Action[Fields] = authenticated(Roles.orgAdmin).async(fieldsBodyParser) { implicit request ⇒
    for {
      organizationId   ← userSrv.getOrganizationId(request.userId)
      workerDefinition ← Future.fromTry(workerSrv.getDefinition(analyzerDefinitionId))
      analyzer         ← workerSrv.create(organizationId, workerDefinition, request.body)
    } yield renderer.toOutput(CREATED, analyzerJson(isAdmin = false)(analyzer))
  }

  def listDefinitions: Action[AnyContent] = authenticated(Roles.orgAdmin, Roles.superAdmin).async { _ ⇒
    val (analyzers, analyzerTotal) = workerSrv.listAnalyzerDefinitions
    renderer.toOutput(OK, analyzers, analyzerTotal)
  }

  def scan: Action[AnyContent] = authenticated(Roles.orgAdmin, Roles.superAdmin) { _ ⇒
    workerSrv.rescan()
    NoContent
  }

  def delete(analyzerId: String): Action[AnyContent] = authenticated(Roles.orgAdmin, Roles.superAdmin).async { implicit request ⇒
    for {
      analyzer ← workerSrv.getForUser(request.userId, analyzerId)
      _        ← workerSrv.delete(analyzer)
    } yield NoContent
  }

  def update(analyzerId: String): Action[Fields] = authenticated(Roles.orgAdmin).async(fieldsBodyParser) { implicit request ⇒
    for {
      analyzer        ← workerSrv.getForUser(request.userId, analyzerId)
      updatedAnalyzer ← workerSrv.update(analyzer, request.body)
    } yield renderer.toOutput(OK, analyzerJson(isAdmin = true)(updatedAnalyzer))
  }
} 
Example 133
Source File: AssetCtrl.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.controllers

import javax.inject.{Inject, Singleton}
import play.api.http.{FileMimeTypes, HttpErrorHandler}
import play.api.mvc.{Action, AnyContent}
import controllers.{Assets, AssetsMetadata, ExternalAssets}
import play.api.Environment

import scala.concurrent.ExecutionContext

trait AssetCtrl {
  def get(file: String): Action[AnyContent]
}

@Singleton
class AssetCtrlProd @Inject()(errorHandler: HttpErrorHandler, meta: AssetsMetadata) extends Assets(errorHandler, meta) with AssetCtrl {
  def get(file: String): Action[AnyContent] = at("/www", file)
}

@Singleton
class AssetCtrlDev @Inject()(environment: Environment)(implicit ec: ExecutionContext, fileMimeTypes: FileMimeTypes)
    extends ExternalAssets(environment)
    with AssetCtrl {
  def get(file: String): Action[AnyContent] = at("www/dist", file)
} 
Example 134
Source File: DBListCtrl.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.controllers

import javax.inject.{Inject, Singleton}

import scala.concurrent.{ExecutionContext, Future}

import play.api.libs.json.{JsValue, Json}
import play.api.mvc._

import org.thp.cortex.models.Roles

import org.elastic4play.controllers.{Authenticated, Fields, FieldsBodyParser, Renderer}
import org.elastic4play.services.DBLists
import org.elastic4play.MissingAttributeError

@Singleton
class DBListCtrl @Inject()(
    dblists: DBLists,
    authenticated: Authenticated,
    renderer: Renderer,
    components: ControllerComponents,
    fieldsBodyParser: FieldsBodyParser,
    implicit val ec: ExecutionContext
) extends AbstractController(components) {

  def list: Action[AnyContent] = authenticated(Roles.read).async { _ ⇒
    dblists.listAll.map { listNames ⇒
      renderer.toOutput(OK, listNames)
    }
  }

  def listItems(listName: String): Action[AnyContent] = authenticated(Roles.read) { _ ⇒
    val (src, _) = dblists(listName).getItems[JsValue]
    val items = src
      .map { case (id, value) ⇒ s""""$id":$value""" }
      .intersperse("{", ",", "}")
    Ok.chunked(items).as("application/json")
  }

  def addItem(listName: String): Action[Fields] = authenticated(Roles.superAdmin).async(fieldsBodyParser) { implicit request ⇒
    request.body.getValue("value").fold(Future.successful(NoContent)) { value ⇒
      dblists(listName).addItem(value).map { item ⇒
        renderer.toOutput(OK, item.id)
      }
    }
  }

  def deleteItem(itemId: String): Action[AnyContent] = authenticated(Roles.superAdmin).async { implicit request ⇒
    dblists.deleteItem(itemId).map { _ ⇒
      NoContent
    }
  }

  def updateItem(itemId: String): Action[Fields] = authenticated(Roles.superAdmin).async(fieldsBodyParser) { implicit request ⇒
    request
      .body
      .getValue("value")
      .map { value ⇒
        for {
          item    ← dblists.getItem(itemId)
          _       ← dblists.deleteItem(item)
          newItem ← dblists(item.dblist).addItem(value)
        } yield renderer.toOutput(OK, newItem.id)
      }
      .getOrElse(Future.failed(MissingAttributeError("value")))
  }

  def itemExists(listName: String): Action[Fields] = authenticated(Roles.read).async(fieldsBodyParser) { implicit request ⇒
    val itemKey   = request.body.getString("key").getOrElse(throw MissingAttributeError("Parameter key is missing"))
    val itemValue = request.body.getValue("value").getOrElse(throw MissingAttributeError("Parameter value is missing"))
    dblists(listName).exists(itemKey, itemValue).map(r ⇒ Ok(Json.obj("found" → r)))
  }
} 
Example 135
Source File: AuthenticationCtrl.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.controllers

import scala.concurrent.{ExecutionContext, Future}

import play.api.mvc._

import javax.inject.{Inject, Singleton}
import org.thp.cortex.models.UserStatus
import org.thp.cortex.services.UserSrv

import org.elastic4play.controllers.{Authenticated, Fields, FieldsBodyParser, Renderer}
import org.elastic4play.database.DBIndex
import org.elastic4play.services.AuthSrv
import org.elastic4play.services.JsonFormat.authContextWrites
import org.elastic4play.{AuthorizationError, MissingAttributeError, OAuth2Redirect, Timed}

@Singleton
class AuthenticationCtrl @Inject()(
    authSrv: AuthSrv,
    userSrv: UserSrv,
    authenticated: Authenticated,
    dbIndex: DBIndex,
    renderer: Renderer,
    components: ControllerComponents,
    fieldsBodyParser: FieldsBodyParser,
    implicit val ec: ExecutionContext
) extends AbstractController(components) {

  @Timed
  def login: Action[Fields] = Action.async(fieldsBodyParser) { implicit request ⇒
    dbIndex.getIndexStatus.flatMap {
      case false ⇒ Future.successful(Results.Status(520))
      case _ ⇒
        for {
          user        ← request.body.getString("user").fold[Future[String]](Future.failed(MissingAttributeError("user")))(Future.successful)
          password    ← request.body.getString("password").fold[Future[String]](Future.failed(MissingAttributeError("password")))(Future.successful)
          authContext ← authSrv.authenticate(user, password)
        } yield authenticated.setSessingUser(renderer.toOutput(OK, authContext), authContext)
    }
  }

  @Timed
  def ssoLogin: Action[AnyContent] = Action.async { implicit request ⇒
    dbIndex.getIndexStatus.flatMap {
      case false ⇒ Future.successful(Results.Status(520))
      case _ ⇒
        (for {
          authContext ← authSrv.authenticate()
          user        ← userSrv.get(authContext.userId)
        } yield {
          if (user.status() == UserStatus.Ok)
            authenticated.setSessingUser(Ok, authContext)
          else
            throw AuthorizationError("Your account is locked")
        }) recover {
          // A bit of a hack with the status code, so that Angular doesn't reject the origin
          case OAuth2Redirect(redirectUrl, qp) ⇒ Redirect(redirectUrl, qp, status = OK)
          case e                               ⇒ throw e
        }
    }
  }

  @Timed
  def logout = Action {
    Ok.withNewSession
  }
} 
Example 136
Source File: AttachmentCtrl.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.controllers

import java.net.URLEncoder
import java.nio.file.Files
import javax.inject.{Inject, Singleton}

import play.api.http.HttpEntity
import play.api.libs.Files.DefaultTemporaryFileCreator
import play.api.mvc._
import play.api.{mvc, Configuration}

import akka.stream.scaladsl.FileIO
import net.lingala.zip4j.core.ZipFile
import net.lingala.zip4j.model.ZipParameters
import net.lingala.zip4j.util.Zip4jConstants
import org.thp.cortex.models.Roles

import org.elastic4play.Timed
import org.elastic4play.controllers.{Authenticated, Renderer}
import org.elastic4play.models.AttachmentAttributeFormat
import org.elastic4play.services.AttachmentSrv


  @Timed("controllers.AttachmentCtrl.downloadZip")
  def downloadZip(hash: String, name: Option[String]): Action[AnyContent] = authenticated(Roles.read) { _ ⇒
    if (!name.getOrElse("").intersect(AttachmentAttributeFormat.forbiddenChar).isEmpty)
      BadRequest("File name is invalid")
    else {
      val f = tempFileCreator.create("zip", hash).path
      Files.delete(f)
      val zipFile   = new ZipFile(f.toFile)
      val zipParams = new ZipParameters
      zipParams.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_FASTEST)
      zipParams.setEncryptFiles(true)
      zipParams.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD)
      zipParams.setPassword(password)
      zipParams.setFileNameInZip(name.getOrElse(hash))
      zipParams.setSourceExternalStream(true)
      zipFile.addStream(attachmentSrv.stream(hash), zipParams)

      Result(
        header = ResponseHeader(
          200,
          Map(
            "Content-Disposition"       → s"""attachment; filename="${URLEncoder.encode(name.getOrElse(hash), "utf-8")}.zip"""",
            "Content-Type"              → "application/zip",
            "Content-Transfer-Encoding" → "binary",
            "Content-Length"            → Files.size(f).toString
          )
        ),
        body = HttpEntity.Streamed(FileIO.fromPath(f), Some(Files.size(f)), Some("application/zip"))
      )
    }
  }
} 
Example 137
Source File: OrganizationCtrl.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.controllers

import javax.inject.{Inject, Singleton}

import scala.concurrent.{ExecutionContext, Future}

import play.api.Logger
import play.api.http.Status
import play.api.mvc._

import org.thp.cortex.models.Roles
import org.thp.cortex.services.{OrganizationSrv, UserSrv}

import org.elastic4play.{BadRequestError, NotFoundError}
import org.elastic4play.controllers.{Authenticated, Fields, FieldsBodyParser, Renderer}
import org.elastic4play.models.JsonFormat.baseModelEntityWrites
import org.elastic4play.services.JsonFormat.{aggReads, queryReads}
import org.elastic4play.services.{UserSrv ⇒ _, _}

@Singleton
class OrganizationCtrl @Inject()(
    organizationSrv: OrganizationSrv,
    authSrv: AuthSrv,
    auxSrv: AuxSrv,
    userSrv: UserSrv,
    authenticated: Authenticated,
    renderer: Renderer,
    fieldsBodyParser: FieldsBodyParser,
    components: ControllerComponents,
    implicit val ec: ExecutionContext
) extends AbstractController(components)
    with Status {

  private[OrganizationCtrl] lazy val logger = Logger(getClass)

  def create: Action[Fields] = authenticated(Roles.superAdmin).async(fieldsBodyParser) { implicit request ⇒
    organizationSrv
      .create(request.body)
      .map(organization ⇒ renderer.toOutput(CREATED, organization))
  }

  def get(organizationId: String): Action[Fields] = authenticated(Roles.superAdmin, Roles.orgAdmin).async(fieldsBodyParser) { implicit request ⇒
    val withStats = request.body.getBoolean("nstats").getOrElse(false)
    (for {
      userOrganizationId ← if (request.roles.contains(Roles.superAdmin)) Future.successful(organizationId)
      else userSrv.getOrganizationId(request.userId)
      if userOrganizationId == organizationId
      organization          ← organizationSrv.get(organizationId)
      organizationWithStats ← auxSrv(organization, 0, withStats, removeUnaudited = false)
    } yield renderer.toOutput(OK, organizationWithStats))
      .recoverWith { case _: NoSuchElementException ⇒ Future.failed(NotFoundError(s"organization $organizationId not found")) }
  }

  def update(organizationId: String): Action[Fields] = authenticated(Roles.superAdmin).async(fieldsBodyParser) { implicit request ⇒
    if (organizationId == "cortex")
      Future.failed(BadRequestError("Cortex organization can't be updated"))
    else
      organizationSrv.update(organizationId, request.body).map { organization ⇒
        renderer.toOutput(OK, organization)
      }
  }

  def delete(organizationId: String): Action[AnyContent] = authenticated(Roles.superAdmin).async { implicit request ⇒
    if (organizationId == "cortex")
      Future.failed(BadRequestError("Cortex organization can't be removed"))
    else
      organizationSrv
        .delete(organizationId)
        .map(_ ⇒ NoContent)
  }

  def find: Action[Fields] = authenticated(Roles.superAdmin).async(fieldsBodyParser) { implicit request ⇒
    val query                  = request.body.getValue("query").fold[QueryDef](QueryDSL.any)(_.as[QueryDef])
    val range                  = request.body.getString("range")
    val sort                   = request.body.getStrings("sort").getOrElse(Nil)
    val withStats              = request.body.getBoolean("nstats").getOrElse(false)
    val (organizations, total) = organizationSrv.find(query, range, sort)
    val organizationWithStats  = auxSrv(organizations, 0, withStats, removeUnaudited = false)
    renderer.toOutput(OK, organizationWithStats, total)
  }

  def stats(): Action[Fields] = authenticated(Roles.superAdmin).async(fieldsBodyParser) { implicit request ⇒
    val query = request.body.getValue("query").fold[QueryDef](QueryDSL.any)(_.as[QueryDef])
    val aggs  = request.body.getValue("stats").getOrElse(throw BadRequestError("Parameter \"stats\" is missing")).as[Seq[Agg]]
    organizationSrv.stats(query, aggs).map(s ⇒ Ok(s))
  }
} 
Example 138
Source File: ResponderConfigCtrl.scala    From Cortex   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.thp.cortex.controllers

import scala.concurrent.{ExecutionContext, Future}

import play.api.libs.json.JsObject
import play.api.mvc.{AbstractController, Action, AnyContent, ControllerComponents}

import javax.inject.{Inject, Singleton}
import org.thp.cortex.models.{BaseConfig, Roles}
import org.thp.cortex.services.{ResponderConfigSrv, UserSrv}

import org.elastic4play.BadRequestError
import org.elastic4play.controllers.{Authenticated, Fields, FieldsBodyParser, Renderer}

@Singleton
class ResponderConfigCtrl @Inject()(
    responderConfigSrv: ResponderConfigSrv,
    userSrv: UserSrv,
    authenticated: Authenticated,
    fieldsBodyParser: FieldsBodyParser,
    renderer: Renderer,
    components: ControllerComponents,
    implicit val ec: ExecutionContext
) extends AbstractController(components) {

  def get(analyzerConfigName: String): Action[AnyContent] = authenticated(Roles.orgAdmin).async { request ⇒
    responderConfigSrv
      .getForUser(request.userId, analyzerConfigName)
      .map(renderer.toOutput(OK, _))
  }

  def list(): Action[AnyContent] = authenticated(Roles.orgAdmin).async { request ⇒
    responderConfigSrv
      .listConfigForUser(request.userId)
      .map { bc ⇒
        renderer.toOutput(
          OK,
          bc.sortWith {
            case (BaseConfig("global", _, _, _), _)               ⇒ true
            case (_, BaseConfig("global", _, _, _))               ⇒ false
            case (BaseConfig(a, _, _, _), BaseConfig(b, _, _, _)) ⇒ a.compareTo(b) < 0
          }
        )
      }
  }

  def update(analyzerConfigName: String): Action[Fields] = authenticated(Roles.orgAdmin).async(fieldsBodyParser) { implicit request ⇒
    request.body.getValue("config").flatMap(_.asOpt[JsObject]) match {
      case Some(config) ⇒
        responderConfigSrv
          .updateOrCreate(request.userId, analyzerConfigName, config)
          .map(renderer.toOutput(OK, _))
      case None ⇒ Future.failed(BadRequestError("attribute config has invalid format"))
    }
  }
} 
Example 139
Source File: FinatraHttpServer.scala    From the-finagle-docs   with MIT License 5 votes vote down vote up
package net.gutefrage.basic

import javax.inject.{Inject, Singleton}

import com.google.inject.{Module, Provides}
import com.twitter.finagle.Dtab
import com.twitter.finagle.http.{Request, Response}
import com.twitter.finatra.http.{Controller, HttpServer}
import com.twitter.finatra.http.filters.{CommonFilters, LoggingMDCFilter, TraceIdMDCFilter}
import com.twitter.finatra.http.routing.HttpRouter
import com.twitter.finatra.response.Mustache
import com.twitter.inject.TwitterModule
import com.twitter.inject.annotations.Flag
import net.gutefrage.Dtabs
import net.gutefrage.temperature.thrift.TemperatureService

object FinatraHttpServer extends HttpServer {

  premain {
    Dtabs.init()
  }

  override def modules: Seq[Module] = Seq(TemperatureServiceModule)

  override def defaultFinatraHttpPort = ":9000"

  override protected def configureHttp(router: HttpRouter): Unit =
    router
      .filter[LoggingMDCFilter[Request, Response]]
      .filter[TraceIdMDCFilter[Request, Response]]
      .filter[CommonFilters]
      .add[WeatherController]
}


class WeatherController @Inject()(
  temperatureService: TemperatureService.FutureIface,
  @Flag("local.doc.root") localDocRoot: String,
  @Flag("doc.root") docRoot: String
) extends Controller {

  private val docConfig = DocConfig(localDocRoot, docRoot)

  get("/") { request: Request =>
    temperatureService.mean().map { meanTemperature =>
      DashboardData(meanTemperature, Some("local"), docConfig)
    }
  }

  // Change dtab according to the environment
  get("/:env") { request: Request =>
    val environment = request.params("env")

    Dtab.unwind {
      Dtab.local = Dtab.read(s"/env => /s#/$environment")
      temperatureService.mean().map { meanTemperature =>
        DashboardData(meanTemperature, Some(environment), docConfig)
      }
    }
  }

  // Asset route (for styles.css)
  get("/assets/:*") { request: Request =>
    response.ok.file("/assets/" + request.params("*"))
  }
}

@Mustache("dashboard")
case class DashboardData(
  meanTemperature: Double,
  environment: Option[String],
  docConfig: DocConfig
)
case class DocConfig(localDocRoot: String, docRoot: String) 
Example 140
Source File: UserResource.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package resources

import java.util.concurrent.atomic.AtomicInteger
import javax.inject.Inject
import javax.inject.Singleton

import org.coursera.naptime.model.KeyFormat
import org.coursera.naptime.model.Keyed
import org.coursera.naptime.NaptimeModule
import org.coursera.naptime.Ok
import org.coursera.example.User
import org.coursera.naptime.courier.CourierFormats
import org.coursera.naptime.resources.TopLevelCollectionResource
import org.coursera.naptime.resources.RestActionHelpers
import play.api.libs.json.OFormat


  def create() = Rest
      .jsonBody[User]
      .create { context =>
        val user = context.body
        val id = userStore.create(user)

        // Could return Ok(Keyed(id, None)) if we want to return 201 Created,
        // with an empty body. Prefer returning the updated body, however.
        Ok(Keyed(id, Some(user)))
      }
}

class ResourceModule extends NaptimeModule {
  override def configure(): Unit = {
    bindResource[UsersResource]
    bind[UserStore].to[UserStoreImpl]
  }
}


trait UserStore {
  def get(id: Int): Option[User]
  def create(user: User): Int
}

class UserStoreImpl extends UserStore {
  @volatile
  var userStore = Map.empty[Int, User]
  val nextId = new AtomicInteger(0)


  def get(id: Int) = userStore.get(id)

  def create(user: User): Int = {
    val id = nextId.incrementAndGet()
    userStore = userStore + (id -> user)
    id
  }


}

class UserBanManager {
  @volatile
  var bannedUsers = Set.empty[Int]
} 
Example 141
Source File: InstructorStore.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package stores

import java.util.concurrent.atomic.AtomicInteger
import javax.inject.Singleton

import org.coursera.example.Instructor
import org.coursera.naptime.model.Keyed

@Singleton
class InstructorStore {
  @volatile
  var instructorStore = Map.empty[Int, Instructor]
  val nextId = new AtomicInteger(0)

  instructorStore = instructorStore + (
    1 -> Instructor(
      partnerId = "stanford",
      name = "Andrew Ng",
      photoUrl = ""),
    2 -> Instructor(
      partnerId = "ucsd",
      name = "Barb Oakley",
      photoUrl = ""))


  def get(id: Int) = instructorStore.get(id)

  def create(instructor: Keyed[Int, Instructor]): Unit = {
    instructorStore = instructorStore + (instructor.key -> instructor.value)
  }

  def all() = instructorStore
} 
Example 142
Source File: PartnerStore.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package stores

import java.util.concurrent.atomic.AtomicInteger
import javax.inject.Singleton

import org.coursera.example.Instructor
import org.coursera.example.Partner
import org.coursera.naptime.model.Keyed

@Singleton
class PartnerStore {
  @volatile
  var partnerStore = Map.empty[String, Partner]
  val nextId = new AtomicInteger(0)

  partnerStore = partnerStore + (
    "stanford" -> Partner(
      courseIds = List("ml"),
      instructorIds = List(1),
      name = "Stanford University",
      homepage = ""),
    "ucsd" -> Partner(
      courseIds = List("lhtl"),
      instructorIds = List(2),
      name = "UCSD",
      homepage = ""))


  def get(id: String) = partnerStore.get(id)

  def create(partner: Keyed[String, Partner]): Unit = {
    partnerStore = partnerStore + (partner.key -> partner.value)
  }

  def all() = partnerStore
} 
Example 143
Source File: CourseStore.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package stores

import java.util.concurrent.atomic.AtomicInteger
import javax.inject.Singleton

import com.linkedin.data.DataMap
import org.coursera.courier.templates.DataTemplates.DataConversion
import org.coursera.example.AnyData
import org.coursera.example.CertificateCourseMetadata
import org.coursera.example.Course
import org.coursera.example.DegreeCourseMetadata
import org.coursera.naptime.model.Keyed

import scala.collection.JavaConverters._

@Singleton
class CourseStore {
  @volatile
  var courseStore = Map.empty[String, Course]
  val nextId = new AtomicInteger(0)

  courseStore = courseStore + (
    "ml" -> Course(
      instructorIds = List(1),
      partnerId = "stanford",
      slug = "machine-learning",
      name = "Machine Learning",
      description = Some("Machine learning is the science of getting computers to act without being explicitly programmed."),
      extraData = AnyData.build(new DataMap(
        Map("firstModuleId" -> "wrh7vtpj").asJava),
        DataConversion.SetReadOnly),
      courseMetadata = CertificateCourseMetadata(
        certificateInstructorIds = List(1))),
    "lhtl" -> Course(
      instructorIds = List(2),
      partnerId = "ucsd",
      slug = "learning-how-to-learn",
      name = "Learning How to Learn",
      description = None,
      extraData = AnyData.build(new DataMap(
        Map("recentEnrollments" -> new Integer(1000)).asJava),
        DataConversion.SetReadOnly),
      courseMetadata = DegreeCourseMetadata(
        degreeCertificateName = "iMBA",
        degreeInstructorIds = List(1, 2))))

  def get(id: String) = courseStore.get(id)

  def create(course: Keyed[String, Course]): Unit = {
    courseStore = courseStore + (course.key -> course.value)
  }

  def all() = courseStore
} 
Example 144
Source File: InstructorsResource.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package resources

import javax.inject.Inject
import javax.inject.Singleton

import akka.stream.Materializer
import org.coursera.example.Instructor
import org.coursera.naptime.Fields
import org.coursera.naptime.FinderGraphQLRelation
import org.coursera.naptime.GetGraphQLRelation
import org.coursera.naptime.Ok
import org.coursera.naptime.ResourceName
import org.coursera.naptime.model.Keyed
import org.coursera.naptime.resources.CourierCollectionResource
import stores.InstructorStore

import scala.concurrent.ExecutionContext

@Singleton
class InstructorsResource @Inject() (
    instructorStore: InstructorStore)(implicit ec: ExecutionContext, mat: Materializer)
  extends CourierCollectionResource[Int, Instructor] {

  override def resourceName = "instructors"
  override def resourceVersion = 1
  override implicit lazy val Fields: Fields[Instructor] = BaseFields
    .withGraphQLRelations(
      "courses" -> FinderGraphQLRelation(
        resourceName = ResourceName("courses", 1),
        finderName = "byInstructor",
        arguments = Map("instructorId" -> "$id")),
      "partner" -> GetGraphQLRelation(
        resourceName = ResourceName("partners", 1),
        id = "$partnerId"))

  def get(id: Int) = Nap.get { context =>
    OkIfPresent(id, instructorStore.get(id))
  }

  def multiGet(ids: Set[Int]) = Nap.multiGet { context =>
    Ok(instructorStore.all()
      .filter(instructor => ids.contains(instructor._1))
      .map { case (id, instructor) => Keyed(id, instructor) }.toList)
  }

  def getAll() = Nap.getAll { context =>
    Ok(instructorStore.all().map { case (id, instructor) => Keyed(id, instructor) }.toList)
  }

} 
Example 145
Source File: UserResource.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package resources

import java.util.concurrent.atomic.AtomicInteger
import javax.inject.Inject
import javax.inject.Singleton

import akka.stream.Materializer
import org.coursera.naptime.model.KeyFormat
import org.coursera.naptime.model.Keyed
import org.coursera.naptime.Ok
import org.coursera.example.User
import org.coursera.naptime.courier.CourierFormats
import org.coursera.naptime.resources.TopLevelCollectionResource
import play.api.libs.json.OFormat

import scala.concurrent.ExecutionContext


@Singleton
class UsersResource @Inject() (
    userStore: UserStore,
    banManager: UserBanManager)
    (implicit override val executionContext: ExecutionContext,
    override val materializer: Materializer)
  extends TopLevelCollectionResource[Int, User] {

  override def resourceName = "users"
  override def resourceVersion = 1  // optional; defaults to 1
  implicit val fields = Fields.withDefaultFields(  // default field projection
    "id", "name", "email")

  override def keyFormat: KeyFormat[KeyType] = KeyFormat.intKeyFormat
  override implicit def resourceFormat: OFormat[User] = CourierFormats.recordTemplateFormats[User]

  def get(id: Int) = Nap.get { context =>
    OkIfPresent(id, userStore.get(id))
  }

  def multiGet(ids: Set[Int]) = Nap.multiGet { context =>
    Ok(userStore.all()
      .filter(user => ids.contains(user._1))
      .map { case (id, user) => Keyed(id, user) }.toList)
  }

  def getAll() = Nap.getAll { context =>
    Ok(userStore.all().map { case (id, user) => Keyed(id, user) }.toList)
  }

  def create() = Nap
    .jsonBody[User]
    .create { context =>
      val user = context.body
      val id = userStore.create(user)

      // Could return Ok(Keyed(id, None)) if we want to return 201 Created,
      // with an empty body. Prefer returning the updated body, however.
      Ok(Keyed(id, Some(user)))
    }

  def email(email: String) = Nap.finder { context =>
    Ok(userStore.all()
      .filter(_._2.email == email)
      .map { case (id, user) => Keyed(id, user) }.toList)
  }

}


trait UserStore {
  def get(id: Int): Option[User]
  def create(user: User): Int
  def all(): Map[Int, User]
}

@Singleton
class UserStoreImpl extends UserStore {
  @volatile
  var userStore = Map.empty[Int, User]
  val nextId = new AtomicInteger(0)

  def get(id: Int) = userStore.get(id)

  def create(user: User): Int = {
    val id = nextId.incrementAndGet()
    userStore = userStore + (id -> user)
    id
  }

  def all() = userStore

}

class UserBanManager {
  @volatile
  var bannedUsers = Set.empty[Int]
} 
Example 146
Source File: PartnersResource.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package resources

import javax.inject.Inject
import javax.inject.Singleton

import akka.stream.Materializer
import org.coursera.example.Partner
import org.coursera.naptime.Fields
import org.coursera.naptime.MultiGetGraphQLRelation
import org.coursera.naptime.Ok
import org.coursera.naptime.ResourceName
import org.coursera.naptime.model.Keyed
import org.coursera.naptime.resources.CourierCollectionResource
import stores.PartnerStore

import scala.concurrent.ExecutionContext

@Singleton
class PartnersResource @Inject() (
    partnerStore: PartnerStore)(implicit ec: ExecutionContext, mat: Materializer)
  extends CourierCollectionResource[String, Partner] {

  override def resourceName = "partners"
  override def resourceVersion = 1
  override implicit lazy val Fields: Fields[Partner] = BaseFields
    .withGraphQLRelations(
      "instructors" -> MultiGetGraphQLRelation(
        resourceName = ResourceName("instructors", 1),
        ids = "$instructorIds"),
      "courses" -> MultiGetGraphQLRelation(
        resourceName = ResourceName("courses", 1),
        ids = "$courseIds"))

  def get(id: String) = Nap.get { context =>
    OkIfPresent(id, partnerStore.get(id))
  }

  def multiGet(ids: Set[String]) = Nap.multiGet { context =>
    Ok(partnerStore.all()
      .filter(partner => ids.contains(partner._1))
      .map { case (id, partner) => Keyed(id, partner) }.toList)
  }

  def getAll() = Nap.getAll { context =>
    Ok(partnerStore.all().map { case (id, partner) => Keyed(id, partner) }.toList)
  }

} 
Example 147
Source File: CoursesResource.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package resources

import javax.inject.Inject
import javax.inject.Singleton

import akka.stream.Materializer
import org.coursera.example.Course
import org.coursera.naptime.Fields
import org.coursera.naptime.GetGraphQLRelation
import org.coursera.naptime.MultiGetGraphQLRelation
import org.coursera.naptime.Ok
import org.coursera.naptime.ResourceName
import org.coursera.naptime.model.Keyed
import org.coursera.naptime.resources.CourierCollectionResource
import stores.CourseStore

import scala.concurrent.ExecutionContext

@Singleton
class CoursesResource @Inject() (
    courseStore: CourseStore)(implicit ec: ExecutionContext, mat: Materializer)
  extends CourierCollectionResource[String, Course] {

  override def resourceName = "courses"
  override def resourceVersion = 1
  override implicit lazy val Fields: Fields[Course] = BaseFields
    .withGraphQLRelations(
      "instructors" -> MultiGetGraphQLRelation(
        resourceName = ResourceName("instructors", 1),
        ids = "$instructorIds"),
      "partner" -> GetGraphQLRelation(
        resourceName = ResourceName("partners", 1),
        id = "$partnerId",
        description = "Partner who produces this course."),
      "courseMetadata/org.coursera.example.CertificateCourseMetadata/certificateInstructors" ->
        MultiGetGraphQLRelation(
          resourceName = ResourceName("instructors", 1),
          ids = "${courseMetadata/certificate/certificateInstructorIds}",
          description = "Instructor whose name and signature appears on the course certificate."),
      "courseMetadata/org.coursera.example.DegreeCourseMetadata/degreeInstructors" ->
        MultiGetGraphQLRelation(
          resourceName = ResourceName("instructors", 1),
          ids = "${courseMetadata/degree/degreeInstructorIds}",
          description = "Instructor whose name and signature appears on the degree certificate."))

  def get(id: String = "v1-123") = Nap.get { context =>
    OkIfPresent(id, courseStore.get(id))
  }

  def multiGet(ids: Set[String], types: Set[String] = Set("course", "specialization")) = Nap.multiGet { context =>
    Ok(courseStore.all()
      .filter(course => ids.contains(course._1))
      .map { case (id, course) => Keyed(id, course) }.toList)
  }

  def getAll() = Nap.getAll { context =>

    val courses = courseStore.all().toList.map { case (id, course) => Keyed(id, course) }
    val coursesAfterNext = context.paging.start
      .map(s => courses.dropWhile(_.key != s))
      .getOrElse(courses)

    val coursesSubset = coursesAfterNext.take(context.paging.limit)

    val next = coursesAfterNext.drop(context.paging.limit).headOption.map(_.key)

    Ok(coursesSubset)
      .withPagination(next, Some(courses.size.toLong))
  }

  def byInstructor(instructorId: String) = Nap.finder { context =>
    val courses = courseStore.all()
      .filter(course => course._2.instructorIds.map(_.toString).contains(instructorId))
    Ok(courses.toList.map { case (id, course) => Keyed(id, course) })
      .withPagination(next = "testNext")
  }

} 
Example 148
Source File: QueryComplexityFilter.scala    From naptime   with Apache License 2.0 5 votes vote down vote up
package org.coursera.naptime.ari.graphql.controllers.filters

import javax.inject.Inject
import javax.inject.Singleton

import com.typesafe.scalalogging.StrictLogging
import org.coursera.naptime.ari.Response
import org.coursera.naptime.ari.graphql.GraphqlSchemaProvider
import org.coursera.naptime.ari.graphql.SangriaGraphQlContext
import org.coursera.naptime.ari.graphql.controllers.GraphQLController
import org.coursera.naptime.ari.graphql.marshaller.NaptimeMarshaller._
import org.coursera.naptime.ari.graphql.resolvers.NaptimeResolver
import org.coursera.naptime.ari.graphql.resolvers.NoopResolver
import play.api.libs.json.JsObject
import play.api.libs.json.Json
import play.api.mvc.Results
import sangria.ast.Document
import sangria.execution.ErrorWithResolver
import sangria.execution.Executor
import sangria.execution.QueryAnalysisError
import sangria.execution.QueryReducer

import scala.concurrent.ExecutionContext
import scala.concurrent.Future

@Singleton
class QueryComplexityFilter @Inject()(
    graphqlSchemaProvider: GraphqlSchemaProvider,
    configuration: ComplexityFilterConfiguration)(implicit executionContext: ExecutionContext)
    extends Filter
    with Results
    with StrictLogging {

  val MAX_COMPLEXITY = configuration.maxComplexity

  def apply(nextFilter: FilterFn): FilterFn = { incoming =>
    computeComplexity(incoming.document, incoming.variables)
      .flatMap { complexity =>
        if (complexity > MAX_COMPLEXITY) {
          Future.successful(
            OutgoingQuery(
              response = Json.obj("error" -> "Query is too complex.", "complexity" -> complexity),
              ariResponse = None))
        } else {
          nextFilter.apply(incoming)
        }
      }
      .recover {
        case error: QueryAnalysisError =>
          OutgoingQuery(error.resolveError.as[JsObject], None)
        case error: ErrorWithResolver =>
          OutgoingQuery(error.resolveError.as[JsObject], None)
        case error: Exception =>
          OutgoingQuery(Json.obj("errors" -> Json.arr(error.getMessage)), None)
      }
  }

  private[graphql] def computeComplexity(queryAst: Document, variables: JsObject)(
      implicit executionContext: ExecutionContext): Future[Double] = {
    // TODO(bryan): is there a way around this var?
    var complexity = 0D
    val complReducer = QueryReducer.measureComplexity[SangriaGraphQlContext] { (c, ctx) =>
      complexity = c
      ctx
    }
    val executorFut = Executor.execute(
      graphqlSchemaProvider.schema,
      queryAst,
      SangriaGraphQlContext(null, null, executionContext, debugMode = false),
      variables = variables,
      exceptionHandler = GraphQLController.exceptionHandler(logger),
      queryReducers = List(complReducer),
      deferredResolver = new NoopResolver())

    executorFut.map { _ =>
      complexity
    }

  }
}

case class ComplexityFilterConfiguration(maxComplexity: Int)

object ComplexityFilterConfiguration {
  val DEFAULT = ComplexityFilterConfiguration(100000)
} 
Example 149
Source File: Config.scala    From dependency   with MIT License 5 votes vote down vote up
package io.flow.dependency.www.lib

import io.flow.dependency.v0.models.Scms
import io.flow.play.util.{Config => FlowConfig}
import java.net.URLEncoder
import javax.inject.{Inject, Singleton}


@Singleton
class GitHubConfig @Inject()(config: FlowConfig) {
  private val Scopes = Seq("user:email", "repo", "read:repo_hook", "write:repo_hook")
  private val OauthUrl = "https://github.com/login/oauth/authorize"

  private val githubClientId = config.requiredString("github.dependency.client.id")
  private val dependencyWwwHost = config.requiredString("dependency.www.host")
  private val githubBaseUrl = s"$dependencyWwwHost/login/github"

  def githubOauthUrl(returnUrl: Option[String]): String = {
    val returnUrlParam = returnUrl
      .map { encoded =>
        s"$githubBaseUrl?return_url=$encoded"
      }

    val params: Map[String, String] = Seq(
      Some("scope" -> Scopes.mkString(",")),
      Some("client_id" -> githubClientId),
      returnUrlParam.map("redirect_uri" -> _)
    ).flatten.toMap

    val queryParams =
      params
        .view
        .mapValues(URLEncoder.encode(_, "UTF-8"))
        .map {
          case (key, value) => s"$key=$value"
        }

    OauthUrl + "?" + queryParams.mkString("&")
  }

}

object Config {
  val VersionsPerPage = 5

  
  def scmsUrl(scms: Scms, uri: String, path: String): String = {
    val separator = if (path.startsWith("/")) "" else "/"
    val pathSep = separator + path

    scms match {
      case Scms.Github =>
        s"$uri/blob/master$pathSep"

      case Scms.UNDEFINED(_) =>
        uri + pathSep
    }
  }

} 
Example 150
Source File: LibraryRecommendationsDao.scala    From dependency   with MIT License 5 votes vote down vote up
package db

import javax.inject.{Inject, Singleton}

import io.flow.dependency.api.lib.Recommendations
import io.flow.dependency.v0.models.{Library, LibraryVersion, Project, VersionForm}
import com.google.inject.Provider

case class LibraryRecommendation(
  library: Library,
  from: String,
  to: LibraryVersion,
  latest: LibraryVersion
)

@Singleton
class LibraryRecommendationsDao @Inject()(
  internalProjectLibrariesDao: InternalProjectLibrariesDao,
  libraryVersionsDaoProvider: Provider[LibraryVersionsDao],
  librariesDaoProvider: Provider[LibrariesDao],
){

  def forProject(project: Project): Seq[LibraryRecommendation] = {
    val recommendations = scala.collection.mutable.ListBuffer[LibraryRecommendation]()
    val auth = Authorization.Organization(project.organization.id)

    internalProjectLibrariesDao.findAll(
      Authorization.Organization(project.organization.id),
      projectId = Some(project.id),
      hasLibrary = Some(true),
      limit = None,
      orderBy = None,
    ).foreach { projectLibrary =>
      projectLibrary.db.libraryId.flatMap { libraryId => librariesDaoProvider.get.findById(auth, libraryId) }.map { library =>
        val recentVersions = versionsGreaterThan(auth, library, projectLibrary.db.version)
        recommend(projectLibrary, recentVersions).map { v =>
          recommendations ++= Seq(
            LibraryRecommendation(
              library = library,
              from = projectLibrary.db.version,
              to = v,
              latest = recentVersions.headOption.getOrElse(v)
            )
          )
        }
      }
    }

    recommendations.toSeq
  }

  def recommend(current: InternalProjectLibrary, others: Seq[LibraryVersion]): Option[LibraryVersion] = {
    Recommendations.version(
      VersionForm(current.db.version, current.db.crossBuildVersion),
      others.map(v => VersionForm(v.version, v.crossBuildVersion))
    ).map { version =>
      others.find { _.version == version }.getOrElse {
        sys.error(s"Failed to find recommended library with version[$version]")
      }
    }
  }

  
  private[this] def versionsGreaterThan(
    auth: Authorization,
    library: Library,
    version: String
  ): Seq[LibraryVersion] = {
    libraryVersionsDaoProvider.get.findAll(
      auth,
      libraryId = Some(library.id),
      greaterThanVersion = Some(version),
      limit = None
    )
  }

} 
Example 151
Source File: BinaryRecommendationsDao.scala    From dependency   with MIT License 5 votes vote down vote up
package db

import javax.inject.{Inject, Singleton}

import io.flow.dependency.api.lib.Recommendations
import io.flow.dependency.v0.models.{Binary, BinaryVersion, Project, ProjectBinary, VersionForm}
import io.flow.postgresql.Pager
import com.google.inject.Provider

case class BinaryRecommendation(
  binary: Binary,
  from: String,
  to: BinaryVersion,
  latest: BinaryVersion
)

@Singleton
class BinaryRecommendationsDao @Inject()(
  binaryVersionsDaoProvider: Provider[BinaryVersionsDao],
  projectBinariesDaoProvider: Provider[ProjectBinariesDao],
  binariesDaoProvider: Provider[BinariesDao]
) {

  def forProject(project: Project): Seq[BinaryRecommendation] = {
    val recommendations = scala.collection.mutable.ListBuffer[BinaryRecommendation]()

    Pager.create { offset =>
      projectBinariesDaoProvider.get.findAll(
        Authorization.Organization(project.organization.id),
        projectId = Some(project.id),
        hasBinary = Some(true),
        offset = offset
      )
    }.foreach { projectBinary =>
      projectBinary.binary.flatMap { lib => binariesDaoProvider.get.findById(lib.id) }.map { binary =>
        val recentVersions = versionsGreaterThan(binary, projectBinary.version)
        recommend(projectBinary, recentVersions).map { v =>
          recommendations ++= Seq(
            BinaryRecommendation(
              binary = binary,
              from = projectBinary.version,
              to = v,
              latest = recentVersions.headOption.getOrElse(v)
            )
          )
        }
      }
    }

    recommendations.toSeq
  }

  def recommend(current: ProjectBinary, others: Seq[BinaryVersion]): Option[BinaryVersion] = {
    Recommendations.version(
      VersionForm(current.version),
      others.map(v => VersionForm(v.version))
    ).map { version =>
      others.find {
        _.version == version
      }.getOrElse {
        sys.error(s"Failed to find recommended binary with version[$version]")
      }
    }
  }

  
  private[this] def versionsGreaterThan(binary: Binary, version: String): Seq[BinaryVersion] = {
    val recommendations = scala.collection.mutable.ListBuffer[BinaryVersion]()
    Pager.create { offset =>
      binaryVersionsDaoProvider.get.findAll(
        binaryId = Some(binary.id),
        greaterThanVersion = Some(version),
        offset = offset
      )
    }.foreach { binaryVersion =>
      recommendations ++= Seq(binaryVersion)
    }
    recommendations.toSeq
  }

} 
Example 152
Source File: OrganizationsHelper.scala    From dependency   with MIT License 5 votes vote down vote up
package controllers.helpers

import javax.inject.{Inject, Singleton}

import db.{Authorization, OrganizationsDao}
import io.flow.common.v0.models.UserReference
import io.flow.dependency.v0.models.Organization
import play.api.mvc.{Result, Results}

@Singleton
class OrganizationsHelper @Inject()(
  organizationsDao: OrganizationsDao
) {

  def withOrganization(user: UserReference, id: String)(
    f: Organization => Result
  ) = {
    organizationsDao.findById(Authorization.User(user.id), id) match {
      case None => {
        Results.NotFound
      }
      case Some(organization) => {
        f(organization)
      }
    }
  }

} 
Example 153
Source File: BinaryHelper.scala    From dependency   with MIT License 5 votes vote down vote up
package controllers.helpers

import javax.inject.{Inject, Singleton}

import db.BinariesDao
import io.flow.dependency.v0.models.Binary
import play.api.mvc.{Result, Results}

@Singleton
class BinaryHelper @Inject()(
  binariesDao: BinariesDao
) {

  def withBinary(id: String)(
    f: Binary => Result
  ): Result = {
    binariesDao.findById(id) match {
      case None => {
        Results.NotFound
      }
      case Some(binary) => {
        f(binary)
      }
    }
  }


} 
Example 154
Source File: LibrariesHelper.scala    From dependency   with MIT License 5 votes vote down vote up
package controllers.helpers

import javax.inject.{Inject, Singleton}

import db.{Authorization, LibrariesDao}
import io.flow.common.v0.models.UserReference
import io.flow.dependency.v0.models.Library
import play.api.mvc.{Result, Results}

@Singleton
class LibrariesHelper @Inject()(
  librariesDao: LibrariesDao
) {

  def withLibrary(user: UserReference, id: String)(
    f: Library => Result
  ): Result = {
    librariesDao.findById(Authorization.User(user.id), id) match {
      case None => {
        Results.NotFound
      }
      case Some(library) => {
        f(library)
      }
    }
  }


} 
Example 155
Source File: UsersHelper.scala    From dependency   with MIT License 5 votes vote down vote up
package controllers.helpers

import javax.inject.{Inject, Singleton}

import db.UsersDao
import io.flow.common.v0.models.User
import play.api.mvc.{Result, Results}

@Singleton
class UsersHelper @Inject()(
  usersDao: UsersDao
) {

  def withUser(id: String)(
    f: User => Result
  ) = {
    usersDao.findById(id) match {
      case None => {
        Results.NotFound
      }
      case Some(user) => {
        f(user)
      }
    }
  }

} 
Example 156
Source File: ProjectHelper.scala    From dependency   with MIT License 5 votes vote down vote up
package controllers.helpers

import javax.inject.{Inject, Singleton}

import db.{Authorization, ProjectsDao}
import io.flow.common.v0.models.UserReference
import io.flow.dependency.v0.models.Project
import play.api.mvc.{Result, Results}

@Singleton
class ProjectHelper @Inject()(
  projectsDao: ProjectsDao
) {

  def withProject(user: UserReference, id: String)(
    f: Project => Result
  ): Result = {
    projectsDao.findById(Authorization.User(user.id), id) match {
      case None => {
        Results.NotFound
      }
      case Some(project) => {
        f(project)
      }
    }
  }


} 
Example 157
Source File: ProjectDependencyResolutions.scala    From dependency   with MIT License 5 votes vote down vote up
package controllers

import cache.ProjectDependencyResolutionServiceCache
import db.{Authorization, MembershipsDao}
import io.flow.common.v0.models.UserReference
import io.flow.dependency.v0.models.json._
import io.flow.play.controllers.FlowControllerComponents
import javax.inject.{Inject, Singleton}
import play.api.mvc._
import io.flow.util.Config
import play.api.libs.json.Json

@Singleton
class ProjectDependencyResolutions @Inject() (
  val config: Config,
  val controllerComponents: ControllerComponents,
  val flowControllerComponents: FlowControllerComponents,
  val baseIdentifiedControllerWithFallbackComponents: BaseIdentifiedControllerWithFallbackComponents,
  membershipsDao: MembershipsDao,
  service: ProjectDependencyResolutionServiceCache,
) extends BaseIdentifiedControllerWithFallback {

  def get(organization: String, groupId: String): Action[AnyContent] = IdentifiedWithFallback { request =>
    withValidatedMember(request.user, organization) {
      Ok(
        Json.toJson(
          service.getByOrganizationKey(organization, groupId = groupId)
        )
      )
    }
  }

  private[this] def withValidatedMember(user: UserReference, organizationKey: String)(f: => Result): Result = {
    membershipsDao.findByOrganizationAndUserId(Authorization.All, organizationKey, user.id) match {
      case None => Unauthorized
      case Some(_) => f
    }
  }
} 
Example 158
Source File: IdentificationWithFallback.scala    From dependency   with MIT License 5 votes vote down vote up
package controllers.util

import java.util.UUID

import javax.inject.{Inject, Singleton}
import db.{TokensDao, UsersDao}
import io.flow.common.v0.models.UserReference
import io.flow.log.RollbarLogger
import io.flow.play.controllers._
import io.flow.play.util.{AuthData, Config}
import play.api.mvc._

import scala.concurrent.{ExecutionContext, Future}

// Custom implementation based on FlowController.Identified but with database fallback for auth
@Singleton
class IdentificationWithFallback @Inject()(
  val parser: BodyParsers.Default,
  val config: Config,
  authorization: AuthorizationImpl,
  tokensDao: TokensDao,
  usersDao: UsersDao
)(implicit val executionContext: ExecutionContext, logger: RollbarLogger)
  extends ActionBuilder[IdentifiedRequest, AnyContent] with FlowActionInvokeBlockHelper {

  def invokeBlock[A](request: Request[A], block: (IdentifiedRequest[A]) => Future[Result]): Future[Result] = {
    auth(request.headers)(AuthData.Identified.fromMap) match {
      case None =>
        legacyUser(request.headers) match {
          case None => Future.successful(unauthorized(request))
          case Some(user) =>
            val ad = AuthData.Identified(user = user, session = None, requestId = "lib-play-" + UUID.randomUUID.toString, customer = None)
            block(new IdentifiedRequest(ad, request))
        }
      case Some(ad) => block(new IdentifiedRequest(ad, request))
    }
  }

  private[this] def legacyUser(headers: Headers): Option[UserReference] = {
    basicAuthorizationToken(headers) match {
      case None => None
      case Some(token) => {
        token match {
          case token: Token => getUser(token.token)
          case token: JwtToken => Some(UserReference(token.userId))
        }
      }
    }
  }

  private def getUser(token: String): Option[UserReference] = {
    tokensDao.findByToken(token) match {
      case Some(t) => Some(UserReference(t.user.id))
      case None => usersDao.findById(token).map(user => UserReference(user.id))
    }
  }

  
  private[this] def basicAuthorizationToken(
    headers: play.api.mvc.Headers
  ): Option[Authorization] = {
    headers.get("Authorization").flatMap { h =>
      authorization.get(h)
    }
  }

} 
Example 159
Source File: PersonRepository.scala    From akka-http-test   with Apache License 2.0 5 votes vote down vote up
package com.github.dnvriend.component.repository

import javax.inject.{ Inject, Singleton }

import akka.NotUsed
import akka.stream.scaladsl.Source
import com.github.dnvriend.component.simpleserver.dto.http.Person

import scala.concurrent.{ ExecutionContext, Future }

@Singleton
class PersonRepository @Inject() (implicit ec: ExecutionContext) {
  def people(numberOfPeople: Int): Source[Person, NotUsed] =
    Source.repeat(Person("foo", 1, false)).zipWith(Source.fromIterator(() => Iterator from 0)) {
      case (p, i) => p.copy(
        name = if (i % 10 == 0) "baz-" + i else if (i % 2 == 0) "foo-" + i else "bar-" + i,
        age = i,
        married = i % 2 == 0
      )
    }.take(numberOfPeople)

  def listOfPersons(numberOfPeople: Int): Seq[Person] = (0 to numberOfPeople).map { i =>
    Person(
      name = if (i % 10 == 0) "baz-" + i else if (i % 2 == 0) "foo-" + i else "bar-" + i,
      age = i,
      married = i % 2 == 0
    )
  }

  def personAsync: Future[Person] = Future.successful(personSync)

  def personAsyncFailed: Future[Person] = Future.failed(new RuntimeException("This should fail")).map(_ => personSync)

  def personSync: Person = Person("John Doe", 25, false)
} 
Example 160
Source File: OAuth2AuthProvider.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import javax.inject.{Inject, Singleton}

import play.api.Logger

import scala.concurrent.{ExecutionContext, Future}


@Singleton
class OAuth2AuthProvider @Inject() (getTokenInfo: (OAuth2Token) => Future[Option[TokenInfo]])(implicit ec: ExecutionContext)
  extends AuthProvider {

  val logger: Logger = Logger("security.OAuth2AuthProvider")

  private val bearerTokenType = "Bearer"

  override def valid(token: Option[OAuth2Token], scope: Scope): Future[AuthResult] =
    token.map(validateToken(_, scope)).getOrElse(Future.successful(AuthTokenEmpty))

  private def validateToken(token: OAuth2Token, scope: Scope): Future[AuthResult] =
    getTokenInfo(token).map(validateTokenInfo(_, token, scope))

  private def validateTokenInfo(tokenInfo: Option[TokenInfo], token: OAuth2Token, scope: Scope): AuthResult = {
    tokenInfo match {
      case Some(tokenInfo @ TokenInfo(`token`.value, thatScope, `bearerTokenType`, _, _, _)) if scope.in(thatScope) =>
        AuthTokenValid(tokenInfo)
      case Some(tokenInfo @ TokenInfo(_, thatScope, tokenType, _, _, _)) =>
        logger.info(s"Token '${token.toSafeString} has insufficient scope or wrong type, token scopes are ${thatScope.names.mkString(", ")}," +
          s"token type is $tokenType")
        AuthTokenInsufficient
      case None =>
        logger.debug(s"Token '${token.toSafeString} is not valid'")
        AuthTokenInvalid
    }
  }
} 
Example 161
Source File: IAMClient.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import java.util.concurrent.atomic.AtomicInteger
import javax.inject.{Inject, Singleton}

import akka.actor.ActorSystem
import akka.pattern.CircuitBreaker
import org.zalando.zhewbacca.metrics.PluggableMetrics
import play.api.http.Status._
import play.api.libs.ws.WSClient
import play.api.{Configuration, Logger}

import scala.concurrent.duration._
import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal

import atmos.dsl._
import atmos.dsl.Slf4jSupport._


@Singleton
class IAMClient @Inject() (
    config: Configuration,
    pluggableMetrics: PluggableMetrics,
    ws: WSClient,
    actorSystem: ActorSystem,
    implicit val ec: ExecutionContext) extends (OAuth2Token => Future[Option[TokenInfo]]) {

  val logger: Logger = Logger("security.IAMClient")

  val METRICS_BREAKER_CLOSED = 0
  val METRICS_BREAKER_OPEN = 1
  val circuitStatus = new AtomicInteger()

  pluggableMetrics.gauge {
    circuitStatus.get
  }

  val authEndpoint: String = config.getOptional[String]("authorisation.iam.endpoint").getOrElse(
    throw new IllegalArgumentException("Authorisation: IAM endpoint is not configured"))

  val breakerMaxFailures: Int = config.getOptional[Int]("authorisation.iam.cb.maxFailures").getOrElse(
    throw new IllegalArgumentException("Authorisation: Circuit Breaker max failures is not configured"))

  val breakerCallTimeout: FiniteDuration = config.getOptional[FiniteDuration]("authorisation.iam.cb.callTimeout").getOrElse(
    throw new IllegalArgumentException("Authorisation: Circuit Breaker call timeout is not configured"))

  val breakerResetTimeout: FiniteDuration = config.getOptional[FiniteDuration]("authorisation.iam.cb.resetTimeout").getOrElse(
    throw new IllegalArgumentException("Authorisation: Circuit Breaker reset timeout is not configured"))

  val breakerMaxRetries: TerminationPolicy = config.getOptional[Int]("authorisation.iam.maxRetries").getOrElse(
    throw new IllegalArgumentException("Authorisation: Circuit Breaker max retries is not configured")).attempts

  val breakerRetryBackoff: FiniteDuration = config.getOptional[FiniteDuration]("authorisation.iam.retry.backoff.duration").getOrElse(
    throw new IllegalArgumentException("Authorisation: Circuit Breaker the duration of exponential backoff is not configured"))

  lazy val breaker: CircuitBreaker = new CircuitBreaker(
    actorSystem.scheduler,
    breakerMaxFailures,
    breakerCallTimeout,
    breakerResetTimeout).onHalfOpen {
    circuitStatus.set(METRICS_BREAKER_OPEN)
  }.onOpen {
    circuitStatus.set(METRICS_BREAKER_OPEN)
  }.onClose {
    circuitStatus.set(METRICS_BREAKER_CLOSED)
  }

  implicit val retryRecover = retryFor { breakerMaxRetries } using {
    exponentialBackoff { breakerRetryBackoff }
  } monitorWith {
    logger.logger onRetrying logNothing onInterrupted logWarning onAborted logError
  }

  override def apply(token: OAuth2Token): Future[Option[TokenInfo]] = {
    breaker.withCircuitBreaker(
      pluggableMetrics.timing(
        retryAsync(s"Calling $authEndpoint") {
          ws.url(authEndpoint).withQueryStringParameters(("access_token", token.value)).get()
        })).map { response =>
        response.status match {
          case OK => Some(response.json.as[TokenInfo])
          case _ => None
        }
      } recover {
        case NonFatal(e) =>
          logger.error(s"Exception occurred during validation of token '${token.toSafeString}': $e")
          None // consider any exception as invalid token
      }
  }

} 
Example 162
Source File: MavenLoggerProxy.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.maven

import javax.inject.Inject
import javax.inject.Singleton

import com.lightbend.lagom.devmode.MiniLogger
import org.codehaus.plexus.logging.Logger
import play.dev.filewatch.LoggerProxy


@Singleton
class MavenLoggerProxy @Inject() (logger: Logger) extends LoggerProxy with MiniLogger {
  override def debug(message: => String): Unit = {
    if (logger.isDebugEnabled) {
      logger.debug(message)
    }
  }

  override def info(message: => String): Unit = {
    if (logger.isInfoEnabled) {
      logger.info(message)
    }
  }

  override def warn(message: => String): Unit = {
    if (logger.isWarnEnabled) {
      logger.warn(message)
    }
  }

  override def error(message: => String): Unit = {
    if (logger.isErrorEnabled) {
      logger.error(message)
    }
  }

  override def verbose(message: => String): Unit = debug(message)

  override def success(message: => String): Unit = info(message)

  override def trace(t: => Throwable): Unit = {
    if (logger.isDebugEnabled) {
      logger.debug(t.getMessage, t)
    }
  }
} 
Example 163
Source File: ScalaClassLoaderManager.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.maven

import java.net.URLClassLoader
import javax.inject.Inject
import javax.inject.Singleton

import org.eclipse.aether.artifact.Artifact


  def extractScalaClassLoader(artifacts: Seq[Artifact]): ClassLoader = synchronized {
    val scalaArtifacts = artifacts.filter { artifact =>
      ScalaLibs.contains(artifact.getGroupId -> stripScalaVersion(artifact.getArtifactId))
    }

    val cacheKey = createCacheKey(scalaArtifacts)
    cache.get(cacheKey) match {
      case Some(classLoader) =>
        logger.debug(s"ScalaClassLoader cache hit - $cacheKey")
        classLoader
      case None =>
        logger.debug(s"ScalaClassLoader cache miss - $cacheKey")
        // Use System classloader parent as documented here:
        // https://svn.apache.org/repos/infra/websites/production/maven/content/reference/maven-classloading.html#Maven_API_classloader
        // Keep in mind this does not contain any application or javaagent classes, which will
        // be added in the classLoader below.
        //
        // This behaves a little different depending on the Java version used:
        // - For Java 8: the parent is the boostrap class loader (or null), which in the end
        //   means the boostrap class loader is used.
        // - For Java9+: the parent is the platform class loader is a parent or an ancestor
        //   of the system class loader that all platform classes are visible to it.
        val parent      = ClassLoader.getSystemClassLoader().getParent()
        val classLoader = new URLClassLoader(scalaArtifacts.map(_.getFile.toURI.toURL).toArray, parent)
        cache += (cacheKey -> classLoader)
        classLoader
    }
  }
} 
Example 164
Source File: ServiceRegistrationModule.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.server

import java.net.URI
import java.util.function.{ Function => JFunction }

import akka.actor.CoordinatedShutdown
import akka.Done
import akka.NotUsed
import com.lightbend.lagom.internal.javadsl.registry.ServiceRegistry
import com.lightbend.lagom.internal.javadsl.registry.ServiceRegistryService
import com.lightbend.lagom.internal.javadsl.server.ResolvedServices
import com.lightbend.lagom.devmode.internal.registry.serviceDnsRecords
import com.typesafe.config.Config
import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton
import play.api.inject.Binding
import play.api.inject.Module
import play.api.Configuration
import play.api.Environment
import play.api.Logger

import scala.compat.java8.FutureConverters.CompletionStageOps
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import scala.collection.JavaConverters._
import scala.collection.immutable

class ServiceRegistrationModule extends Module {
  override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(
    bind[ServiceRegistrationModule.RegisterWithServiceRegistry].toSelf.eagerly(),
    bind[ServiceRegistrationModule.ServiceConfig].toProvider[ServiceRegistrationModule.ServiceConfigProvider]
  )
}

object ServiceRegistrationModule {
  class ServiceConfigProvider @Inject() (config: Config) extends Provider[ServiceConfig] {
    override lazy val get = ServiceConfig(serviceDnsRecords(config))
  }

  case class ServiceConfig(uris: immutable.Seq[URI])

  
  @Singleton
  private class RegisterWithServiceRegistry @Inject() (
      coordinatedShutdown: CoordinatedShutdown,
      resolvedServices: ResolvedServices,
      config: ServiceConfig,
      registry: ServiceRegistry
  )(implicit ec: ExecutionContext) {
    private lazy val logger: Logger = Logger(this.getClass())

    private val locatableServices = resolvedServices.services.filter(_.descriptor.locatableService)

    coordinatedShutdown.addTask(
      CoordinatedShutdown.PhaseBeforeServiceUnbind,
      "unregister-services-from-service-locator-javadsl"
    ) { () =>
      Future
        .sequence(locatableServices.map { service =>
          registry.unregister(service.descriptor.name).invoke().toScala
        })
        .map(_ => Done)
    }

    locatableServices.foreach { service =>
      val c = ServiceRegistryService.of(config.uris.asJava, service.descriptor.acls)
      registry
        .register(service.descriptor.name)
        .invoke(c)
        .exceptionally(new JFunction[Throwable, NotUsed] {
          def apply(t: Throwable) = {
            logger
              .error(s"Service name=[${service.descriptor.name}] couldn't register itself to the service locator.", t)
            NotUsed.getInstance()
          }
        })
    }
  }
} 
Example 165
Source File: JavaServiceRegistryClient.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.registry

import java.net.URI
import java.util.Optional

import javax.inject.Inject
import javax.inject.Singleton
import com.lightbend.lagom.devmode.internal.registry.AbstractLoggingServiceRegistryClient
import com.lightbend.lagom.javadsl.api.transport.NotFound

import scala.collection.immutable
import scala.compat.java8.FutureConverters._
import scala.compat.java8.OptionConverters
import scala.concurrent.ExecutionContext
import scala.concurrent.Future

@Singleton
private[lagom] class JavaServiceRegistryClient @Inject() (
    registry: ServiceRegistry,
    implicit val ec: ExecutionContext
) extends AbstractLoggingServiceRegistryClient {
  protected override def internalLocateAll(serviceName: String, portName: Option[String]): Future[immutable.Seq[URI]] =
    registry
      .lookup(serviceName, OptionConverters.toJava(portName))
      .invoke()
      .toScala
      .map(immutable.Seq[URI](_))
      .recover {
        case _: NotFound => Nil
      }
} 
Example 166
Source File: ServiceRegistryServiceLocator.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.registry

import java.net.URI
import java.util.concurrent.CompletionStage
import java.util.Optional
import java.util.{ List => JList }

import javax.inject.Inject
import javax.inject.Singleton
import com.lightbend.lagom.devmode.internal.registry.ServiceRegistryClient
import com.lightbend.lagom.javadsl.api.Descriptor.Call
import com.lightbend.lagom.javadsl.client.CircuitBreakersPanel
import com.lightbend.lagom.javadsl.client.CircuitBreakingServiceLocator

import scala.collection.JavaConverters._
import scala.compat.java8.FutureConverters._
import scala.compat.java8.OptionConverters._
import scala.concurrent.ExecutionContext

@Singleton
private[lagom] class ServiceRegistryServiceLocator @Inject() (
    circuitBreakers: CircuitBreakersPanel,
    client: ServiceRegistryClient,
    implicit val ec: ExecutionContext
) extends CircuitBreakingServiceLocator(circuitBreakers) {
  override def locateAll(name: String, serviceCall: Call[_, _]): CompletionStage[JList[URI]] =
    // a ServiceLocator doesn't know what a `portName` is so we default to `None` and the
    // implementation will return any registry without a port name. This means that in order
    // for this queries to work any service registered using `http` as portName will also have
    // to be registered without name.
    client.locateAll(name, None).map(_.asJava).toJava

  override def locate(name: String, serviceCall: Call[_, _]): CompletionStage[Optional[URI]] =
    // a ServiceLocator doesn't know what a `portName` is so we default to `None` and the
    // implementation will return any registry without a port name. This means that in order
    // for this queries to work any service registered using `http` as portName will also have
    // to be registered without name.
    client.locateAll(name, None).map(_.headOption.asJava).toJava
} 
Example 167
Source File: ProjectionRegistryModule.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.javadsl.projection

import java.util.concurrent.CompletionStage

import akka.actor.ActorSystem
import akka.annotation.ApiMayChange
import akka.annotation.InternalApi
import com.lightbend.lagom.internal.projection.ProjectionRegistry
import com.lightbend.lagom.internal.projection.ProjectionRegistryActor.WorkerCoordinates
import com.lightbend.lagom.projection.State
import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton
import play.api.Configuration
import play.api.Environment
import play.api.inject.Binding
import play.api.inject.Module

import scala.compat.java8.FutureConverters
import scala.concurrent.ExecutionContext


private class ProjectionsImpl @Inject() (registry: ProjectionRegistry)(
    implicit executionContext: ExecutionContext
) extends Projections {
  import FutureConverters._

  override def getStatus(): CompletionStage[State] =
    registry.getState().toJava

  override def stopAllWorkers(projectionName: String): Unit =
    registry.stopAllWorkers(projectionName)

  override def stopWorker(projectionName: String, tagName: String): Unit =
    registry.stopWorker(WorkerCoordinates(projectionName, tagName))

  override def startAllWorkers(projectionName: String): Unit =
    registry.startAllWorkers(projectionName)

  override def startWorker(projectionName: String, tagName: String): Unit =
    registry.startWorker(WorkerCoordinates(projectionName, tagName))
} 
Example 168
Source File: PubSubRegistryImpl.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.pubsub

import akka.actor.ActorSystem
import akka.cluster.pubsub.DistributedPubSub
import com.typesafe.config.Config
import javax.inject.Inject
import javax.inject.Singleton

import com.lightbend.lagom.javadsl.pubsub.PubSubRef
import com.lightbend.lagom.javadsl.pubsub.PubSubRegistry
import com.lightbend.lagom.javadsl.pubsub.TopicId

@Singleton
private[lagom] class PubSubRegistryImpl(system: ActorSystem, conf: Config) extends PubSubRegistry {
  @Inject
  def this(system: ActorSystem) =
    this(system, system.settings.config.getConfig("lagom.pubsub"))

  private val pubsub          = DistributedPubSub(system)
  private val bufferSize: Int = conf.getInt("subscriber-buffer-size")

  override def refFor[T](topic: TopicId[T]): PubSubRef[T] =
    new PubSubRef(topic, pubsub.mediator, system, bufferSize)
} 
Example 169
Source File: TopicFactory.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.api.broker

import javax.inject.Inject
import javax.inject.Singleton

import com.lightbend.lagom.javadsl.api.Descriptor.TopicCall
import com.lightbend.lagom.javadsl.api.broker.Topic
import play.api.inject.Injector

import scala.util.control.NonFatal


trait TopicFactoryProvider {
  def get: Option[TopicFactory]
}

@Singleton
class InjectorTopicFactoryProvider @Inject() (injector: Injector) extends TopicFactoryProvider {
  override lazy val get: Option[TopicFactory] =
    try {
      Some(injector.instanceOf[TopicFactory])
    } catch {
      case NonFatal(e) => None
    }
}

object NoTopicFactoryProvider extends TopicFactoryProvider {
  override val get = None
} 
Example 170
Source File: CircuitBreakerModule.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.client

import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton
import akka.actor.ActorSystem
import com.lightbend.lagom.internal.client.CircuitBreakerConfig
import com.lightbend.lagom.internal.client.CircuitBreakerMetricsProviderImpl
import com.lightbend.lagom.internal.client.CircuitBreakerMetricsProviderProvider
import com.lightbend.lagom.internal.spi.CircuitBreakerMetricsProvider
import com.lightbend.lagom.javadsl.client.CircuitBreakersPanel
import play.api.inject.Binding
import play.api.inject.Module
import play.api.Configuration
import play.api.Environment

class CircuitBreakerModule extends Module {
  override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = {
    Seq(
      bind[CircuitBreakersPanel].to[CircuitBreakersPanelImpl],
      bind[CircuitBreakerMetricsProvider].toProvider[CircuitBreakerMetricsProviderProvider],
      bind[CircuitBreakerConfig].toSelf,
      bind[CircuitBreakerMetricsProviderImpl].toSelf
    )
  }
} 
Example 171
Source File: ServiceClientLoader.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.client

import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton
import com.lightbend.lagom.internal.javadsl.api.JacksonPlaceholderExceptionSerializer
import com.lightbend.lagom.internal.javadsl.api.JacksonPlaceholderSerializerFactory
import com.lightbend.lagom.internal.javadsl.api.ServiceReader
import com.lightbend.lagom.javadsl.api.Service
import com.lightbend.lagom.javadsl.jackson.JacksonExceptionSerializer
import com.lightbend.lagom.javadsl.jackson.JacksonSerializerFactory
import play.api.Environment

@Singleton
class ServiceClientLoader @Inject() (
    jacksonSerializerFactory: JacksonSerializerFactory,
    jacksonExceptionSerializer: JacksonExceptionSerializer,
    environment: Environment,
    implementor: JavadslServiceClientImplementor
) {
  def loadServiceClient[T](interface: Class[T]): T = {
    if (classOf[Service].isAssignableFrom(interface)) {
      val descriptor = ServiceReader.readServiceDescriptor(
        environment.classLoader,
        interface.asSubclass(classOf[Service])
      )
      val resolved = ServiceReader.resolveServiceDescriptor(
        descriptor,
        environment.classLoader,
        Map(JacksonPlaceholderSerializerFactory   -> jacksonSerializerFactory),
        Map(JacksonPlaceholderExceptionSerializer -> jacksonExceptionSerializer)
      )
      implementor.implement(interface, resolved)
    } else {
      throw new IllegalArgumentException("Don't know how to load services that don't implement Service")
    }
  }
}

@Singleton
class ServiceClientProvider[T](interface: Class[T]) extends Provider[T] {
  @Inject private var loader: ServiceClientLoader = _
  lazy val get                                    = loader.loadServiceClient(interface)
} 
Example 172
Source File: JavadslWebSocketClient.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.client

import javax.inject.Inject
import javax.inject.Singleton

import com.lightbend.lagom.internal.client.WebSocketClient
import com.lightbend.lagom.internal.client.WebSocketClientConfig
import com.typesafe.config.Config
import io.netty.channel.EventLoopGroup
import play.api.Environment
import play.api.inject.ApplicationLifecycle

import scala.concurrent.ExecutionContext

@Singleton
class JavadslWebSocketClient(
    environment: Environment,
    config: WebSocketClientConfig,
    eventLoop: EventLoopGroup,
    lifecycle: ApplicationLifecycle
)(implicit ec: ExecutionContext)
    extends WebSocketClient(environment, config, eventLoop, lifecycle)
    with JavadslServiceApiBridge {
  // Constructor that manages its own event loop
  @Inject
  def this(environment: Environment, config: Config, applicationLifecycle: ApplicationLifecycle)(
      implicit ec: ExecutionContext
  ) = {
    this(
      environment,
      WebSocketClientConfig(config),
      WebSocketClient.createEventLoopGroup(applicationLifecycle),
      applicationLifecycle
    )
  }
} 
Example 173
Source File: CassandraReadSideImpl.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.persistence.cassandra

import java.util
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CompletionStage
import java.util.function.BiFunction
import java.util.function.Function
import java.util.function.Supplier

import javax.inject.Inject
import javax.inject.Singleton
import akka.Done
import akka.actor.ActorSystem
import com.datastax.driver.core.BoundStatement
import com.lightbend.lagom.internal.javadsl.persistence.ReadSideImpl
import com.lightbend.lagom.internal.persistence.cassandra.CassandraOffsetStore
import com.lightbend.lagom.javadsl.persistence.ReadSideProcessor.ReadSideHandler
import com.lightbend.lagom.javadsl.persistence._
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraReadSide.ReadSideHandlerBuilder
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraReadSide
import com.lightbend.lagom.javadsl.persistence.cassandra.CassandraSession
import play.api.inject.Injector


@Singleton
private[lagom] final class CassandraReadSideImpl @Inject() (
    system: ActorSystem,
    session: CassandraSession,
    offsetStore: CassandraOffsetStore,
    readSide: ReadSideImpl,
    injector: Injector
) extends CassandraReadSide {
  private val dispatcher = system.settings.config.getString("lagom.persistence.read-side.use-dispatcher")
  implicit val ec        = system.dispatchers.lookup(dispatcher)

  override def builder[Event <: AggregateEvent[Event]](eventProcessorId: String): ReadSideHandlerBuilder[Event] = {
    new ReadSideHandlerBuilder[Event] {
      import CassandraAutoReadSideHandler.Handler
      private var prepareCallback: AggregateEventTag[Event] => CompletionStage[Done] =
        tag => CompletableFuture.completedFuture(Done.getInstance())
      private var globalPrepareCallback: () => CompletionStage[Done] =
        () => CompletableFuture.completedFuture(Done.getInstance())
      private var handlers = Map.empty[Class[_ <: Event], Handler[Event]]

      override def setGlobalPrepare(callback: Supplier[CompletionStage[Done]]): ReadSideHandlerBuilder[Event] = {
        globalPrepareCallback = () => callback.get
        this
      }

      override def setPrepare(
          callback: Function[AggregateEventTag[Event], CompletionStage[Done]]
      ): ReadSideHandlerBuilder[Event] = {
        prepareCallback = callback.apply
        this
      }

      override def setEventHandler[E <: Event](
          eventClass: Class[E],
          handler: Function[E, CompletionStage[util.List[BoundStatement]]]
      ): ReadSideHandlerBuilder[Event] = {
        handlers += (eventClass -> ((event: E, offset: Offset) => handler(event)))
        this
      }

      override def setEventHandler[E <: Event](
          eventClass: Class[E],
          handler: BiFunction[E, Offset, CompletionStage[util.List[BoundStatement]]]
      ): ReadSideHandlerBuilder[Event] = {
        handlers += (eventClass -> handler.apply _)
        this
      }

      override def build(): ReadSideHandler[Event] = {
        new CassandraAutoReadSideHandler[Event](
          session,
          offsetStore,
          handlers,
          globalPrepareCallback,
          prepareCallback,
          eventProcessorId,
          dispatcher
        )
      }
    }
  }
} 
Example 174
Source File: JdbcPersistenceModule.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.javadsl.persistence.jdbc

import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton
import akka.actor.ActorSystem
import akka.actor.CoordinatedShutdown
import com.lightbend.lagom.internal.javadsl.persistence.jdbc._
import com.lightbend.lagom.internal.persistence.jdbc.SlickDbProvider
import com.lightbend.lagom.internal.persistence.jdbc.SlickOffsetStore
import com.lightbend.lagom.javadsl.persistence.PersistentEntityRegistry
import com.lightbend.lagom.spi.persistence.OffsetStore
import play.api.Configuration
import play.api.Environment
import play.api.db.DBApi
import play.api.inject.Binding
import play.api.inject.Module

import scala.concurrent.ExecutionContext

class JdbcPersistenceModule extends Module {
  override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(
    bind[SlickProvider].toProvider[GuiceSlickProvider],
    bind[JdbcReadSide].to[JdbcReadSideImpl],
    bind[PersistentEntityRegistry].to[JdbcPersistentEntityRegistry],
    bind[JdbcSession].to[JdbcSessionImpl],
    bind[SlickOffsetStore].to[JavadslJdbcOffsetStore],
    bind[OffsetStore].to(bind[SlickOffsetStore])
  )
}

@Singleton
class GuiceSlickProvider @Inject() (
    dbApi: DBApi,
    actorSystem: ActorSystem,
    coordinatedShutdown: CoordinatedShutdown
)(
    implicit ec: ExecutionContext
) extends Provider[SlickProvider] {
  lazy val get = {
    // Ensures JNDI bindings are made before we build the SlickProvider
    SlickDbProvider.buildAndBindSlickDatabases(
      dbApi,
      actorSystem.settings.config,
      coordinatedShutdown
    )
    new SlickProvider(actorSystem, coordinatedShutdown)
  }
} 
Example 175
Source File: JavadslJdbcOffsetStore.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.persistence.jdbc

import javax.inject.Inject
import javax.inject.Singleton

import akka.actor.ActorSystem
import com.lightbend.lagom.internal.persistence.ReadSideConfig
import com.lightbend.lagom.internal.persistence.jdbc.AbstractSlickOffsetStoreConfiguration
import com.lightbend.lagom.internal.persistence.jdbc.SlickOffsetStore
import com.typesafe.config.Config

import scala.concurrent.ExecutionContext
import scala.concurrent.duration.FiniteDuration


@Singleton
private[lagom] class OffsetTableConfiguration @Inject() (config: Config, readSideConfig: ReadSideConfig)
    extends AbstractSlickOffsetStoreConfiguration(config) {
  override def minBackoff: FiniteDuration           = readSideConfig.minBackoff
  override def maxBackoff: FiniteDuration           = readSideConfig.maxBackoff
  override def randomBackoffFactor: Double          = readSideConfig.randomBackoffFactor
  override def globalPrepareTimeout: FiniteDuration = readSideConfig.globalPrepareTimeout
  override def role: Option[String]                 = readSideConfig.role
  override def toString: String                     = s"OffsetTableConfiguration($tableName,$schemaName)"
}

@Singleton
private[lagom] class JavadslJdbcOffsetStore @Inject() (
    slick: SlickProvider,
    system: ActorSystem,
    tableConfig: OffsetTableConfiguration,
    readSideConfig: ReadSideConfig
)(implicit ec: ExecutionContext)
    extends SlickOffsetStore(system, slick, tableConfig) 
Example 176
Source File: JdbcSessionImpl.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.persistence.jdbc

import java.util.concurrent.CompletionStage
import javax.inject.Inject
import javax.inject.Singleton

import com.lightbend.lagom.javadsl.persistence.jdbc.JdbcSession
import com.lightbend.lagom.javadsl.persistence.jdbc.JdbcSession.ConnectionFunction

import scala.compat.java8.FutureConverters._


@Singleton
final class JdbcSessionImpl @Inject() (slick: SlickProvider) extends JdbcSession {
  import slick.profile.api._

  override def withConnection[T](block: ConnectionFunction[T]): CompletionStage[T] = {
    slick.db.run {
      SimpleDBIO { ctx =>
        block(ctx.connection)
      }
    }.toJava
  }

  override def withTransaction[T](block: ConnectionFunction[T]): CompletionStage[T] = {
    slick.db.run {
      SimpleDBIO { ctx =>
        block(ctx.connection)
      }.transactionally
    }.toJava
  }
} 
Example 177
Source File: JdbcPersistentEntityRegistry.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.persistence.jdbc

import java.util.Optional

import javax.inject.Inject
import javax.inject.Singleton
import akka.actor.ActorSystem
import akka.persistence.jdbc.query.scaladsl.JdbcReadJournal
import com.lightbend.lagom.internal.javadsl.persistence.AbstractPersistentEntityRegistry
import com.lightbend.lagom.javadsl.persistence.PersistentEntity
import play.api.inject.Injector


@Singleton
private[lagom] final class JdbcPersistentEntityRegistry @Inject() (
    system: ActorSystem,
    injector: Injector,
    slickProvider: SlickProvider
) extends AbstractPersistentEntityRegistry(system, injector) {
  private lazy val ensureTablesCreated = slickProvider.ensureTablesCreated()

  override def register[C, E, S](entityClass: Class[_ <: PersistentEntity[C, E, S]]): Unit = {
    ensureTablesCreated
    super.register(entityClass)
  }

  protected override val queryPluginId = Optional.of(JdbcReadJournal.Identifier)
} 
Example 178
Source File: AkkaManagementModule.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.server

import akka.actor.ActorSystem
import akka.actor.CoordinatedShutdown
import com.lightbend.lagom.internal.akka.management.AkkaManagementTrigger
import com.typesafe.config.Config
import javax.inject.Inject
import javax.inject.Provider
import javax.inject.Singleton
import play.api.inject.Binding
import play.api.inject.Module
import play.api.Configuration
import play.api.Environment
import play.api.Mode

import scala.concurrent.ExecutionContext

private[lagom] class AkkaManagementModule extends Module {
  override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = {
    // The trigger must be eager because it's often not required by anyone as a dependency to
    // be injected and yet it must be started anyway
    Seq(bind[AkkaManagementTrigger].toProvider[AkkaManagementProvider].eagerly())
  }
}

@Singleton
private[lagom] class AkkaManagementProvider @Inject() (
    config: Config,
    actorSystem: ActorSystem,
    coordinatedShutdown: CoordinatedShutdown,
    environment: Environment,
    executionContext: ExecutionContext
) extends Provider[AkkaManagementTrigger] {
  override def get(): AkkaManagementTrigger = {
    val instance = new AkkaManagementTrigger(config, actorSystem, coordinatedShutdown)(executionContext)
    if (environment.mode == Mode.Prod) {
      instance.start()
    }
    instance
  }
} 
Example 179
Source File: TestServiceLocator.scala    From lagom   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.testkit

import java.net.URI
import java.util.Optional
import java.util.concurrent.CompletionStage

import scala.compat.java8.FutureConverters._
import scala.concurrent.ExecutionContext
import scala.concurrent.Future
import com.lightbend.lagom.javadsl.api.Descriptor
import javax.inject.Inject
import javax.inject.Singleton

import com.lightbend.lagom.javadsl.client.CircuitBreakersPanel
import com.lightbend.lagom.javadsl.client.CircuitBreakingServiceLocator

@Singleton
private[lagom] class TestServiceLocator @Inject() (
    circuitBreakers: CircuitBreakersPanel,
    port: TestServiceLocatorPort,
    implicit val ec: ExecutionContext
) extends CircuitBreakingServiceLocator(circuitBreakers) {
  private val futureUri = port.port.map(p => URI.create("http://localhost:" + p))

  override def locate(name: String, call: Descriptor.Call[_, _]): CompletionStage[Optional[URI]] =
    futureUri.map(uri => Optional.of(uri)).toJava
}

private[lagom] final case class TestServiceLocatorPort(port: Future[Int]) 
Example 180
Source File: AppConfig.scala    From self-assessment-api   with Apache License 2.0 5 votes vote down vote up
package config

import javax.inject.{Inject, Singleton}
import play.api.{Configuration, Environment}
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig

@Singleton
class AppConfig @Inject()(val environment: Environment,
                          val configuration: Configuration,
                          config: ServicesConfig) {

  def appName: String = config.getString("appName")
  def appUrl: String = config.getString("appUrl")
  def registrationEnabled: Boolean = config.getBoolean("microservice.services.service-locator.enabled")

  def featureSwitch: Option[Configuration] = configuration.getOptional[Configuration](s"feature-switch")
  def apiStatus(version: String): String = config.getString(s"api.$version.status")
  def apiGatewayContext: String = config.getString("api.gateway.context")

  //Services
  def saApiUrl: String = config.baseUrl("self-assessment-api")
  def cgApiUrl: String = config.baseUrl("mtd-charitable-giving")
  def taxCalcUrl: String = config.baseUrl("mtd-tax-calculation")
  def propertyUrl: String = config.baseUrl("mtd-property-api")
  def selfEmploymentUrl: String = config.baseUrl("mtd-self-employment")
  def release2Enabled: Boolean = config.getBoolean("release-2.enabled")
  def dividendsApiUrl: String = config.baseUrl("mtd-dividends-income")
  def savingsAccountApiUrl: String = config.baseUrl("mtd-savings-accounts")
  def crystallisationApiUrl: String = config.baseUrl("mtd-crystallisation")

} 
Example 181
Source File: SelfAssessmentApiDefinition.scala    From self-assessment-api   with Apache License 2.0 5 votes vote down vote up
package router.definition

import config.{AppConfig, FeatureSwitch}
import javax.inject.{Inject, Singleton}
import play.api.Logger
import router.definition.APIStatus.APIStatus
import router.constants.Versions._

@Singleton
class SelfAssessmentApiDefinition @Inject()(appConfig: AppConfig) {

  private val readScope = "read:self-assessment"
  private val writeScope = "write:self-assessment"

  lazy val definition: Definition =
    Definition(
      scopes = Seq(
        Scope(
          key = readScope,
          name = "View your Self Assessment information",
          description = "Allow read access to self assessment data"
        ),
        Scope(
          key = writeScope,
          name = "Change your Self Assessment information",
          description = "Allow write access to self assessment data"
        )
      ),
      api = APIDefinition(
        name = "Self Assessment (MTD)",
        description = "An API for providing self assessment data and obtaining tax calculations",
        context = appConfig.apiGatewayContext,
        versions = Seq(
          APIVersion(
            version = VERSION_1,
            access = buildWhiteListingAccess(),
            status = buildAPIStatus(VERSION_1),
            endpointsEnabled = true),
          APIVersion(
            version = VERSION_2,
            access = buildWhiteListingAccess(),
            status = buildAPIStatus(VERSION_2),
            endpointsEnabled = true)
        ),
        requiresTrust = None
      )
    )

  private[definition] def buildAPIStatus(version: String): APIStatus = {
    appConfig.apiStatus(version) match {
      case "ALPHA" => APIStatus.ALPHA
      case "BETA" => APIStatus.BETA
      case "STABLE" => APIStatus.STABLE
      case "DEPRECATED" => APIStatus.DEPRECATED
      case "RETIRED" => APIStatus.RETIRED
      case _ => Logger.error(s"[ApiDefinition][buildApiStatus] no API Status found in config.  Reverting to Alpha")
        APIStatus.ALPHA
    }
  }

  private[definition] def buildWhiteListingAccess(): Option[Access] = {
    val featureSwitch = FeatureSwitch(appConfig.featureSwitch)
    featureSwitch.isWhiteListingEnabled match {
      case true => Some(Access("PRIVATE", featureSwitch.whiteListedApplicationIds))
      case false => None
    }
  }
} 
Example 182
Source File: DocumentationController.scala    From self-assessment-api   with Apache License 2.0 5 votes vote down vote up
package router.controllers

import controllers.Assets
import javax.inject.{Inject, Singleton}
import play.api.http.HttpErrorHandler
import play.api.libs.json.Json
import play.api.mvc.{Action, AnyContent, ControllerComponents}
import router.definition.SelfAssessmentApiDefinition
import uk.gov.hmrc.api.controllers.{DocumentationController => HmrcDocumentationController}

@Singleton
class DocumentationController @Inject()(selfAssessmentApiDefinition: SelfAssessmentApiDefinition,
                                        cc: ControllerComponents, assets: Assets, errorHandler: HttpErrorHandler)
  extends HmrcDocumentationController(cc, assets, errorHandler) {

  override def definition(): Action[AnyContent] = Action {
    Ok(Json.toJson(selfAssessmentApiDefinition.definition))
  }

  override def conf(version: String, file: String): Action[AnyContent] = {
    assets.at(s"/public/api/conf/$version", file)
  }
} 
Example 183
Source File: CouchbaseReadSideImpl.scala    From akka-persistence-couchbase   with Apache License 2.0 5 votes vote down vote up
package com.lightbend.lagom.internal.javadsl.persistence.couchbase

import java.util.concurrent.{CompletableFuture, CompletionStage}
import java.util.function.{BiFunction, Function => JFunction}

import akka.Done
import akka.actor.ActorSystem
import akka.dispatch.MessageDispatcher
import akka.stream.alpakka.couchbase.javadsl.CouchbaseSession
import com.lightbend.lagom.internal.persistence.couchbase.CouchbaseOffsetStore
import com.lightbend.lagom.javadsl.persistence.couchbase.CouchbaseReadSide
import com.lightbend.lagom.javadsl.persistence.{AggregateEvent, AggregateEventTag, Offset, ReadSideProcessor}
import javax.inject.{Inject, Singleton}
import play.api.inject.Injector

@Singleton
private[lagom] class CouchbaseReadSideImpl @Inject() (
    system: ActorSystem,
    couchbaseSession: CouchbaseSession,
    offsetStore: CouchbaseOffsetStore,
    injector: Injector
) extends CouchbaseReadSide {
  private val dispatcher = system.settings.config.getString("lagom.persistence.read-side.use-dispatcher")
  private implicit val ec: MessageDispatcher = system.dispatchers.lookup(dispatcher)

  override def builder[Event <: AggregateEvent[Event]](
      readSideId: String
  ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] =
    new CouchbaseReadSide.ReadSideHandlerBuilder[Event] {
      type Handler[E] = CouchbaseReadSideHandler.Handler[E]

      private var globalPrepareCallback: CouchbaseSession => CompletionStage[Done] =
        (_) => CompletableFuture.completedFuture(Done.getInstance())

      private var prepareCallback: (CouchbaseSession, AggregateEventTag[Event]) => CompletionStage[Done] =
        (_, _) => CompletableFuture.completedFuture(Done.getInstance())

      private var handlers = Map.empty[Class[_ <: Event], Handler[Event]]

      override def setGlobalPrepare(
          callback: JFunction[CouchbaseSession, CompletionStage[Done]]
      ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] = {
        globalPrepareCallback = callback.apply
        this
      }

      override def setPrepare(
          callback: BiFunction[CouchbaseSession, AggregateEventTag[Event], CompletionStage[Done]]
      ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] = {
        prepareCallback = callback.apply
        this
      }

      override def setEventHandler[E <: Event](
          eventClass: Class[E],
          handler: CouchbaseReadSide.TriConsumer[CouchbaseSession, E, Offset, CompletionStage[Done]]
      ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] = {
        handlers += (eventClass -> ((cs: CouchbaseSession, event: E, offset: Offset) => handler(cs, event, offset)))
        this
      }

      override def setEventHandler[E <: Event](
          eventClass: Class[E],
          handler: BiFunction[CouchbaseSession, E, CompletionStage[Done]]
      ): CouchbaseReadSide.ReadSideHandlerBuilder[Event] = {
        handlers += (eventClass -> ((cs: CouchbaseSession, event: E, offset: Offset) => handler(cs, event)))
        this
      }

      override def build(): ReadSideProcessor.ReadSideHandler[Event] =
        new CouchbaseReadSideHandler[Event](
          couchbaseSession,
          offsetStore,
          handlers,
          globalPrepareCallback,
          prepareCallback,
          readSideId,
          dispatcher
        )
    }
} 
Example 184
Source File: UnixSignalManager.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.signal

import javax.inject.Singleton

import org.apache.commons.lang3.SystemUtils
import sun.misc.{Signal, SignalHandler}

import scala.collection.mutable

@Singleton
class UnixSignalManager extends SignalManager {
  private val signals = mutable.HashMap.empty[Signal, SignalHandler]

  def register(signal: Signal, handler: SignalHandler): Unit =
    if (SystemUtils.IS_OS_UNIX) {
      if (signals.contains(signal)) {
        throw new IllegalArgumentException(s"Signal $signal is already registered")
      }

      Signal.handle(signal, handler)
      signals.put(signal, handler)
    } else {
      throw new UnsupportedOperationException("Signal handling is only supported on UNIX")
    }

  def unregister(signal: Signal): Unit =
    if (signals.contains(signal)) {
      Signal.handle(signal, new SignalHandler {
        override def handle(signal: Signal): Unit = {}
      })
      signals.remove(signal)
    }
} 
Example 185
Source File: TemplateModule.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.templates

import javax.inject.Singleton

import com.google.inject.{AbstractModule, Provides}
import de.frosner.broccoli.BroccoliConfiguration
import de.frosner.broccoli.signal.UnixSignalManager
import net.codingwell.scalaguice.ScalaModule


  @Provides
  @Singleton
  def provideTemplateSource(config: BroccoliConfiguration,
                            signalManager: UnixSignalManager,
                            templateRenderer: TemplateRenderer): TemplateSource =
    new SignalRefreshedTemplateSource(
      new CachedTemplateSource(new DirectoryTemplateSource(config.templates.path, templateRenderer)),
      signalManager
    )
} 
Example 186
Source File: JinjavaModule.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.templates.jinjava

import javax.inject.Singleton

import com.google.inject.{AbstractModule, Provides}
import com.hubspot.jinjava.JinjavaConfig
import de.frosner.broccoli.BroccoliConfiguration
import net.codingwell.scalaguice.ScalaModule


class JinjavaModule extends AbstractModule with ScalaModule {
  override def configure(): Unit = {}
  @Provides
  @Singleton
  def provideJinjavaConfig(broccoliConfiguration: BroccoliConfiguration): JinjavaConfig = {
    val config = broccoliConfiguration.templates.jinjava
    JinjavaConfig
      .newBuilder()
      .withMaxRenderDepth(config.maxRenderDepth)
      .withTrimBlocks(config.trimBlocks)
      .withLstripBlocks(config.lstripBlocks)
      .withEnableRecursiveMacroCalls(config.enableRecursiveMacroCalls)
      .withReadOnlyResolver(config.readOnlyResolver)
      .withMaxOutputSize(config.maxOutputSize)
      .withNestedInterpretationEnabled(config.nestedInterpretationEnabled)
      .withFailOnUnknownTokens(config.failOnUnknownTokens)
      .build()
  }
} 
Example 187
Source File: CachedTemplateSource.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.templates

import de.frosner.broccoli.models.Template
import javax.inject.Singleton


class CachedTemplateSource(source: TemplateSource) extends TemplateSource {
  @volatile private var templatesCache: Option[Seq[Template]] = None

  override val templateRenderer: TemplateRenderer = source.templateRenderer

  override def loadTemplates(): Seq[Template] =
    templatesCache match {
      case Some(templates) => templates
      case None =>
        refresh()
        templatesCache.get
    }

  def refresh(): Unit = templatesCache = Some(source.loadTemplates())
} 
Example 188
Source File: AboutInfoService.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.services

import javax.inject.{Inject, Singleton}

import de.frosner.broccoli.auth.{Account, AuthMode}
import de.frosner.broccoli.conf
import de.frosner.broccoli.models._

@Singleton
class AboutInfoService @Inject()(instanceService: InstanceService, securityService: SecurityService) {

  def aboutInfo(loggedIn: Account) = AboutInfo(
    project = AboutProject(
      name = de.frosner.broccoli.build.BuildInfo.name,
      version = de.frosner.broccoli.build.BuildInfo.version
    ),
    scala = AboutScala(
      version = de.frosner.broccoli.build.BuildInfo.scalaVersion
    ),
    sbt = AboutSbt(
      version = de.frosner.broccoli.build.BuildInfo.sbtVersion
    ),
    auth = AboutAuth(
      enabled = securityService.authMode != AuthMode.None,
      user = AboutUser(
        name = loggedIn.name,
        role = loggedIn.role,
        instanceRegex = loggedIn.instanceRegex
      )
    ),
    services = AboutServices(
      clusterManager = AboutClusterManager(connected = instanceService.isNomadReachable),
      serviceDiscovery = AboutServiceDiscovery(connected = instanceService.isConsulReachable)
    )
  )

} 
Example 189
Source File: SecurityService.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.services

import javax.inject.{Inject, Singleton}

import cats.data.{EitherT, OptionT}
import cats.instances.future._
import cats.syntax.either._
import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.api.services.IdentityService
import com.mohiva.play.silhouette.api.util.Credentials
import com.mohiva.play.silhouette.impl.exceptions.{IdentityNotFoundException, InvalidPasswordException}
import com.mohiva.play.silhouette.impl.providers.CredentialsProvider
import de.frosner.broccoli.auth.{Account, AuthConfiguration, AuthMode}

import scala.concurrent.{ExecutionContext, Future}

sealed trait LoginError

object LoginError {
  final case object InvalidPassword extends LoginError
  final case object UnknownUser extends LoginError
  final case object Locked extends LoginError
}

@Singleton()
case class SecurityService @Inject()(
    configuration: AuthConfiguration,
    credentialsProvider: CredentialsProvider,
    identityService: IdentityService[Account]
)(implicit ec: ExecutionContext) {

  private val log = play.api.Logger(getClass)

  val sessionTimeoutInSeconds: Int = configuration.session.timeout.toSeconds.toInt

  val allowedFailedLogins: Int = configuration.allowedFailedLogins

  val authMode: AuthMode = configuration.mode

  val cookieSecure: Boolean = configuration.cookie.secure
  val allowMultiLogin: Boolean = configuration.session.allowMultiLogin

  @volatile
  private var failedLoginAttempts: Map[String, Int] = Map.empty

  
  def authenticate(credentials: Credentials): Future[Option[LoginInfo]] =
    EitherT
      .rightT(credentials)
      .ensure(LoginError.Locked)(c => failedLoginAttempts.getOrElse(c.identifier, 0) <= allowedFailedLogins)
      .flatMapF(credentialsProvider.authenticate(_).map(_.asRight).recover {
        case _: InvalidPasswordException  => LoginError.InvalidPassword.asLeft
        case _: IdentityNotFoundException => LoginError.UnknownUser.asLeft
      })
      .leftMap { error =>
        // Login if an account was locked
        val attempts = failedLoginAttempts.getOrElse(credentials.identifier, 0)
        if (error == LoginError.Locked) {
          log.warn(
            s"Credentials for '${credentials.identifier}' exceeded the allowed number of failed logins: " +
              s"$allowedFailedLogins (has $attempts)")
        }
        // Track the failed attempt
        failedLoginAttempts = failedLoginAttempts.updated(credentials.identifier, attempts + 1)
        error
      }
      .toOption
      .value
} 
Example 190
Source File: CheckerExceptionAdapter.scala    From apalache   with Apache License 2.0 5 votes vote down vote up
package at.forsyte.apalache.tla.bmcmt.config

import at.forsyte.apalache.infra.ExceptionAdapter
import at.forsyte.apalache.tla.bmcmt._
import at.forsyte.apalache.tla.bmcmt.types.TypeInferenceError
import at.forsyte.apalache.tla.imp.src.SourceStore
import at.forsyte.apalache.tla.lir.{MalformedTlaError, TlaEx}
import at.forsyte.apalache.tla.lir.storage.{ChangeListener, SourceLocator}
import at.forsyte.apalache.tla.pp.NotInKeraError
import javax.inject.{Inject, Singleton}


@Singleton
class CheckerExceptionAdapter @Inject()(sourceStore: SourceStore,
                                        changeListener: ChangeListener) extends ExceptionAdapter {

  override def toMessage: PartialFunction[Exception, String] = {
    case err: NoRuleException =>
      "%s: no rule to rewrite a TLA+ expression: %s".format(findLoc(err.causeExpr), err.getMessage)

    case err: RewriterException =>
      "%s: rewriter error: %s".format(findLoc(err.causeExpr), err.getMessage)

    case err: SmtEncodingException =>
      "%s: error when rewriting to SMT: %s".format(findLoc(err.causeExpr), err.getMessage)

    case err: TypeException =>
      "%s: type error: %s".format(findLoc(err.causeExpr), err.getMessage)

    case err: TypeInferenceError =>
      "%s: type error: %s".format(findLoc(err.origin), err.getMessage)

    case err: InvalidTlaExException =>
      "%s: unexpected TLA+ expression: %s".format(findLoc(err.causeExpr), err.getMessage)

    case err: InternalCheckerError =>
      "%s: internal error: %s".format(findLoc(err.causeExpr), err.getMessage)

    case err: CheckerException =>
      "%s: checker error: %s".format(findLoc(err.causeExpr), err.getMessage)

    case err: NotInKeraError =>
      "%s: expression outside of KerA, report an issue: %s [see docs/kera.md]"
        .format(findLoc(err.causeExpr), err.getMessage)

    case err: MalformedTlaError =>
      "%s: unexpected TLA+ expression: %s".format(findLoc(err.causeExpr), err.getMessage)
  }

  private def findLoc(expr: TlaEx): String = {
    val sourceLocator: SourceLocator = SourceLocator(sourceStore.makeSourceMap, changeListener)

    sourceLocator.sourceOf(expr) match {
      case Some(loc) => loc.toString
      case None => "<unknown>"
    }
  }
} 
Example 191
Source File: HoconMessagesApi.scala    From play-i18n-hocon   with Apache License 2.0 5 votes vote down vote up
package com.marcospereira.play.i18n

import java.net.URL
import java.util.Properties
import javax.inject.{ Inject, Singleton }

import com.typesafe.config.ConfigFactory
import play.api.http.HttpConfiguration
import play.api.i18n._
import play.api.inject.Module
import play.api.{ Configuration, Environment }
import play.utils.Resources

import scala.collection.JavaConverters._

@Singleton
class HoconMessagesApiProvider @Inject() (
  environment: Environment,
  config: Configuration,
  langs: Langs,
  httpConfiguration: HttpConfiguration
)
    extends DefaultMessagesApiProvider(environment, config, langs, httpConfiguration) {

  override lazy val get: MessagesApi = {
    new DefaultMessagesApi(
      loadAllMessages,
      langs,
      langCookieName = langCookieName,
      langCookieSecure = langCookieSecure,
      langCookieHttpOnly = langCookieHttpOnly,
      httpConfiguration = httpConfiguration
    )
  }

  override protected def loadMessages(file: String): Map[String, String] = {
    getResources(file)
      .filterNot(url => Resources.isDirectory(environment.classLoader, url)).reverse
      .map(getMessages)
      .foldLeft(Map.empty[String, String]) { _ ++ _ }
  }

  override protected def loadAllMessages: Map[String, Map[String, String]] = {
    langs.availables.map(_.code).map { lang =>
      (lang, loadMessages(s"messages.$lang.conf"))
    }.toMap ++ Map(
      "default" -> loadMessages("messages.conf"),
      "default.play" -> loadMessages("messages.default")
    )
  }

  override protected def joinPaths(first: Option[String], second: String) = first match {
    case Some(parent) => new java.io.File(parent, second).getPath
    case None => second
  }

  private def getResources(file: String): List[URL] = {
    environment.classLoader.getResources(joinPaths(messagesPrefix, file)).asScala.toList
  }

  private def getMessages(url: URL): Map[String, String] = {
    // messages.default is bundled with play and it is a properties file
    val config = if (url.toString.endsWith("messages.default")) {
      ConfigFactory.parseProperties(getProperties(url))
    } else {
      ConfigFactory.parseURL(url)
    }

    config.resolve().entrySet().asScala
      .map(e => e.getKey -> String.valueOf(e.getValue.unwrapped()))
      .toMap
  }

  private def getProperties(url: URL): Properties = {
    val properties = new Properties()
    val input = url.openStream()
    try {
      properties.load(input)
    } finally {
      input.close()
    }
    properties
  }
}


trait HoconI18nComponents extends I18nComponents {

  def environment: Environment
  def configuration: Configuration
  def httpConfiguration: HttpConfiguration
  def langs: Langs

  override lazy val messagesApi: MessagesApi = new HoconMessagesApiProvider(environment, configuration, langs, httpConfiguration).get
} 
Example 192
Source File: HatDatabaseProvider.scala    From HAT2.0   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.hatdex.hat.resourceManagement

import javax.inject.{ Inject, Singleton }

import com.typesafe.config.{ Config, ConfigFactory }
import org.hatdex.hat.dal.HatDbSchemaMigration
import org.hatdex.hat.resourceManagement.models.HatSignup
import org.hatdex.libs.dal.HATPostgresProfile.api.Database
import play.api.cache.AsyncCacheApi
import play.api.libs.ws.WSClient
import play.api.{ Configuration, Logger }

import scala.concurrent.{ ExecutionContext, Future }
import scala.collection.JavaConverters._
import scala.concurrent.duration.Duration

trait HatDatabaseProvider {
  protected val configuration: Configuration

  def database(hat: String)(implicit ec: ExecutionContext): Future[Database]

  def shutdown(db: Database): Future[Unit] = {
    // Execution context for the future is defined by specifying the executor during initialisation

    db.shutdown
  }

  def update(db: Database)(implicit ec: ExecutionContext): Future[Unit] = {
    new HatDbSchemaMigration(configuration, db, ec).run("hat.schemaMigrations")
  }
}

@Singleton
class HatDatabaseProviderConfig @Inject() (val configuration: Configuration) extends HatDatabaseProvider {
  def database(hat: String)(implicit ec: ExecutionContext): Future[Database] = {
    Future {
      Database.forConfig(s"hat.${hat.replace(':', '.')}.database", configuration.underlying)
    } recoverWith {
      case e =>
        Future.failed(new HatServerDiscoveryException(s"Database configuration for $hat incorrect or unavailable", e))
    }
  }
}

@Singleton
class HatDatabaseProviderMilliner @Inject() (
    val configuration: Configuration,
    val cache: AsyncCacheApi,
    val ws: WSClient) extends HatDatabaseProvider with MillinerHatSignup {
  val logger = Logger(this.getClass)

  def database(hat: String)(implicit ec: ExecutionContext): Future[Database] = {
    getHatSignup(hat) map { signup =>
      val config = signupDatabaseConfig(signup)
      //      val databaseUrl = s"jdbc:postgresql://${signup.databaseServer.get.host}:${signup.databaseServer.get.port}/${signup.database.get.name}"
      //      val executor = AsyncExecutor(hat, numThreads = 3, queueSize = 1000)
      //      Database.forURL(databaseUrl, signup.database.get.name, signup.database.get.password, driver = "org.postgresql.Driver"  )
      Database.forConfig("", config)
    }
  }

  def signupDatabaseConfig(signup: HatSignup): Config = {
    val database = signup.database.get
    val config = Map(
      "dataSourceClass" -> "org.postgresql.ds.PGSimpleDataSource",
      "properties" -> Map[String, String](
        "user" -> database.name,
        "password" -> database.password,
        "databaseName" -> database.name,
        "portNumber" -> signup.databaseServer.get.port.toString,
        "serverName" -> signup.databaseServer.get.host).asJava,
      "numThreads" -> configuration.get[Int]("resourceManagement.hatDBThreads").toString,
      "idleTimeout" -> configuration.get[Duration]("resourceManagement.hatDBIdleTimeout").toMillis.toString).asJava

    ConfigFactory.parseMap(config)
  }
} 
Example 193
Source File: HatServerProvider.scala    From HAT2.0   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.hatdex.hat.resourceManagement

import java.io.StringWriter
import java.security.interfaces.RSAPublicKey
import javax.inject.{ Inject, Named, Singleton }

import akka.actor.ActorRef
import akka.pattern.ask
import akka.util.Timeout
import com.mohiva.play.silhouette.api.services.DynamicEnvironmentProviderService
import org.bouncycastle.util.io.pem.{ PemObject, PemWriter }
import org.hatdex.hat.api.service.RemoteExecutionContext
import org.hatdex.hat.resourceManagement.actors.HatServerProviderActor
import org.hatdex.hat.utils.LoggingProvider
import play.api.cache.{ AsyncCacheApi, NamedCache }
import play.api.Configuration
import play.api.mvc.Request

import scala.concurrent.Future
import scala.concurrent.duration._

trait HatServerProvider extends DynamicEnvironmentProviderService[HatServer] {
  def retrieve[B](request: Request[B]): Future[Option[HatServer]]
  def retrieve(hatAddress: String): Future[Option[HatServer]]
  def toString(publicKey: RSAPublicKey): String = {
    val pemObject = new PemObject("PUBLIC KEY", publicKey.getEncoded)
    val stringPemWriter = new StringWriter()
    val pemWriter: PemWriter = new PemWriter(stringPemWriter)
    pemWriter.writeObject(pemObject)
    pemWriter.flush()
    val pemPublicKey = stringPemWriter.toString
    pemPublicKey
  }
}

@Singleton
class HatServerProviderImpl @Inject() (
    configuration: Configuration,
    @NamedCache("hatserver-cache") cache: AsyncCacheApi,
    loggingProvider: LoggingProvider,
    @Named("hatServerProviderActor") serverProviderActor: ActorRef)(
    implicit
    val ec: RemoteExecutionContext) extends HatServerProvider {

  private val logger = loggingProvider.logger(this.getClass)

  def retrieve[B](request: Request[B]): Future[Option[HatServer]] = {
    val hatAddress = request.host //.split(':').headOption.getOrElse(request.host)
    retrieve(hatAddress)
  }

  implicit val timeout: Timeout = configuration.get[FiniteDuration]("resourceManagement.serverProvisioningTimeout")
  implicit val serverInfoTimeout: Duration = configuration.get[FiniteDuration]("resourceManagement.serverIdleTimeout")

  def retrieve(hatAddress: String): Future[Option[HatServer]] = {
    cache.get[HatServer](s"server:$hatAddress")
      .flatMap {
        case Some(server) => Future.successful(Some(server))
        case _ =>
          (serverProviderActor ? HatServerProviderActor.HatServerRetrieve(hatAddress)) map {
            case server: HatServer =>
              logger.debug(s"Got back server $server")
              cache.set(s"server:$hatAddress", server, serverInfoTimeout)
              Some(server)
            case error: HatServerDiscoveryException =>
              logger.warn(s"Got back error $error")
              throw error
            case message =>
              logger.warn(s"Unknown message $message from HAT Server provider actor")
              val error = new HatServerDiscoveryException("Unknown message")
              throw error
          } recoverWith {
            case e =>
              logger.warn(s"Error while retrieving HAT $hatAddress info: ${e.getMessage}")
              val error = new HatServerDiscoveryException("HAT Server info retrieval failed", e)
              throw error
          }
      }
  }

} 
Example 194
Source File: LoggingFilter.scala    From HAT2.0   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.hatdex.hat.utils

import javax.inject.{ Inject, Singleton }
import akka.stream.Materializer
import com.nimbusds.jose.JWSObject
import com.nimbusds.jwt.JWTClaimsSet
import play.api.http.HttpErrorHandler
import play.api.mvc.{ Filter, RequestHeader, Result }
import play.api.{ Configuration, Logger }

import scala.concurrent.{ ExecutionContext, Future }
import scala.util.Try

@Singleton
class ActiveHatCounter() {
  // Careful! Mutable state
  private var count: Long = 0

  def get(): Long = count
  def increase(): Unit = this.synchronized(count += 1)
  def decrease(): Unit = this.synchronized(count -= 1)
}

class LoggingFilter @Inject() (
    errorHandler: HttpErrorHandler,
    configuration: Configuration,
    hatCounter: ActiveHatCounter)(
    implicit
    ec: ExecutionContext,
    val mat: Materializer) extends Filter {
  private val logger = Logger("api")

  def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader): Future[Result] = {

    val startTime = System.currentTimeMillis

    nextFilter(requestHeader)
      .recoverWith({
        case e ⇒ errorHandler.onServerError(requestHeader, e)
      })
      .map { result =>
        val active = hatCounter.get()
        val requestTime = System.currentTimeMillis - startTime
        logger.info(s"[${requestHeader.remoteAddress}] [${requestHeader.method}:${requestHeader.host}:${requestHeader.uri}] " +
          s"[${result.header.status}] [$requestTime:ms] [hats:$active] ${tokenInfo(requestHeader)}")

        result.withHeaders("Request-Time" -> requestTime.toString)
      }
  }

  private val authTokenFieldName: String = configuration.get[String]("silhouette.authenticator.fieldName")
  private def tokenInfo(requestHeader: RequestHeader): String = {
    requestHeader.queryString.get(authTokenFieldName).flatMap(_.headOption)
      .orElse(requestHeader.headers.get(authTokenFieldName))
      .flatMap(t ⇒ if (t.isEmpty) { None } else { Some(t) })
      .flatMap(t ⇒ Try(JWSObject.parse(t)).toOption)
      .map(o ⇒ JWTClaimsSet.parse(o.getPayload.toJSONObject))
      .map { claimSet =>
        s"[${Option(claimSet.getStringClaim("application")).getOrElse("api")}@" +
          s"${Option(claimSet.getStringClaim("applicationVersion")).getOrElse("_")}]"
      }
      .getOrElse("[unauthenticated@_]")
  }
} 
Example 195
Source File: FakeCache.scala    From HAT2.0   with GNU Affero General Public License v3.0 5 votes vote down vote up
package org.hatdex.hat

import akka.Done
import javax.inject.Singleton
import play.api.cache.AsyncCacheApi

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scala.concurrent.duration.Duration
import scala.reflect.ClassTag

@Singleton
class FakeCache extends AsyncCacheApi {

  private var store = Map[String, Any]()

  override def set(key: String, value: Any, expiration: Duration): Future[Done] =
    Future(store = store + (key -> value)).map(_ => Done)

  override def get[T](key: String)(implicit evidence$2: ClassTag[T]): Future[Option[T]] =
    Future(store.get(key).asInstanceOf[Option[T]])

  override def getOrElseUpdate[A](key: String, expiration: Duration)(orElse: => Future[A])(implicit evidence$1: ClassTag[A]): Future[A] =
    Future(store.get(key).asInstanceOf[Option[A]])
      .flatMap(_.map(Future.successful(_)).getOrElse(orElse))

  override def remove(key: String): Future[Done] =
    Future(store = store - key).map(_ => Done)

  override def removeAll(): Future[Done] =
    Future(store = Map[String, Any]()).map(_ => Done)
} 
Example 196
Source File: LoginController.scala    From Scala-Reactive-Programming   with MIT License 5 votes vote down vote up
package controllers

import javax.inject.Singleton
import com.google.inject.Inject
import forms.UserData
import play.api._
import play.api.mvc._
import play.api.i18n.Messages.Implicits._
import play.api.Play.current
import services.LoginService

import scala.concurrent.ExecutionContext

@Singleton
class LoginController @Inject()(loginService:LoginService)(cc:MessagesControllerComponents)
                               (implicit executionContext: ExecutionContext)
  extends MessagesAbstractController(cc) {

  def showLoginPage: Action[AnyContent] = Action {
    implicit  request =>
      Ok(views.html.loginPage(UserData.form))
  }

  def submitLogin = Action {
    implicit request =>
      UserData.form.bindFromRequest().fold(
        formWithErrors => {
          BadRequest(views.html.loginPage(formWithErrors))
        },
        user => {
          val isValidUser = loginService.checkLogin(user)
          if(isValidUser)
            Redirect(routes.LoginController.homePage).flashing("loginStatus" -> "User logged-in successfully.")
          else
            Ok(views.html.loginPage(UserData.form))
        }
      )
  }

  def homePage = Action{
    implicit request =>
      Ok(views.html.homePage())
  }
} 
Example 197
Source File: ServicesRoutesCache.scala    From CM-Well   with Apache License 2.0 5 votes vote down vote up
package logic.services

import akka.actor.ActorSystem
import cmwell.domain.{DeletedInfoton, Infoton, ObjectInfoton}
import cmwell.fts.PathFilter
import cmwell.ws.Settings
import com.typesafe.scalalogging.LazyLogging
import javax.inject.{Inject, Singleton}
import logic.CRUDServiceFS

import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Failure, Success, Try}

@Singleton
class ServicesRoutesCache @Inject()(crudService: CRUDServiceFS)(implicit ec: ExecutionContext, sys: ActorSystem) extends LazyLogging {
  private var services: Map[String, ServiceDefinition] = Map.empty
  private val (initialDelay, interval) = Settings.servicesRoutesCacheInitialDelay -> Settings.servicesRoutesCacheRefreshInterval

  sys.scheduler.schedule(initialDelay, interval)(populate())

  def find(path: String): Option[ServiceDefinition] =
    services.values.find(sd => path.startsWith(sd.route))

  def list: Set[String] = services.values.map(_.route).toSet

  def populate(): Future[Unit] = {
    //TODO use consume API, don't get everything each time
    crudService.search(Some(PathFilter("/meta/services", descendants = false)), withData = true, withDeleted = true).andThen {
      case Success(sr) =>
        val toAddOrUpdate = sr.infotons.collect { case oi: ObjectInfoton => oi }
        val toRemove = sr.infotons.collect { case di: DeletedInfoton => di }

        toAddOrUpdate.map(desrialize).
          collect { case Success(se) => se }.
          foreach { se => services += se.infotonPath -> se.serviceDefinition }

        toRemove.foreach(services -= _.systemFields.path)

      case Failure(t) => logger.error("Could not load Services from /meta/services", t)
    }.map(_ => ())
  }

  private def desrialize(infoton: Infoton): Try[ServiceEntry] = Try {
    val fields = infoton.fields.getOrElse(throw new RuntimeException(s"Infoton with no fields was not expected (path=${infoton.systemFields.path})"))

    def field(name: String): String = fields(name).head.value.toString

    val route = field("route")
    field("type.lzN1FA") match {
      case "cmwell://meta/sys#Redirection" =>
        val sourcePattern = field("sourcePattern")
        val replacement = field("replacement")
        val replceFunc = (input: String) => sourcePattern.r.replaceAllIn(input, replacement)
        ServiceEntry(infoton.systemFields.path, RedirectionService(route, sourcePattern, replceFunc))
      case "cmwell://meta/sys#Source" => ??? //TODO implement the unimplemented
      case "cmwell://meta/sys#Binary" => ??? //TODO implement the unimplemented
      case other => throw new RuntimeException(s"Infoton with type $other was not expected (path=${infoton.systemFields.path})")
    }
  }

  case class ServiceEntry(infotonPath: String, serviceDefinition: ServiceDefinition)
} 
Example 198
Source File: GameInfoDatabase.scala    From lila-openingexplorer   with GNU Affero General Public License v3.0 5 votes vote down vote up
package lila.openingexplorer

import fm.last.commons.kyoto.factory.{ Compressor, PageComparator }
import javax.inject.{ Inject, Singleton }
import akka.actor.CoordinatedShutdown

@Singleton
final class GameInfoDatabase @Inject() (
    config: Config,
    shutdown: CoordinatedShutdown
)(implicit ec: scala.concurrent.ExecutionContext) {

  private val db = Util.wrapLog(
    "Loading gameInfo database...",
    "GameInfo database loaded!"
  ) {
    Kyoto
      .builder(config.explorer.gameInfo.kyoto)
      .compressor(Compressor.LZMA)
      .pageComparator(PageComparator.LEXICAL)
      .buildAndOpen
  }

  def get(gameId: String): Option[GameInfo] =
    Option(db.get(gameId)) flatMap GameInfoDatabase.unpack

  def contains(gameId: String): Boolean = db.exists(gameId)

  def store(gameId: String, info: GameInfo): Boolean =
    db.putIfAbsent(gameId, GameInfoDatabase pack info)

  def count = db.recordCount()

  shutdown.addTask(CoordinatedShutdown.PhaseServiceStop, "close master db") { () =>
    scala.concurrent.Future {
      db.close()
      akka.Done
    }
  }
}

object GameInfoDatabase {

  def pack(info: GameInfo): String =
    List(
      info.white.name,
      info.white.rating,
      info.black.name,
      info.black.rating,
      info.year.fold("?")(_.toString)
    ) mkString "|"

  def unpack(str: String): Option[GameInfo] = str split '|' match {
    case Array(wn, wrS, bn, brS, yearS) =>
      for {
        wr <- wrS.toIntOption
        br <- brS.toIntOption
        year = yearS.toIntOption
      } yield GameInfo(
        white = GameInfo.Player(wn, wr),
        black = GameInfo.Player(bn, br),
        year = year
      )
    case _ => None
  }
} 
Example 199
Source File: PgnDatabase.scala    From lila-openingexplorer   with GNU Affero General Public License v3.0 5 votes vote down vote up
package lila.openingexplorer

import akka.actor.CoordinatedShutdown
import fm.last.commons.kyoto.factory.{ Compressor, PageComparator }
import javax.inject.{ Inject, Singleton }

import chess.format.Forsyth
import chess.format.pgn.{ Move, ParsedPgn, Pgn, Tag, TagType, Tags, Turn }
import chess.Replay

@Singleton
final class PgnDatabase @Inject() (
    config: Config,
    shutdown: CoordinatedShutdown
)(implicit ec: scala.concurrent.ExecutionContext) {

  private val db = Util.wrapLog(
    "Loading PGN database...",
    "PGN database loaded!"
  ) {
    Kyoto
      .builder(config.explorer.pgn.kyoto)
      .compressor(Compressor.LZMA)
      .pageComparator(PageComparator.LEXICAL)
      .buildAndOpen
  }

  private val relevantTags: Set[TagType] =
    Tag.tagTypes.toSet diff Set(Tag.ECO, Tag.Opening, Tag.Variant)

  def get(gameId: String): Option[String] = Option(db.get(gameId))

  def store(gameId: String, parsed: ParsedPgn, replay: Replay): Boolean = {

    val tags = parsed.tags.value.filter { tag => relevantTags contains tag.name }
    val fenSituation = tags find (_.name == Tag.FEN) flatMap {
      case Tag(_, fen) => Forsyth <<< fen
    }
    val pgnMoves = replay.chronoMoves
      .foldLeft(replay.setup) {
        case (game, moveOrDrop) => moveOrDrop.fold(game.apply, game.applyDrop)
      }
      .pgnMoves
    val moves       = if (fenSituation.exists(_.situation.color.black)) ".." +: pgnMoves else pgnMoves
    val initialTurn = fenSituation.map(_.fullMoveNumber) getOrElse 1
    val pgn         = Pgn(Tags(tags), turns(moves, initialTurn))

    db.putIfAbsent(gameId, pgn.toString)
  }

  private def turns(moves: Vector[String], from: Int): List[Turn] =
    (moves grouped 2).zipWithIndex.toList map {
      case (moves, index) =>
        Turn(
          number = index + from,
          white = moves.headOption filter (".." !=) map { Move(_) },
          black = moves lift 1 map { Move(_) }
        )
    } filterNot (_.isEmpty)

  def delete(gameId: String) = db.remove(gameId)

  def count = db.recordCount()

  shutdown.addTask(CoordinatedShutdown.PhaseServiceStop, "close master db") { () =>
    scala.concurrent.Future {
      db.close()
      akka.Done
    }
  }
} 
Example 200
Source File: Config.scala    From lila-openingexplorer   with GNU Affero General Public License v3.0 5 votes vote down vote up
package lila.openingexplorer

import io.methvin.play.autoconfig._
import play.api._
import javax.inject.{ Inject, Singleton }
import scala.concurrent.duration._

import chess.variant._

@Singleton
final class Config @Inject() (conf: Configuration) {

  import Config._

  lazy val explorer = conf.get[Explorer]("explorer")
}
object Config {

  case class Explorer(
      master: Domain,
      lichess: Lichess,
      pgn: Pgn,
      gameInfo: GameInfo,
      corsHeader: Boolean,
      cache: Cache
  )
  implicit val explorerLoader: ConfigLoader[Explorer] = AutoConfig.loader

  case class Cache(
      maxMoves: Int,
      ttl: FiniteDuration
  )
  implicit val cacheLoader: ConfigLoader[Cache] = AutoConfig.loader

  case class Domain(
      maxPlies: Int,
      kyoto: Kyoto
  )
  implicit val domainLoader: ConfigLoader[Domain] = AutoConfig.loader

  case class Pgn(kyoto: Kyoto)
  implicit val pgnLoader: ConfigLoader[Pgn] = AutoConfig.loader

  case class GameInfo(kyoto: Kyoto)
  implicit val gameInfoLoader: ConfigLoader[GameInfo] = AutoConfig.loader

  case class Kyoto(
      file: String,
      buckets: Long,
      defragUnitSize: Int,
      memoryMapSize: Long
  )
  implicit val kyotoLoader: ConfigLoader[Kyoto] = AutoConfig.loader

  case class Lichess(
      standard: Domain,
      chess960: Domain,
      kingOfTheHill: Domain,
      threeCheck: Domain,
      antichess: Domain,
      atomic: Domain,
      horde: Domain,
      racingKings: Domain,
      crazyhouse: Domain
  ) {

    def apply(variant: Variant): Domain = variant match {
      case Standard      => standard
      case Chess960      => chess960
      case KingOfTheHill => kingOfTheHill
      case ThreeCheck    => threeCheck
      case Antichess     => antichess
      case Atomic        => atomic
      case Horde         => horde
      case RacingKings   => racingKings
      case Crazyhouse    => crazyhouse
    }
  }
  implicit val lichessLoader: ConfigLoader[Lichess] = AutoConfig.loader
}