Skip to content

Commit

Permalink
#1738 Prevent multiple merge of an alert
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Jan 11, 2021
1 parent 64d4147 commit 0b2c524
Showing 1 changed file with 28 additions and 22 deletions.
50 changes: 28 additions & 22 deletions thehive/app/org/thp/thehive/services/AlertSrv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import org.thp.scalligraph.query.PropertyUpdater
import org.thp.scalligraph.services._
import org.thp.scalligraph.traversal.TraversalOps._
import org.thp.scalligraph.traversal.{Converter, IdentityConverter, StepLabel, Traversal}
import org.thp.scalligraph.{CreateError, EntityId, EntityIdOrName, RichOptionTry, RichSeq}
import org.thp.scalligraph.{BadRequestError, CreateError, EntityId, EntityIdOrName, RichOptionTry, RichSeq}
import org.thp.thehive.controllers.v1.Conversion._
import org.thp.thehive.dto.v1.InputCustomFieldValue
import org.thp.thehive.models._
Expand Down Expand Up @@ -280,28 +280,31 @@ class AlertSrv @Inject() (
} yield updatedCase

def mergeInCase(alert: Alert with Entity, `case`: Case with Entity)(implicit graph: Graph, authContext: AuthContext): Try[Case with Entity] =
auditSrv
.mergeAudits {
// No audit for markAsRead and observables
// Audits for customFields, description and tags
val description = `case`.description + s"\n \n#### Merged with alert #${alert.sourceRef} ${alert.title}\n\n${alert.description.trim}"
for {
_ <- markAsRead(alert._id)
_ <- importObservables(alert, `case`)
_ <- importCustomFields(alert, `case`)
_ <- caseSrv.addTags(`case`, get(alert).tags.toSeq.map(_.toString).toSet)
_ <- alertCaseSrv.create(AlertCase(), alert, `case`)
c <- caseSrv.get(`case`).update(_.description, description).getOrFail("Case")
details <- Success(
Json.obj(
"customFields" -> get(alert).richCustomFields.toSeq.map(_.toOutput.toJson),
"description" -> c.description,
"tags" -> caseSrv.get(`case`).tags.toSeq.map(_.toString)
if (get(alert).isImported)
Failure(BadRequestError("Alert is already imported"))
else
auditSrv
.mergeAudits {
// No audit for markAsRead and observables
// Audits for customFields, description and tags
val description = `case`.description + s"\n \n#### Merged with alert #${alert.sourceRef} ${alert.title}\n\n${alert.description.trim}"
for {
_ <- markAsRead(alert._id)
_ <- importObservables(alert, `case`)
_ <- importCustomFields(alert, `case`)
_ <- caseSrv.addTags(`case`, get(alert).tags.toSeq.map(_.toString).toSet)
_ <- alertCaseSrv.create(AlertCase(), alert, `case`)
c <- caseSrv.get(`case`).update(_.description, description).getOrFail("Case")
details <- Success(
Json.obj(
"customFields" -> get(alert).richCustomFields.toSeq.map(_.toOutput.toJson),
"description" -> c.description,
"tags" -> caseSrv.get(`case`).tags.toSeq.map(_.toString)
)
)
)
} yield details
}(details => auditSrv.alertToCase.merge(alert, `case`, Some(details)))
.flatMap(_ => caseSrv.getOrFail(`case`._id))
} yield details
}(details => auditSrv.alertToCase.merge(alert, `case`, Some(details)))
.flatMap(_ => caseSrv.getOrFail(`case`._id))

def importObservables(alert: Alert with Entity, `case`: Case with Entity)(implicit
graph: Graph,
Expand Down Expand Up @@ -400,6 +403,9 @@ object AlertOps {
def imported: Traversal[Boolean, Boolean, IdentityConverter[Boolean]] =
traversal.choose(_.outE[AlertCase], onTrue = true, onFalse = false)

def isImported: Boolean =
traversal.outE[AlertCase].exists

def importDate: Traversal[Date, Date, Converter[Date, Date]] =
traversal.outE[AlertCase].value(_._createdAt)

Expand Down

0 comments on commit 0b2c524

Please sign in to comment.