Skip to content

Commit

Permalink
#1579 Add case filter and observable type count in alert similar case…
Browse files Browse the repository at this point in the history
… query
  • Loading branch information
To-om committed Nov 13, 2020
1 parent 5a00aff commit a54ebe4
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 15 deletions.
2 changes: 1 addition & 1 deletion ScalliGraph
2 changes: 1 addition & 1 deletion thehive/app/org/thp/thehive/controllers/v0/AlertCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class AlertCtrl @Inject() (
def alertSimilarityRenderer(implicit
authContext: AuthContext
): Traversal.V[Alert] => Traversal[JsArray, JList[JMap[String, Any]], Converter[JsArray, JList[JMap[String, Any]]]] =
_.similarCases
_.similarCases(None)
.fold
.domainMap { similarCases =>
JsArray {
Expand Down
20 changes: 17 additions & 3 deletions thehive/app/org/thp/thehive/controllers/v1/AlertCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import javax.inject.{Inject, Named, Singleton}
import org.thp.scalligraph.EntityIdOrName
import org.thp.scalligraph.controllers.{Entrypoint, FieldsParser}
import org.thp.scalligraph.models.Database
import org.thp.scalligraph.query.{ParamQuery, PropertyUpdater, PublicProperties, Query}
import org.thp.scalligraph.query._
import org.thp.scalligraph.traversal.TraversalOps._
import org.thp.scalligraph.traversal.{Converter, IteratorOutput, Traversal}
import org.thp.thehive.controllers.v1.Conversion._
Expand All @@ -20,6 +20,9 @@ import org.thp.thehive.services._
import play.api.libs.json.{JsValue, Json}
import play.api.mvc.{Action, AnyContent, Results}

import scala.reflect.runtime.{universe => ru}

case class SimilarCaseFilter()
@Singleton
class AlertCtrl @Inject() (
entrypoint: Entrypoint,
Expand Down Expand Up @@ -51,12 +54,23 @@ class AlertCtrl @Inject() (
)
)
override val outputQuery: Query = Query.output[RichAlert, Traversal.V[Alert]](_.richAlert)
val caseFilterParser: FieldsParser[Option[InputQuery[Traversal.Unk, Traversal.Unk]]] =
FilterQuery.default(db, properties.`case`).paramParser(ru.typeOf[Traversal.V[Case]]).optional.on("caseFilter")
override val extraQueries: Seq[ParamQuery[_]] = Seq(
Query[Traversal.V[Alert], Traversal.V[Observable]]("observables", (alertSteps, _) => alertSteps.observables),
Query[Traversal.V[Alert], Traversal.V[Case]]("case", (alertSteps, _) => alertSteps.`case`),
Query[Traversal.V[Alert], Traversal[JsValue, JMap[String, Any], Converter[JsValue, JMap[String, Any]]]](
Query.withParam[Option[InputQuery[Traversal.Unk, Traversal.Unk]], Traversal.V[Alert], Traversal[
JsValue,
JMap[String, Any],
Converter[JsValue, JMap[String, Any]]
]](
"similarCases",
(alertSteps, authContext) => alertSteps.similarCases(authContext).domainMap(Json.toJson(_))
caseFilterParser,
{ (maybeCaseFilterQuery, alertSteps, authContext) =>
val maybeCaseFilter: Option[Traversal.V[Case] => Traversal.V[Case]] =
maybeCaseFilterQuery.map(f => cases => f(db, properties.`case`, ru.typeOf[Traversal.V[Case]], cases.cast, authContext).cast)
alertSteps.similarCases(maybeCaseFilter)(authContext).domainMap(Json.toJson(_))
}
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ trait AlertRenderer {
"similarObservableCount" -> similarStats.observable._1,
"observableCount" -> similarStats.observable._2,
"similarIocCount" -> similarStats.ioc._1,
"iocCount" -> similarStats.ioc._2
"iocCount" -> similarStats.ioc._2,
"observableTypes" -> similarStats.types
)
}
def similarCasesStats(implicit
Expand All @@ -35,7 +36,7 @@ trait AlertRenderer {
else if (x._2.ioc._2 > y._2.ioc._2) -1
else if (x._2.ioc._2 < y._2.ioc._2) 1
else 0
_.similarCases.fold.domainMap(sc => JsArray(sc.sorted.map(Json.toJson(_))))
_.similarCases(None).fold.domainMap(sc => JsArray(sc.sorted.map(Json.toJson(_))))
}

def alertStatsRenderer[D, G, C <: Converter[D, G]](extraData: Set[String])(implicit
Expand Down
2 changes: 1 addition & 1 deletion thehive/app/org/thp/thehive/models/Case.scala
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,4 @@ object RichCase {
}
}

case class SimilarStats(observable: (Int, Int), ioc: (Int, Int))
case class SimilarStats(observable: (Int, Int), ioc: (Int, Int), types: Map[String, Long])
26 changes: 19 additions & 7 deletions thehive/app/org/thp/thehive/services/AlertSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -369,12 +369,14 @@ object AlertOps {
.count
.choose(_.is(P.gt(0)), onTrue = true, onFalse = false)

def similarCases(implicit
def similarCases(maybeCaseFilter: Option[Traversal.V[Case] => Traversal.V[Case]])(implicit
authContext: AuthContext
): Traversal[(RichCase, SimilarStats), JMap[String, Any], Converter[(RichCase, SimilarStats), JMap[String, Any]]] =
observables
): Traversal[(RichCase, SimilarStats), JMap[String, Any], Converter[(RichCase, SimilarStats), JMap[String, Any]]] = {
val similarObservables = observables
.similar
.visible
maybeCaseFilter
.fold(similarObservables)(caseFilter => similarObservables.filter(o => caseFilter(o.`case`)))
.group(_.by(_.`case`))
.unfold
.project(
Expand All @@ -384,17 +386,27 @@ object AlertOps {
_.by(_.richCaseWithoutPerms)
.by((_: Traversal.V[Case]).observables.groupCount(_.byValue(_.ioc)))
)
).by(_.selectValues.unfold.groupCount(_.byValue(_.ioc)))
)
.by(
_.selectValues
.unfold
.project(
_.by(_.groupCount(_.byValue(_.ioc)))
.by(_.groupCount(_.by(_.typeName)))
)
)
)
.domainMap {
case ((richCase, obsStats), similarStats) =>
case ((richCase, obsStats), (iocStats, observableTypeStats)) =>
val obsStatsMap = obsStats.mapValues(_.toInt)
val similarStatsMap = similarStats.mapValues(_.toInt)
val similarStatsMap = iocStats.mapValues(_.toInt)
richCase -> SimilarStats(
similarStatsMap.values.sum -> obsStatsMap.values.sum,
similarStatsMap.getOrElse(true, 0) -> obsStatsMap.getOrElse(true, 0)
similarStatsMap.getOrElse(true, 0) -> obsStatsMap.getOrElse(true, 0),
observableTypeStats
)
}
}

def alertUserOrganisation(
permission: Permission
Expand Down
2 changes: 2 additions & 0 deletions thehive/app/org/thp/thehive/services/ObservableSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ object ObservableOps {

def observableType: Traversal.V[ObservableType] = traversal.out[ObservableObservableType].v[ObservableType]

def typeName: Traversal[String, String, Converter[String, String]] = observableType.value(_.name)

def shares: Traversal.V[Share] = traversal.in[ShareObservable].v[Share]

def share(implicit authContext: AuthContext): Traversal.V[Share] = share(authContext.organisation)
Expand Down

0 comments on commit a54ebe4

Please sign in to comment.