From bda2247bf24811654132399a9e3b3cf16f760753 Mon Sep 17 00:00:00 2001 From: To-om Date: Mon, 18 May 2020 18:09:14 +0200 Subject: [PATCH] #1318 Webhook: change format version 0 to be equivalent to TH3 (version 1 add parent objects) --- .../notification/notifiers/Webhook.scala | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/thehive/app/org/thp/thehive/services/notification/notifiers/Webhook.scala b/thehive/app/org/thp/thehive/services/notification/notifiers/Webhook.scala index 8c04491032..6397263db7 100644 --- a/thehive/app/org/thp/thehive/services/notification/notifiers/Webhook.scala +++ b/thehive/app/org/thp/thehive/services/notification/notifiers/Webhook.scala @@ -1,4 +1,5 @@ package org.thp.thehive.services.notification.notifiers + import akka.stream.Materializer import gremlin.scala.Graph import javax.inject.{Inject, Singleton} @@ -7,10 +8,11 @@ import org.thp.scalligraph.BadConfigurationError import org.thp.scalligraph.models.Entity import org.thp.scalligraph.services.config.{ApplicationConfig, ConfigItem} import org.thp.scalligraph.steps.StepsOps._ +import org.thp.scalligraph.steps.{BranchCase, BranchOtherwise, Traversal, VertexSteps} import org.thp.thehive.controllers.v0.AuditRenderer import org.thp.thehive.controllers.v0.Conversion.fromObjectType import org.thp.thehive.models.{Audit, Organisation, User} -import org.thp.thehive.services.AuditSrv +import org.thp.thehive.services.{AuditSrv, AuditSteps, _} import play.api.libs.json.Json.WithDefaultValues import play.api.libs.json.{Format, JsObject, JsValue, Json} import play.api.{Configuration, Logger} @@ -60,10 +62,61 @@ class Webhook(config: WebhookNotification, auditSrv: AuditSrv, mat: Materializer lazy val logger: Logger = Logger(getClass) + object v0 extends AuditRenderer + + object v1 { + import org.thp.thehive.controllers.v0.Conversion._ + def caseToJson: VertexSteps[_ <: Product] => Traversal[JsValue, JsValue] = + _.asCase.richCaseWithoutPerms.map(_.toJson) + + def taskToJson: VertexSteps[_ <: Product] => Traversal[JsValue, JsValue] = + _.asTask.richTask.map(_.toJson) + + def alertToJson: VertexSteps[_ <: Product] => Traversal[JsValue, JsValue] = + _.asAlert.richAlert.map(_.toJson) + + def logToJson: VertexSteps[_ <: Product] => Traversal[JsValue, JsValue] = + _.asLog.richLog.map(_.toJson) + + def observableToJson: VertexSteps[_ <: Product] => Traversal[JsValue, JsValue] = + _.asObservable.richObservable.map(_.toJson) + + def auditRenderer: AuditSteps => Traversal[JsValue, JsValue] = + (_: AuditSteps) + .coalesce[JsValue]( + _.`object` + .choose( + on = _.label, + BranchCase("Case", caseToJson), + BranchCase("Task", taskToJson), + BranchCase("Log", logToJson), + BranchCase("Observable", observableToJson), + BranchCase("Alert", alertToJson), + BranchOtherwise(_.constant(JsObject.empty)) + ), + _.constant(JsObject.empty) + ) + } + def buildMessage(version: Int, audit: Audit with Entity)(implicit graph: Graph): Try[JsObject] = version match { case 0 => - auditSrv.get(audit).richAuditWithCustomRenderer(new AuditRenderer {}.auditRenderer).getOrFail().map { + auditSrv.get(audit).richAuditWithCustomRenderer(v0.auditRenderer).getOrFail().map { + case (audit, obj) => + Json.obj( + "operation" -> audit.action, + "details" -> audit.details.fold[JsValue](JsObject.empty)(Json.parse), + "objectType" -> fromObjectType(audit.objectType.getOrElse(audit.context._model.label)), + "objectId" -> audit.objectId, + "base" -> audit.mainAction, + "startDate" -> audit._createdAt, + "rootId" -> audit.context._id, + "requestId" -> audit.requestId, + "object" -> obj + ) + } + case 1 => + auditSrv.get(audit).richAuditWithCustomRenderer(v1.auditRenderer).getOrFail().map { case (audit, obj) => Json.obj( "operation" -> audit.action,