Skip to content

Commit

Permalink
#2335 Fix initial values creation
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Feb 6, 2022
1 parent f399824 commit 984349b
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 29 deletions.
1 change: 1 addition & 0 deletions migration/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ output {
caseNumberShift: 0
resume: false
removeData: false
integrityCheck.enabled: false
db {
provider: janusgraph
janusgraph {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ object Migrate extends App with MigrationOps {
opt[Int]('t', "thread-count")
.text("number of threads")
.action((t, c) => addConfig(c, "threadCount", t)),
opt[Unit]('k', "integrity-checks")
.text("run integrity checks after the migration")
.action((_, c) => addConfig(c, "output.integrityCheck.enabled", true)),
/* case age */
opt[String]("max-case-age")
.valueName("<duration>")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
package org.thp.thehive.migration.th4

import akka.actor.Actor
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.scaladsl.adapter.ClassicActorSystemOps
import akka.actor.{Actor, ActorSystem}
import akka.actor.typed.{ActorRef => TypedActorRef}

import java.util.UUID
import javax.inject.{Inject, Provider}

class DummyActor extends Actor {
override def receive: Receive = PartialFunction.empty
}

class DummyTypedActorProvider[T] @Inject() (actorSystem: ActorSystem) extends Provider[TypedActorRef[T]] {
override def get(): TypedActorRef[T] =
actorSystem
.toTyped
.systemActorOf(Behaviors.empty, UUID.randomUUID().toString)
}
53 changes: 36 additions & 17 deletions migration/src/main/scala/org/thp/thehive/migration/th4/Output.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ object Output {
bindActor[DummyActor]("notification-actor")
bindActor[DummyActor]("config-actor")
bindActor[DummyActor]("cortex-actor")
bindActor[DummyActor]("integrity-check-actor")
bind[ActorRef[IntegrityCheck.Request]].toProvider[DummyTypedActorProvider[IntegrityCheck.Request]]
bind[ActorRef[CaseNumberActor.Request]].toProvider[CaseNumberActorProvider]
val integrityCheckOpsBindings = ScalaMultibinder.newSetBinder[IntegrityCheck](binder)
integrityCheckOpsBindings.addBinding.to[AlertIntegrityCheck]
Expand Down Expand Up @@ -131,6 +131,7 @@ class Output @Inject() (
resolutionStatusSrv: ResolutionStatusSrv,
jobSrv: JobSrv,
actionSrv: ActionSrv,
dashboardSrv: DashboardSrv,
db: Database,
cache: SyncCacheApi,
checks: immutable.Set[IntegrityCheck]
Expand Down Expand Up @@ -204,23 +205,23 @@ class Output @Inject() (
db.addSchemaIndexes(theHiveSchema)
.flatMap(_ => db.addSchemaIndexes(cortexSchema))
.foreach { _ =>
implicit val authContext: AuthContext = LocalUserSrv.getSystemAuthContext
checks.foreach { c =>
logger.info(s"Running check on ${c.name} ...")
val desupStats = c match {
case dc: DedupCheck[_] => dc.dedup(KillSwitch.alwaysOn)
case _ => Map.empty[String, Long]
}
val globalStats = c match {
case gc: GlobalCheck[_] => gc.runGlobalCheck(24.hours, KillSwitch.alwaysOn)
case _ => Map.empty[String, Long]
if (configuration.get[Boolean]("integrityCheck.enabled"))
checks.foreach { c =>
logger.info(s"Running check on ${c.name} ...")
val desupStats = c match {
case dc: DedupCheck[_] => dc.dedup(KillSwitch.alwaysOn)
case _ => Map.empty[String, Long]
}
val globalStats = c match {
case gc: GlobalCheck[_] => gc.runGlobalCheck(24.hours, KillSwitch.alwaysOn)
case _ => Map.empty[String, Long]
}
val statsStr = (desupStats <+> globalStats)
.collect { case (k, v) if v != 0 => s"$k:$v" }
.mkString(" ")
if (statsStr.isEmpty) logger.info(s"Check on ${c.name}: no change needed")
else logger.info(s"Check on ${c.name}: $statsStr")
}
val statsStr = (desupStats <+> globalStats)
.collect { case (k, v) if v != 0 => s"$k:$v" }
.mkString(" ")
if (statsStr.isEmpty) logger.info(s"Check on ${c.name}: no change needed")
else logger.info(s"Check on ${c.name}: $statsStr")
}
}

Try(db.close())
Expand Down Expand Up @@ -874,4 +875,22 @@ class Output @Inject() (
_ <- context.map(auditSrv.auditContextSrv.create(AuditContext(), createdAudit, _)).flip
} yield ()
}

def dashboardExists(graph: Graph, inputDashboard: InputDashboard): Boolean =
if (!resumeMigration) false
else
db.roTransaction { implicit graph =>
dashboardSrv.startTraversal.has(_.title, inputDashboard.dashboard.title).exists
}

override def createDashboard(graph: Graph, inputDashboard: InputDashboard): Try[IdMapping] =
withAuthContext(inputDashboard.metaData.createdBy) { implicit authContext =>
implicit val g: Graph = graph
logger.debug(s"Create dashboard ${inputDashboard.dashboard.title}")
for {
dashboard <- dashboardSrv.create(inputDashboard.dashboard).map(_.dashboard)
_ <- inputDashboard.organisation.map { case (org, writable) => dashboardSrv.share(dashboard, EntityName(org), writable) }.flip
_ = updateMetaData(dashboard, inputDashboard.metaData)
} yield IdMapping(inputDashboard.metaData.id, dashboard._id)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import org.thp.scalligraph.EntityId
import org.thp.scalligraph.auth.AuthContext
import org.thp.scalligraph.janus.JanusDatabase
import org.thp.scalligraph.models._
import org.thp.scalligraph.traversal.Graph
import org.thp.scalligraph.traversal.TraversalOps._
import org.thp.thehive.services.LocalUserSrv
import play.api.Logger
Expand Down Expand Up @@ -525,16 +524,10 @@ class TheHiveSchemaDefinition @Inject() extends Schema with UpdatableSchema {
.toSeq
}

override lazy val initialValues: Seq[InitialValue[_]] = modelList.collect {
case vertexModel: VertexModel => vertexModel.getInitialValues
}.flatten

private def tagString(namespace: String, predicate: String, value: String): String =
(if (namespace.headOption.getOrElse('_') == '_') "" else namespace + ':') +
(if (predicate.headOption.getOrElse('_') == '_') "" else predicate) +
(if (value.isEmpty) "" else f"""="$value"""")

override def init(db: Database)(implicit graph: Graph, authContext: AuthContext): Try[Unit] = Success(())

override val authContext: AuthContext = LocalUserSrv.getSystemAuthContext
}
13 changes: 11 additions & 2 deletions thehive/app/org/thp/thehive/services/IntegrityCheckActor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import akka.actor.typed.scaladsl.{Behaviors, TimerScheduler}
import akka.cluster.typed.{ClusterSingleton, SingletonActor}
import org.quartz
import org.quartz._
import org.thp.scalligraph.auth.AuthContext
import org.thp.scalligraph.models.Database
import org.thp.scalligraph.services.config.{ApplicationConfig, ConfigItem}
import org.thp.scalligraph.services.config.ApplicationConfig.finiteDurationFormat
import org.thp.scalligraph.services.{DedupCheck, GlobalCheck, IntegrityCheck, KillSwitch}
Expand All @@ -17,7 +19,7 @@ import play.api.libs.json._
import javax.inject.{Inject, Provider, Singleton}
import scala.collection.immutable
import scala.concurrent.duration.{DurationDouble, DurationLong, FiniteDuration}
import scala.util.Try
import scala.util.{Success, Try}

case class CheckStats(global: Map[String, Long], last: Map[String, Long], lastDate: Long) {
def +(stats: Map[String, Long]): CheckStats = {
Expand Down Expand Up @@ -112,6 +114,7 @@ object IntegrityCheck {
private val actorRefContextKey = "IntegrityCheck-actor"

def behavior(
db: Database,
quartzScheduler: quartz.Scheduler,
appConfig: ApplicationConfig,
integrityChecks: Seq[IntegrityCheck]
Expand All @@ -128,6 +131,11 @@ object IntegrityCheck {
}
)

db.tryTransaction { implicit graph =>
implicit val authContext: AuthContext = LocalUserSrv.getSystemAuthContext
integrityChecks.foreach(_.initialCheck())
Success(())
}
setupScheduling(context.self, quartzScheduler, integrityChecks, configItem)
behavior(context.self, quartzScheduler, configItem, timers, integrityChecks.map(_.name))
}
Expand Down Expand Up @@ -428,12 +436,13 @@ object IntegrityCheck {

@Singleton
class IntegrityCheckActorProvider @Inject() (
db: Database,
system: ActorSystem,
quartzScheduler: quartz.Scheduler,
appConfig: ApplicationConfig,
integrityChecks: immutable.Set[IntegrityCheck]
) extends Provider[ActorRef[IntegrityCheck.Request]] {
override lazy val get: ActorRef[IntegrityCheck.Request] =
ClusterSingleton(system.toTyped)
.init(SingletonActor(IntegrityCheck.behavior(quartzScheduler, appConfig, integrityChecks.toSeq), "IntegrityCheckActor"))
.init(SingletonActor(IntegrityCheck.behavior(db, quartzScheduler, appConfig, integrityChecks.toSeq), "IntegrityCheckActor"))
}
2 changes: 1 addition & 1 deletion thehive/app/org/thp/thehive/services/ProfileSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import org.thp.thehive.services.ProfileOps._
import play.api.libs.json.JsObject

import javax.inject.{Inject, Provider, Singleton}
import scala.util.{Failure, Success, Try}
import scala.util.{Failure, Try}

@Singleton
class ProfileSrv @Inject() (
Expand Down

0 comments on commit 984349b

Please sign in to comment.