diff --git a/cortex/connector/src/main/scala/org/thp/thehive/connector/cortex/controllers/v0/Conversion.scala b/cortex/connector/src/main/scala/org/thp/thehive/connector/cortex/controllers/v0/Conversion.scala index 32b7d2e32e..b6fdd9b9a9 100644 --- a/cortex/connector/src/main/scala/org/thp/thehive/connector/cortex/controllers/v0/Conversion.scala +++ b/cortex/connector/src/main/scala/org/thp/thehive/connector/cortex/controllers/v0/Conversion.scala @@ -77,7 +77,7 @@ object Conversion { _.case_artifact, jobWithParent._2.fold[Option[OutputObservable]](None) { case (richObservable, richCase) => - Some(observableWithExtraOutput.toValue((richObservable, JsObject.empty, Some(richCase)))) + Some(observableWithExtraOutput.toValue((richObservable, JsObject.empty, Some(Left(richCase))))) } ) .enableMethodAccessors diff --git a/dto/src/main/scala/org/thp/thehive/dto/v0/Observable.scala b/dto/src/main/scala/org/thp/thehive/dto/v0/Observable.scala index 02e7d4fd89..13ea1d7783 100644 --- a/dto/src/main/scala/org/thp/thehive/dto/v0/Observable.scala +++ b/dto/src/main/scala/org/thp/thehive/dto/v0/Observable.scala @@ -71,6 +71,7 @@ case class OutputObservable( stats: JsObject, seen: Option[Boolean], `case`: Option[OutputCase], + alert: Option[OutputAlert], ignoreSimilarity: Option[Boolean] ) diff --git a/thehive/app/org/thp/thehive/controllers/v0/Conversion.scala b/thehive/app/org/thp/thehive/controllers/v0/Conversion.scala index 5c4047304c..3a66b8fd87 100644 --- a/thehive/app/org/thp/thehive/controllers/v0/Conversion.scala +++ b/thehive/app/org/thp/thehive/controllers/v0/Conversion.scala @@ -408,13 +408,14 @@ object Conversion { ) .withFieldConst(_.stats, JsObject.empty) .withFieldConst(_.`case`, None) + .withFieldConst(_.alert, None) .enableMethodAccessors .transform ) - implicit val observableWithExtraOutput: Renderer.Aux[(RichObservable, JsObject, Option[RichCase]), OutputObservable] = - Renderer.toJson[(RichObservable, JsObject, Option[RichCase]), OutputObservable] { - case (richObservable, stats, richCase) => + implicit val observableWithExtraOutput: Renderer.Aux[(RichObservable, JsObject, Option[Either[RichCase, RichAlert]]), OutputObservable] = + Renderer.toJson[(RichObservable, JsObject, Option[Either[RichCase, RichAlert]]), OutputObservable] { + case (richObservable, stats, caseOrAlert) => richObservable .into[OutputObservable] .withFieldConst(_._type, "case_artifact") @@ -438,7 +439,8 @@ object Conversion { }) ) .withFieldConst(_.stats, stats) - .withFieldConst(_.`case`, richCase.map(_.toValue)) + .withFieldConst(_.`case`, caseOrAlert.flatMap(_.swap.map(_.toValue).toOption)) + .withFieldConst(_.alert, caseOrAlert.flatMap(_.map(_.toValue).toOption)) .enableMethodAccessors .transform } @@ -470,6 +472,7 @@ object Conversion { ) .withFieldConst(_.stats, stats) .withFieldConst(_.`case`, None) + .withFieldConst(_.alert, None) .enableMethodAccessors .transform } diff --git a/thehive/app/org/thp/thehive/controllers/v0/ObservableCtrl.scala b/thehive/app/org/thp/thehive/controllers/v0/ObservableCtrl.scala index c71af8ca49..5a4d08efe9 100644 --- a/thehive/app/org/thp/thehive/controllers/v0/ObservableCtrl.scala +++ b/thehive/app/org/thp/thehive/controllers/v0/ObservableCtrl.scala @@ -16,7 +16,6 @@ import org.thp.thehive.services.AlertOps._ import org.thp.thehive.services.CaseOps._ import org.thp.thehive.services.ObservableOps._ import org.thp.thehive.services.OrganisationOps._ -import org.thp.thehive.services.ShareOps._ import org.thp.thehive.services._ import play.api.Configuration import play.api.libs.Files.DefaultTemporaryFileCreator @@ -382,14 +381,25 @@ class PublicObservable @Inject() ( .richPage(from, to, withTotal = true) { case o if withStats => o.richObservableWithCustomRenderer(organisationSrv, observableStatsRenderer(organisationSrv)(authContext))(authContext) - .domainMap(ros => (ros._1, ros._2, None: Option[RichCase])) + .domainMap(ros => (ros._1, ros._2, None: Option[Either[RichCase, RichAlert]])) case o => o.richObservable.domainMap(ro => (ro, JsObject.empty, None)) } case (OutputParam(from, to, _, _), observableSteps, authContext) => observableSteps.richPage(from, to, withTotal = true)( - _.richObservableWithCustomRenderer(organisationSrv, o => o.`case`.richCase(authContext))(authContext).domainMap(roc => - (roc._1, JsObject.empty, Some(roc._2): Option[RichCase]) + _.richObservableWithCustomRenderer( + organisationSrv, + o => o.project(_.by(_.`case`.richCase(authContext).option).by(_.alert.richAlert.option)) + )(authContext).domainMap(roc => + ( + roc._1, + JsObject.empty, + roc._2 match { + case (Some(c), _) => Some(Left(c)) + case (_, Some(a)) => Some(Right(a)) + case _ => None + } + ) ) ) }