Skip to content

Commit

Permalink
Merge branch 'hotfix/4.1.13'
Browse files Browse the repository at this point in the history
  • Loading branch information
To-om committed Nov 8, 2021
2 parents 7553678 + a87f948 commit 9e889a0
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 15 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Change Log

## [4.1.13](https://github.com/TheHive-Project/TheHive/milestone/83) (2021-11-08)

**Implemented enhancements:**

- [Feature Request] Add API to link alert and case after a broken migration from TH3 [\#2238](https://github.com/TheHive-Project/TheHive/issues/2238)

**Fixed bugs:**

- [Bug] Migration breaks links between alerts and cases thus rendering all alert statuses as ignored [\#2232](https://github.com/TheHive-Project/TheHive/issues/2232)
- [Bug] Search Section results missing (Observables) [\#2233](https://github.com/TheHive-Project/TheHive/issues/2233)
- [Enhancement] Accept slash in attachment filename [\#2240](https://github.com/TheHive-Project/TheHive/issues/2240)

## [4.1.12](https://github.com/TheHive-Project/TheHive/milestone/82) (2021-10-29)

**Fixed bugs:**
Expand Down
2 changes: 1 addition & 1 deletion ScalliGraph
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Dependencies._
import com.typesafe.sbt.packager.Keys.bashScriptDefines
import org.thp.ghcl.Milestone

val thehiveVersion = "4.1.12-1"
val thehiveVersion = "4.1.13-1"
val scala212 = "2.12.13"
val scala213 = "2.13.1"
val supportedScalaVersions = List(scala212, scala213)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ object Conversion {
_.case_artifact,
jobWithParent._2.fold[Option[OutputObservable]](None) {
case (richObservable, richCase) =>
Some(observableWithExtraOutput.toValue((richObservable, JsObject.empty, Some(richCase))))
Some(observableWithExtraOutput.toValue((richObservable, JsObject.empty, Some(Left(richCase)))))
}
)
.enableMethodAccessors
Expand Down
1 change: 1 addition & 0 deletions dto/src/main/scala/org/thp/thehive/dto/v0/Observable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ case class OutputObservable(
stats: JsObject,
seen: Option[Boolean],
`case`: Option[OutputCase],
alert: Option[OutputAlert],
ignoreSimilarity: Option[Boolean]
)

Expand Down
2 changes: 1 addition & 1 deletion frontend/bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "thehive",
"version": "4.1.12-1",
"version": "4.1.13-1",
"license": "AGPL-3.0",
"dependencies": {
"jquery": "^3.4.1",
Expand Down
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "thehive",
"version": "4.1.12-1",
"version": "4.1.13-1",
"license": "AGPL-3.0",
"repository": {
"type": "git",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,7 @@ class Output @Inject() (
for {
organisation <- getOrganisation(inputAlert.organisation)
createdAlert <- alertSrv.createEntity(inputAlert.alert.copy(organisationId = organisation._id, caseId = `case`.fold(EntityId.empty)(_._id)))
_ <- `case`.map(alertSrv.alertCaseSrv.create(AlertCase(), createdAlert, _)).flip
tags = inputAlert.alert.tags.flatMap(getTag(_, organisation._id.value).toOption)
_ = updateMetaData(createdAlert, inputAlert.metaData)
_ <- alertSrv.alertOrganisationSrv.create(AlertOrganisation(), createdAlert, organisation)
Expand Down
11 changes: 7 additions & 4 deletions thehive/app/org/thp/thehive/controllers/v0/Conversion.scala
Original file line number Diff line number Diff line change
Expand Up @@ -408,13 +408,14 @@ object Conversion {
)
.withFieldConst(_.stats, JsObject.empty)
.withFieldConst(_.`case`, None)
.withFieldConst(_.alert, None)
.enableMethodAccessors
.transform
)

implicit val observableWithExtraOutput: Renderer.Aux[(RichObservable, JsObject, Option[RichCase]), OutputObservable] =
Renderer.toJson[(RichObservable, JsObject, Option[RichCase]), OutputObservable] {
case (richObservable, stats, richCase) =>
implicit val observableWithExtraOutput: Renderer.Aux[(RichObservable, JsObject, Option[Either[RichCase, RichAlert]]), OutputObservable] =
Renderer.toJson[(RichObservable, JsObject, Option[Either[RichCase, RichAlert]]), OutputObservable] {
case (richObservable, stats, caseOrAlert) =>
richObservable
.into[OutputObservable]
.withFieldConst(_._type, "case_artifact")
Expand All @@ -438,7 +439,8 @@ object Conversion {
})
)
.withFieldConst(_.stats, stats)
.withFieldConst(_.`case`, richCase.map(_.toValue))
.withFieldConst(_.`case`, caseOrAlert.flatMap(_.swap.map(_.toValue).toOption))
.withFieldConst(_.alert, caseOrAlert.flatMap(_.map(_.toValue).toOption))
.enableMethodAccessors
.transform
}
Expand Down Expand Up @@ -470,6 +472,7 @@ object Conversion {
)
.withFieldConst(_.stats, stats)
.withFieldConst(_.`case`, None)
.withFieldConst(_.alert, None)
.enableMethodAccessors
.transform
}
Expand Down
18 changes: 14 additions & 4 deletions thehive/app/org/thp/thehive/controllers/v0/ObservableCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import org.thp.thehive.services.AlertOps._
import org.thp.thehive.services.CaseOps._
import org.thp.thehive.services.ObservableOps._
import org.thp.thehive.services.OrganisationOps._
import org.thp.thehive.services.ShareOps._
import org.thp.thehive.services._
import play.api.Configuration
import play.api.libs.Files.DefaultTemporaryFileCreator
Expand Down Expand Up @@ -382,14 +381,25 @@ class PublicObservable @Inject() (
.richPage(from, to, withTotal = true) {
case o if withStats =>
o.richObservableWithCustomRenderer(organisationSrv, observableStatsRenderer(organisationSrv)(authContext))(authContext)
.domainMap(ros => (ros._1, ros._2, None: Option[RichCase]))
.domainMap(ros => (ros._1, ros._2, None: Option[Either[RichCase, RichAlert]]))
case o =>
o.richObservable.domainMap(ro => (ro, JsObject.empty, None))
}
case (OutputParam(from, to, _, _), observableSteps, authContext) =>
observableSteps.richPage(from, to, withTotal = true)(
_.richObservableWithCustomRenderer(organisationSrv, o => o.`case`.richCase(authContext))(authContext).domainMap(roc =>
(roc._1, JsObject.empty, Some(roc._2): Option[RichCase])
_.richObservableWithCustomRenderer(
organisationSrv,
o => o.project(_.by(_.`case`.richCase(authContext).option).by(_.alert.richAlert.option))
)(authContext).domainMap(roc =>
(
roc._1,
JsObject.empty,
roc._2 match {
case (Some(c), _) => Some(Left(c))
case (_, Some(a)) => Some(Right(a))
case _ => None
}
)
)
)
}
Expand Down
23 changes: 21 additions & 2 deletions thehive/app/org/thp/thehive/controllers/v1/AlertCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.thp.scalligraph.models.Database
import org.thp.scalligraph.query._
import org.thp.scalligraph.traversal.TraversalOps._
import org.thp.scalligraph.traversal.{Converter, IteratorOutput, Traversal}
import org.thp.scalligraph.{EntityIdOrName, RichOptionTry}
import org.thp.scalligraph.{BadRequestError, EntityIdOrName, EntityName, RichOptionTry}
import org.thp.thehive.controllers.v1.Conversion._
import org.thp.thehive.dto.v1.{InputAlert, InputCustomFieldValue}
import org.thp.thehive.models._
Expand All @@ -19,14 +19,15 @@ import play.api.mvc.{Action, AnyContent, Results}
import java.util.{Map => JMap}
import javax.inject.{Inject, Singleton}
import scala.reflect.runtime.{universe => ru}
import scala.util.Success
import scala.util.{Failure, Success}

case class SimilarCaseFilter()
@Singleton
class AlertCtrl @Inject() (
entrypoint: Entrypoint,
properties: Properties,
alertSrv: AlertSrv,
caseSrv: CaseSrv,
caseTemplateSrv: CaseTemplateSrv,
userSrv: UserSrv,
organisationSrv: OrganisationSrv,
Expand Down Expand Up @@ -211,4 +212,22 @@ class AlertCtrl @Inject() (
Results.NoContent
}
}

def fixCaseLink: Action[AnyContent] =
entrypoint("fix link between case and alert")
.extract("alertName", FieldsParser.string.on("alertName"))
.extract("caseNumber", FieldsParser.string.on("caseNumber"))
.extract("organisation", FieldsParser.string.on("organisation"))
.authPermittedTransaction(db, Permissions.managePlatform) { implicit request => implicit graph =>
val alertName: String = request.body("alertName")
val caseNumber: String = request.body("caseNumber")
val organisation: String = request.body("organisation")
for {
organisation <- organisationSrv.getOrFail(EntityIdOrName(organisation))
alert <- alertSrv.startTraversal.has(_.organisationId, organisation._id).get(EntityName(alertName)).getOrFail("Alert")
_ <- if (alertSrv.get(alert).`case`.exists) Failure(BadRequestError("The alert is already linked to a case")) else Success(())
c <- caseSrv.getOrFail(EntityName(caseNumber))
_ <- alertSrv.alertCaseSrv.create(AlertCase(), alert, c)
} yield Results.NoContent
}
}
1 change: 1 addition & 0 deletions thehive/app/org/thp/thehive/controllers/v1/Router.scala
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ class Router @Inject() (
case POST(p"/alert/$alertId/follow") => alertCtrl.followAlert(alertId)
case POST(p"/alert/$alertId/unfollow") => alertCtrl.unfollowAlert(alertId)
case POST(p"/alert/$alertId/case") => alertCtrl.createCase(alertId)
case POST(p"/alert/fixCaseLink") => alertCtrl.fixCaseLink
// PATCH /alert/_bulk controllers.AlertCtrl.bulkUpdate()
// DELETE /alert/:alertId controllers.AlertCtrl.delete(alertId)
// POST /alert/:alertId/merge/:caseId controllers.AlertCtrl.mergeWithCase(alertId, caseId)
Expand Down

0 comments on commit 9e889a0

Please sign in to comment.