Skip to content

Commit

Permalink
#1557 One CaseUpdate per alert merge
Browse files Browse the repository at this point in the history
  • Loading branch information
rriclet authored and To-om committed Oct 27, 2020
1 parent 98b044f commit d25867c
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ object Conversion {

def fromObjectType(objectType: String): String =
objectType match {
// case "Case" =>"case"
case "Task" => "case_task"
case "Log" => "case_task_log"
case "Observable" => "case_artifact"
Expand Down
30 changes: 19 additions & 11 deletions thehive/app/org/thp/thehive/services/AlertSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -271,17 +271,25 @@ class AlertSrv @Inject() (
updatedCase <- mergeInCase(alert, case0)
} yield updatedCase

def mergeInCase(alert: Alert with Entity, `case`: Case with Entity)(implicit graph: Graph, authContext: AuthContext): Try[Case with Entity] =
for {
_ <- caseSrv.addTags(`case`, get(alert).tags.toSeq.map(_.toString).toSet)
description = `case`.description + s"\n \n#### Merged with alert #${alert.sourceRef} ${alert.title}\n\n${alert.description.trim}"
c <- caseSrv.get(`case`).update(_.description, description).getOrFail("Case")
_ <- importObservables(alert, `case`)
_ <- importCustomFields(alert, `case`)
_ <- alertCaseSrv.create(AlertCase(), alert, `case`)
_ <- markAsRead(alert._id)
_ <- auditSrv.alertToCase.merge(alert, c)
} yield c
def mergeInCase(alert: Alert with Entity, `case`: Case with Entity)(implicit graph: Graph, authContext: AuthContext): Try[Case with Entity] = {
auditSrv.mergeAudits {
// No audit for markAsRead and observables
markAsRead(alert._id)
importObservables(alert, `case`)
importCustomFields(alert, `case`)

// Audits for customFields, description and tags
val customFields = get(alert).richCustomFields.toSeq.map(_.toOutput.toJson)
val description = `case`.description + s"\n \n#### Merged with alert #${alert.sourceRef} ${alert.title}\n\n${alert.description.trim}"
val tags = get(alert).tags.toSeq.map(_.toString)

caseSrv.get(`case`).update(_.description, description).getOrFail("Case")
caseSrv.addTags(`case`, tags.toSet)
Success(Json.obj("customFields" -> customFields, "description" -> description, "tags" -> tags))
} (audits => auditSrv.alertToCase.merge(alert, `case`, Some(audits)))

caseSrv.get(`case`).getOrFail("Case")
}

def importObservables(alert: Alert with Entity, `case`: Case with Entity)(implicit
graph: Graph,
Expand Down
4 changes: 2 additions & 2 deletions thehive/app/org/thp/thehive/services/AuditSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ class AuditSrv @Inject() (
def delete(entity: E with Entity, context: Option[C with Entity])(implicit graph: Graph, authContext: AuthContext): Try[Unit] =
auditSrv.create(Audit(Audit.delete, entity, None), context, None)

def merge(entity: E with Entity, destination: C with Entity)(implicit graph: Graph, authContext: AuthContext): Try[Unit] =
auditSrv.create(Audit(Audit.merge, entity), Some(destination), None)
def merge(entity: E with Entity, destination: C with Entity, details: Option[JsObject] = None)(implicit graph: Graph, authContext: AuthContext): Try[Unit] =
auditSrv.create(Audit(Audit.merge, destination, details.map(_.toString())), Some(destination), None)
}

class SelfContextObjectAudit[E <: Product] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.thp.scalligraph.traversal.{Converter, IdentityConverter, Traversal}
import org.thp.scalligraph.{BadConfigurationError, EntityIdOrName}
import org.thp.thehive.controllers.v0.AuditRenderer
import org.thp.thehive.controllers.v0.Conversion.fromObjectType
import org.thp.thehive.models.Audit._
import org.thp.thehive.models._
import org.thp.thehive.services.AlertOps._
import org.thp.thehive.services.AuditOps._
Expand Down Expand Up @@ -197,7 +198,7 @@ class Webhook(
case (audit, obj) =>
val objectType = audit.objectType.getOrElse(audit.context._label)
Json.obj(
"operation" -> audit.action,
"operation" -> v0Action(audit.action),
"details" -> audit.details.fold[JsValue](JsObject.empty)(fixCustomFieldDetails(objectType, _)),
"objectType" -> fromObjectType(objectType),
"objectId" -> audit.objectId,
Expand Down Expand Up @@ -227,6 +228,12 @@ class Webhook(
case _ => Failure(BadConfigurationError(s"Message version $version in webhook is not supported"))
}

def v0Action(action: String): String =
action match {
case Audit.merge => Audit.update
case action => action
}

override def execute(
audit: Audit with Entity,
context: Option[Entity],
Expand Down

0 comments on commit d25867c

Please sign in to comment.