From 65309cf9008d2b7685d56d077beb9dcf0c724595 Mon Sep 17 00:00:00 2001 From: To-om Date: Tue, 26 May 2020 10:01:49 +0200 Subject: [PATCH] #1361 Check organisation of alerts --- .../cortex/services/ActionSrvTest.scala | 4 +- .../cortex/services/EntityHelperTest.scala | 2 +- .../thp/thehive/migration/th4/Output.scala | 6 ++- .../misp/controllers/v0/MispCtrl.scala | 13 +++---- .../misp/services/MispImportSrvTest.scala | 2 +- .../thehive/controllers/v1/AlertCtrl.scala | 38 +++++++++---------- .../org/thp/thehive/services/AlertSrv.scala | 7 ++-- 7 files changed, 37 insertions(+), 35 deletions(-) diff --git a/cortex/connector/src/test/scala/org/thp/thehive/connector/cortex/services/ActionSrvTest.scala b/cortex/connector/src/test/scala/org/thp/thehive/connector/cortex/services/ActionSrvTest.scala index 411728e052..abe9a6952d 100644 --- a/cortex/connector/src/test/scala/org/thp/thehive/connector/cortex/services/ActionSrvTest.scala +++ b/cortex/connector/src/test/scala/org/thp/thehive/connector/cortex/services/ActionSrvTest.scala @@ -107,7 +107,7 @@ class ActionSrvTest extends PlaySpecification with TestAppBuilder { "handle action related to an Alert" in testApp { app => implicit val entityWrites: OWrites[Entity] = app[ActionCtrl].entityWrites val alert = app[Database].roTransaction { implicit graph => - app[AlertSrv].get("testType;testSource;ref2").head() + app[AlertSrv].get("testType;testSource;ref2").visible.head() } alert.read must beFalse val richAction = await(app[ActionSrv].execute(alert, None, "respTest1", JsObject.empty)) @@ -120,7 +120,7 @@ class ActionSrvTest extends PlaySpecification with TestAppBuilder { updatedActionTry must beSuccessfulTry app[Database].roTransaction { implicit graph => - val updatedAlert = app[AlertSrv].get("testType;testSource;ref2").richAlert.head() + val updatedAlert = app[AlertSrv].get("testType;testSource;ref2").visible.richAlert.head() // FIXME updatedAlert.read must beTrue updatedAlert.tags.map(_.toString) must contain("test tag from action") // TODO } diff --git a/cortex/connector/src/test/scala/org/thp/thehive/connector/cortex/services/EntityHelperTest.scala b/cortex/connector/src/test/scala/org/thp/thehive/connector/cortex/services/EntityHelperTest.scala index ce64503902..c29ae9cf68 100644 --- a/cortex/connector/src/test/scala/org/thp/thehive/connector/cortex/services/EntityHelperTest.scala +++ b/cortex/connector/src/test/scala/org/thp/thehive/connector/cortex/services/EntityHelperTest.scala @@ -54,7 +54,7 @@ class EntityHelperTest extends PlaySpecification with TestAppBuilder { "find a manageable entity only (alert)" in testApp { app => app[Database].roTransaction { implicit graph => for { - alert <- app[AlertSrv].getOrFail("testType;testSource;ref2") + alert <- app[AlertSrv].get("testType;testSource;ref2").visible.getOrFail("Alert") t <- app[EntityHelper].get("Alert", alert._id, Permissions.manageAction) } yield t } must beSuccessfulTry diff --git a/migration/src/main/scala/org/thp/thehive/migration/th4/Output.scala b/migration/src/main/scala/org/thp/thehive/migration/th4/Output.scala index a738a6fbeb..153e40088b 100644 --- a/migration/src/main/scala/org/thp/thehive/migration/th4/Output.scala +++ b/migration/src/main/scala/org/thp/thehive/migration/th4/Output.scala @@ -425,7 +425,11 @@ class Output @Inject() ( } override def alertExists(inputAlert: InputAlert): Boolean = db.roTransaction { implicit graph => - alertSrv.initSteps.getBySourceId(inputAlert.alert.`type`, inputAlert.alert.source, inputAlert.alert.sourceRef).exists() + alertSrv + .initSteps + .getBySourceId(inputAlert.alert.`type`, inputAlert.alert.source, inputAlert.alert.sourceRef) + .filter(_.organisation.get(inputAlert.organisation)) + .exists() } override def createAlert(inputAlert: InputAlert): Try[IdMapping] = authTransaction(inputAlert.metaData.createdBy) { diff --git a/misp/connector/src/main/scala/org/thp/thehive/connector/misp/controllers/v0/MispCtrl.scala b/misp/connector/src/main/scala/org/thp/thehive/connector/misp/controllers/v0/MispCtrl.scala index 915e0d8433..1f84c4f948 100644 --- a/misp/connector/src/main/scala/org/thp/thehive/connector/misp/controllers/v0/MispCtrl.scala +++ b/misp/connector/src/main/scala/org/thp/thehive/connector/misp/controllers/v0/MispCtrl.scala @@ -1,23 +1,21 @@ package org.thp.thehive.connector.misp.controllers.v0 -import scala.concurrent.{ExecutionContext, Future} -import scala.util.Success - -import play.api.mvc.{Action, AnyContent, Results} - import akka.actor.ActorRef import com.google.inject.name.Named import javax.inject.{Inject, Singleton} import org.thp.scalligraph.controllers.Entrypoint import org.thp.scalligraph.models.Database import org.thp.scalligraph.steps.StepsOps._ -import org.thp.thehive.connector.misp.services.{MispActor, MispExportSrv, MispImportSrv} +import org.thp.thehive.connector.misp.services.{MispActor, MispExportSrv} import org.thp.thehive.services.{AlertSrv, CaseSrv} +import play.api.mvc.{Action, AnyContent, Results} + +import scala.concurrent.{ExecutionContext, Future} +import scala.util.Success @Singleton class MispCtrl @Inject() ( entrypoint: Entrypoint, - mispImportSrv: MispImportSrv, mispExportSrv: MispExportSrv, alertSrv: AlertSrv, caseSrv: CaseSrv, @@ -52,6 +50,7 @@ class MispCtrl @Inject() ( alertSrv .initSteps .has("type", "misp") + .visible .toIterator .toTry(alertSrv.cascadeRemove(_)) .map(_ => Results.NoContent) diff --git a/misp/connector/src/test/scala/org/thp/thehive/connector/misp/services/MispImportSrvTest.scala b/misp/connector/src/test/scala/org/thp/thehive/connector/misp/services/MispImportSrvTest.scala index 1a52cc7555..ea2ae96e31 100644 --- a/misp/connector/src/test/scala/org/thp/thehive/connector/misp/services/MispImportSrvTest.scala +++ b/misp/connector/src/test/scala/org/thp/thehive/connector/misp/services/MispImportSrvTest.scala @@ -74,7 +74,7 @@ class MispImportSrvTest(implicit ec: ExecutionContext) extends PlaySpecification await(app[MispImportSrv].syncMispEvents(app[TheHiveMispClient])(authContext))(1.minute) app[Database].roTransaction { implicit graph => - app[AlertSrv].initSteps.getBySourceId("misp", "ORGNAME", "1").getOrFail("Alert") + app[AlertSrv].initSteps.getBySourceId("misp", "ORGNAME", "1").visible.getOrFail("Alert") } must beSuccessfulTry( Alert( `type` = "misp", diff --git a/thehive/app/org/thp/thehive/controllers/v1/AlertCtrl.scala b/thehive/app/org/thp/thehive/controllers/v1/AlertCtrl.scala index ff009a2556..86833437d6 100644 --- a/thehive/app/org/thp/thehive/controllers/v1/AlertCtrl.scala +++ b/thehive/app/org/thp/thehive/controllers/v1/AlertCtrl.scala @@ -61,7 +61,7 @@ class AlertCtrl @Inject() ( entrypoint("get alert") .authRoTransaction(db) { implicit request => implicit graph => alertSrv - .getByIds(alertId) + .get(alertId) .visible .richAlert .getOrFail("Alert") @@ -75,7 +75,7 @@ class AlertCtrl @Inject() ( val propertyUpdaters: Seq[PropertyUpdater] = request.body("alert") alertSrv .update( - _.getByIds(alertId) + _.get(alertId) .can(Permissions.manageAlert), propertyUpdaters ) @@ -88,11 +88,11 @@ class AlertCtrl @Inject() ( entrypoint("mark alert as read") .authTransaction(db) { implicit request => implicit graph => alertSrv - .getByIds(alertId) + .get(alertId) .can(Permissions.manageAlert) - .existsOrFail() - .map { _ => - alertSrv.markAsRead(alertId) + .getOrFail() + .map { alert => + alertSrv.markAsRead(alert._id) Results.NoContent } } @@ -101,11 +101,11 @@ class AlertCtrl @Inject() ( entrypoint("mark alert as unread") .authTransaction(db) { implicit request => implicit graph => alertSrv - .getByIds(alertId) + .get(alertId) .can(Permissions.manageAlert) - .existsOrFail() - .map { _ => - alertSrv.markAsUnread(alertId) + .getOrFail() + .map { alert => + alertSrv.markAsUnread(alert._id) Results.NoContent } } @@ -114,7 +114,7 @@ class AlertCtrl @Inject() ( entrypoint("create case from alert") .authTransaction(db) { implicit request => implicit graph => for { - (alert, organisation) <- alertSrv.getByIds(alertId).alertUserOrganisation(Permissions.manageCase).getOrFail("Alert") + (alert, organisation) <- alertSrv.get(alertId).alertUserOrganisation(Permissions.manageCase).getOrFail("Alert") richCase <- alertSrv.createCase(alert, None, organisation) } yield Results.Created(richCase.toJson) } @@ -123,11 +123,11 @@ class AlertCtrl @Inject() ( entrypoint("follow alert") .authTransaction(db) { implicit request => implicit graph => alertSrv - .getByIds(alertId) + .get(alertId) .can(Permissions.manageAlert) - .existsOrFail() - .map { _ => - alertSrv.followAlert(alertId) + .getOrFail() + .map { alert => + alertSrv.followAlert(alert._id) Results.NoContent } } @@ -136,11 +136,11 @@ class AlertCtrl @Inject() ( entrypoint("unfollow alert") .authTransaction(db) { implicit request => implicit graph => alertSrv - .getByIds(alertId) + .get(alertId) .can(Permissions.manageAlert) - .existsOrFail() - .map { _ => - alertSrv.unfollowAlert(alertId) + .getOrFail() + .map { alert => + alertSrv.unfollowAlert(alert._id) Results.NoContent } } diff --git a/thehive/app/org/thp/thehive/services/AlertSrv.scala b/thehive/app/org/thp/thehive/services/AlertSrv.scala index 99e20839f5..889ae136d9 100644 --- a/thehive/app/org/thp/thehive/services/AlertSrv.scala +++ b/thehive/app/org/thp/thehive/services/AlertSrv.scala @@ -302,14 +302,13 @@ class AlertSteps(raw: GremlinScala[Vertex])(implicit db: Database, graph: Graph) def visible(implicit authContext: AuthContext): AlertSteps = this.filter( _.outTo[AlertOrganisation] - .inTo[RoleOrganisation] - .inTo[UserRole] - .has("login", authContext.userId) + .has("name", authContext.organisation) ) def can(permission: Permission)(implicit authContext: AuthContext): AlertSteps = this.filter( _.outTo[AlertOrganisation] + .has("name", authContext.organisation) .inTo[RoleOrganisation] .filter(_.outTo[RoleProfile].has("permissions", permission)) .inTo[UserRole] @@ -328,7 +327,7 @@ class AlertSteps(raw: GremlinScala[Vertex])(implicit db: Database, graph: Graph) Traversal( raw .`match`( - _.as(alertLabel).out("AlertOrganisation").as(organisationLabel), + _.as(alertLabel).out("AlertOrganisation").has(Key("name") of authContext.organisation).as(organisationLabel), _.as(alertLabel).out("AlertTag").fold().as(tagLabel), _.as(organisationLabel) .inTo[RoleOrganisation]