Skip to content

Commit

Permalink
#52 Add export status in case stats. Add MISP server in TheHive status
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Aug 28, 2017
1 parent 5379580 commit 7696ded
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 130 deletions.
23 changes: 21 additions & 2 deletions thehive-backend/app/models/Case.scala
Expand Up @@ -4,15 +4,16 @@ import java.util.Date
import javax.inject.{ Inject, Provider, Singleton }

import models.JsonFormat.{ caseImpactStatusFormat, caseResolutionStatusFormat, caseStatusFormat }

import org.elastic4play.JsonFormat.dateFormat
import org.elastic4play.models.{ AttributeDef, BaseEntity, EntityDef, HiveEnumeration, ModelDef, AttributeFormat F, AttributeOption O }
import org.elastic4play.services.{ FindSrv, SequenceSrv }
import play.api.Logger
import play.api.libs.json.JsValue.jsValueToJsLookup
import play.api.libs.json.Json.toJsFieldJsValueWrapper
import play.api.libs.json._
import services.{ AuditedModel, CaseSrv }

import services.{ AuditedModel, CaseSrv }
import scala.concurrent.{ ExecutionContext, Future }
import scala.math.BigDecimal.{ int2bigDecimal, long2bigDecimal }

Expand Down Expand Up @@ -57,6 +58,7 @@ class CaseModel @Inject() (
artifactModel: Provider[ArtifactModel],
taskModel: Provider[TaskModel],
caseSrv: Provider[CaseSrv],
alertModel: Provider[AlertModel],
sequenceSrv: SequenceSrv,
findSrv: FindSrv,
implicit val ec: ExecutionContext) extends ModelDef[CaseModel, Case]("case") with CaseAttributes with AuditedModel { caseModel
Expand Down Expand Up @@ -140,16 +142,33 @@ class CaseModel @Inject() (
case _ Json.obj()
}
}

private[models] def buildAlertStats(caze: Case): Future[JsObject] = {
import org.elastic4play.services.QueryDSL._
findSrv(
alertModel.get,
"case" ~= caze.id,
groupByField("type", groupByField("source", selectCount)))
.map { alertStatsJson
val alertStats = for {
(tpe, JsObject(srcStats)) alertStatsJson.value
src srcStats.keys
} yield Json.obj("type" tpe, "source" src)
Json.obj("alerts" alertStats)
}
}

override def getStats(entity: BaseEntity): Future[JsObject] = {

entity match {
case caze: Case
for {
taskStats buildTaskStats(caze)
artifactStats buildArtifactStats(caze)
alertStats buildAlertStats(caze)
mergeIntoStats buildMergeIntoStats(caze)
mergeFromStats buildMergeFromStats(caze)
} yield taskStats ++ artifactStats ++ mergeIntoStats ++ mergeFromStats
} yield taskStats ++ artifactStats ++ alertStats ++ mergeIntoStats ++ mergeFromStats
case other
logger.warn(s"Request caseStats from a non-case entity ?! ${other.getClass}:$other")
Future.successful(Json.obj())
Expand Down
3 changes: 1 addition & 2 deletions thehive-misp/app/connectors/misp/JsonFormat.scala
Expand Up @@ -71,7 +71,6 @@ object JsonFormat {
"category" attribute.category,
"type" attribute.tpe,
"value" attribute.value.fold[String](identity, _.name),
"comment" attribute.comment,
"status" attribute.status)
"comment" attribute.comment)
}
}
16 changes: 10 additions & 6 deletions thehive-misp/app/connectors/misp/MispCtrl.scala
Expand Up @@ -4,32 +4,37 @@ import javax.inject.{ Inject, Singleton }

import connectors.Connector
import models.{ Alert, Case, UpdateMispAlertArtifact }

import org.elastic4play.JsonFormat.tryWrites
import org.elastic4play.controllers.Authenticated
import org.elastic4play.controllers.{ Authenticated, Renderer }
import org.elastic4play.models.JsonFormat.baseModelEntityWrites
import org.elastic4play.services._
import org.elastic4play.{ NotFoundError, Timed }
import play.api.Logger
import play.api.http.Status
import play.api.libs.json.Json
import play.api.libs.json.{ JsObject, Json }
import play.api.mvc.{ Action, AnyContent, Controller }
import play.api.routing.SimpleRouter
import play.api.routing.sird.{ GET, UrlContext }

import services.{ AlertTransformer, CaseSrv }
import connectors.misp.JsonFormat.exportedAttributeWrites

import scala.concurrent.{ ExecutionContext, Future }

@Singleton
class MispCtrl @Inject() (
mispSrv: MispSrv,
mispConfig: MispConfig,
caseSrv: CaseSrv,
authenticated: Authenticated,
renderer: Renderer,
eventSrv: EventSrv,
implicit val ec: ExecutionContext) extends Controller with Connector with Status with AlertTransformer {

override val name: String = "misp"

override val status: JsObject = Json.obj("enabled" true, "servers" mispConfig.connections.map(_.name))

private[MispCtrl] lazy val logger = Logger(getClass)
val router = SimpleRouter {
case GET(p"/_syncAlerts") syncAlerts
Expand Down Expand Up @@ -63,9 +68,8 @@ class MispCtrl @Inject() (
.get(caseId)
.flatMap { caze mispSrv.export(mispName, caze) }
.map {
case (eventId, exportedAttributes) Ok(Json.obj(
"eventId" eventId,
"attributes" exportedAttributes))
case (_, exportedAttributes)
renderer.toMultiOutput(CREATED, exportedAttributes)
}
}

Expand Down
17 changes: 16 additions & 1 deletion thehive-misp/app/connectors/misp/MispModel.scala
Expand Up @@ -2,6 +2,12 @@ package connectors.misp

import java.util.Date

import play.api.libs.json.JsObject

import models.Artifact

import org.elastic4play.services.Attachment

case class MispAlert(
source: String,
sourceRef: String,
Expand All @@ -22,4 +28,13 @@ case class MispAttribute(
date: Date,
comment: String,
value: String,
tags: Seq[String])
tags: Seq[String])

case class ExportedMispAttribute(
artifact: Artifact,
tpe: String,
category: String,
value: Either[String, Attachment],
comment: Option[String])

case class MispExportError(message: String, artifact: Artifact) extends Exception(message)

0 comments on commit 7696ded

Please sign in to comment.