diff --git a/thehive/app/org/thp/thehive/TheHiveModule.scala b/thehive/app/org/thp/thehive/TheHiveModule.scala index 4c752f9926..5edddcdc86 100644 --- a/thehive/app/org/thp/thehive/TheHiveModule.scala +++ b/thehive/app/org/thp/thehive/TheHiveModule.scala @@ -101,6 +101,7 @@ class TheHiveModule(environment: Environment, configuration: Configuration) exte integrityCheckOpsBindings.addBinding.to[CaseTemplateIntegrityCheckOps] integrityCheckOpsBindings.addBinding.to[DataIntegrityCheckOps] integrityCheckOpsBindings.addBinding.to[CaseIntegrityCheckOps] + integrityCheckOpsBindings.addBinding.to[AlertIntegrityCheckOps] bind[ActorRef].annotatedWithName("integrity-check-actor").toProvider[IntegrityCheckActorProvider] bind[ActorRef].annotatedWithName("flow-actor").toProvider[FlowActorProvider] diff --git a/thehive/app/org/thp/thehive/services/AlertSrv.scala b/thehive/app/org/thp/thehive/services/AlertSrv.scala index fc6a60b5a2..41859c2590 100644 --- a/thehive/app/org/thp/thehive/services/AlertSrv.scala +++ b/thehive/app/org/thp/thehive/services/AlertSrv.scala @@ -1,5 +1,6 @@ package org.thp.thehive.services +import akka.actor.ActorRef import org.apache.tinkerpop.gremlin.structure.Graph import org.thp.scalligraph.auth.{AuthContext, Permission} import org.thp.scalligraph.models._ @@ -32,7 +33,8 @@ class AlertSrv @Inject() ( customFieldSrv: CustomFieldSrv, caseTemplateSrv: CaseTemplateSrv, observableSrv: ObservableSrv, - auditSrv: AuditSrv + auditSrv: AuditSrv, + @Named("integrity-check-actor") integrityCheckActor: ActorRef )(implicit @Named("with-thehive-schema") db: Database ) extends VertexSrv[Alert] { @@ -268,6 +270,7 @@ class AlertSrv @Inject() ( _ <- importObservables(alert.alert, createdCase.`case`) _ <- alertCaseSrv.create(AlertCase(), alert.alert, createdCase.`case`) _ <- markAsRead(alert._id) + _ = integrityCheckActor ! EntityAdded("Alert") } yield createdCase } }(richCase => auditSrv.`case`.create(richCase.`case`, richCase.toJson)) @@ -304,6 +307,7 @@ class AlertSrv @Inject() ( ) } yield details }(details => auditSrv.alertToCase.merge(alert, `case`, Some(details))) + .map(_ => integrityCheckActor ! EntityAdded("Alert")) .flatMap(_ => caseSrv.getOrFail(`case`._id)) def importObservables(alert: Alert with Entity, `case`: Case with Entity)(implicit @@ -591,3 +595,18 @@ object AlertOps { implicit class AlertCustomFieldsOpsDefs(traversal: Traversal.E[AlertCustomField]) extends CustomFieldValueOpsDefs(traversal) } + +class AlertIntegrityCheckOps @Inject() (@Named("with-thehive-schema") val db: Database, val service: AlertSrv) extends IntegrityCheckOps[Alert] { + override def check(): Unit = { + db.tryTransaction { implicit graph => + service + .startTraversal + .flatMap(_.outE[AlertCase].range(1, 100)) + .remove() + Success(()) + } + () + } + + override def resolve(entities: Seq[Alert with Entity])(implicit graph: Graph): Try[Unit] = Success(()) +} diff --git a/thehive/conf/reference.conf b/thehive/conf/reference.conf index 403e23198c..523fb7d7d1 100644 --- a/thehive/conf/reference.conf +++ b/thehive/conf/reference.conf @@ -163,6 +163,10 @@ integrityCheck { initialDelay: 1 minute interval: 10 minutes } + alert { + initialDelay: 5 minute + interval: 30 minutes + } }