Skip to content

Commit

Permalink
Update elastic4play
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Oct 28, 2020
1 parent aa3ebde commit bf5e922
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 65 deletions.
107 changes: 58 additions & 49 deletions app/org/thp/cortex/controllers/AttachmentCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@ 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 javax.inject.{Inject, Singleton}
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.controllers.Authenticated
import org.elastic4play.models.AttachmentAttributeFormat
import org.elastic4play.services.AttachmentSrv
import org.elastic4play.services.{AttachmentSrv, ExecutionContextSrv}
import org.thp.cortex.models.Roles
import play.api.http.HttpEntity
import play.api.libs.Files.DefaultTemporaryFileCreator
import play.api.mvc._
import play.api.{mvc, Configuration}

/**
* Controller used to access stored attachments (plain or zipped)
Expand All @@ -30,7 +28,7 @@ class AttachmentCtrl(
attachmentSrv: AttachmentSrv,
authenticated: Authenticated,
components: ControllerComponents,
renderer: Renderer
executionContextSrv: ExecutionContextSrv
) extends AbstractController(components) {

@Inject() def this(
Expand All @@ -39,9 +37,9 @@ class AttachmentCtrl(
attachmentSrv: AttachmentSrv,
authenticated: Authenticated,
components: ControllerComponents,
renderer: Renderer
executionContextSrv: ExecutionContextSrv
) =
this(configuration.get[String]("datastore.attachment.password"), tempFileCreator, attachmentSrv, authenticated, components, renderer)
this(configuration.get[String]("datastore.attachment.password"), tempFileCreator, attachmentSrv, authenticated, components, executionContextSrv)

/**
* Download an attachment, identified by its hash, in plain format
Expand All @@ -50,16 +48,25 @@ class AttachmentCtrl(
*/
@Timed("controllers.AttachmentCtrl.download")
def download(hash: String, name: Option[String]): Action[AnyContent] = authenticated(Roles.read) { _ =>
if (hash.startsWith("{{")) // angularjs hack
NoContent
else if (!name.getOrElse("").intersect(AttachmentAttributeFormat.forbiddenChar).isEmpty)
mvc.Results.BadRequest("File name is invalid")
else
Result(
header = ResponseHeader(200, Map("Content-Disposition" -> s"""attachment; filename="${URLEncoder
.encode(name.getOrElse(hash), "utf-8")}"""", "Content-Transfer-Encoding" -> "binary")),
body = HttpEntity.Streamed(attachmentSrv.source(hash), None, None)
)
executionContextSrv.withDefault { implicit ec =>
if (hash.startsWith("{{")) // angularjs hack
NoContent
else if (!name.getOrElse("").intersect(AttachmentAttributeFormat.forbiddenChar).isEmpty)
mvc.Results.BadRequest("File name is invalid")
else
Result(
header = ResponseHeader(
200,
Map(
"Content-Disposition" ->
s"""attachment; filename="${URLEncoder
.encode(name.getOrElse(hash), "utf-8")}"""",
"Content-Transfer-Encoding" -> "binary"
)
),
body = HttpEntity.Streamed(attachmentSrv.source(hash), None, None)
)
}
}

/**
Expand All @@ -69,33 +76,35 @@ class AttachmentCtrl(
*/
@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)
executionContextSrv.withDefault { implicit ec =>
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"))
)
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"))
)
}
}
}
}
31 changes: 17 additions & 14 deletions app/org/thp/cortex/services/OrganizationSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@ package org.thp.cortex.services

import javax.inject.{Inject, Singleton}

import scala.concurrent.Future
import scala.concurrent.{ExecutionContext, 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._
Expand All @@ -38,38 +35,44 @@ class OrganizationSrv(
deleteSrv: DeleteSrv,
createSrv: CreateSrv,
cache: AsyncCacheApi
) = this(config.get[Duration]("cache.organization"), organizationModel, getSrv, updateSrv, findSrv, deleteSrv, createSrv, cache)
) =
this(config.get[Duration]("cache.organization"), organizationModel, getSrv, updateSrv, findSrv, deleteSrv, createSrv, cache)

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

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

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

def update(orgId: String, fields: Fields, modifyConfig: ModifyConfig)(implicit Context: AuthContext): Future[Organization] = {
def update(orgId: String, fields: Fields, modifyConfig: ModifyConfig)(implicit Context: AuthContext, ec: ExecutionContext): 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] =
def update(organization: Organization, fields: Fields)(implicit Context: AuthContext, ec: ExecutionContext): Future[Organization] =
update(organization, fields, ModifyConfig.default)

def update(organization: Organization, fields: Fields, modifyConfig: ModifyConfig)(implicit Context: AuthContext): Future[Organization] = {
def update(organization: Organization, fields: Fields, modifyConfig: ModifyConfig)(
implicit Context: AuthContext,
ec: ExecutionContext
): Future[Organization] = {
cache.remove(s"org-${organization.id}")
updateSrv(organization, fields, modifyConfig)
}

def delete(orgId: String)(implicit Context: AuthContext): Future[Organization] = {
def delete(orgId: String)(implicit Context: AuthContext, ec: ExecutionContext): 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]) =
def find(queryDef: QueryDef, range: Option[String], sortBy: Seq[String])(
implicit ec: ExecutionContext
): (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: _*)
def stats(queryDef: QueryDef, aggs: Seq[Agg])(implicit ec: ExecutionContext): Future[JsObject] = findSrv(organizationModel, queryDef, aggs: _*)
}
4 changes: 2 additions & 2 deletions project/Dependencies.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sbt._

object Dependencies {
val scalaVersion = "2.12.8"
val scalaVersion = "2.12.12"

object Play {
val version = play.core.PlayVersion.current
Expand All @@ -18,7 +18,7 @@ object Dependencies {

val reflections = "org.reflections" % "reflections" % "0.9.11"
val zip4j = "net.lingala.zip4j" % "zip4j" % "1.3.2"
val elastic4play = "org.thehive-project" %% "elastic4play" % "1.12.1"
val elastic4play = "org.thehive-project" %% "elastic4play" % "1.12.2"
val dockerClient = "com.spotify" % "docker-client" % "8.14.4"
val akkaCluster = "com.typesafe.akka" %% "akka-cluster" % play.core.PlayVersion.akkaVersion
}

0 comments on commit bf5e922

Please sign in to comment.