Skip to content

Commit aa502d0

Browse files
To-omnadouani
authored andcommitted
#12 Make customFields and metrics mandatory (even if empty)
1 parent a80b352 commit aa502d0

File tree

2 files changed

+29
-11
lines changed

2 files changed

+29
-11
lines changed

thehive-backend/app/models/Case.scala

+10-9
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@ package models
33
import java.util.Date
44
import javax.inject.{ Inject, Provider, Singleton }
55

6-
import scala.concurrent.{ ExecutionContext, Future }
7-
import scala.math.BigDecimal.{ int2bigDecimal, long2bigDecimal }
8-
import play.api.Logger
9-
import play.api.libs.json._
10-
import play.api.libs.json.JsValue.jsValueToJsLookup
11-
import play.api.libs.json.Json.toJsFieldJsValueWrapper
6+
import models.JsonFormat.{ caseImpactStatusFormat, caseResolutionStatusFormat, caseStatusFormat }
127
import org.elastic4play.JsonFormat.dateFormat
138
import org.elastic4play.models.{ AttributeDef, BaseEntity, EntityDef, HiveEnumeration, ModelDef, AttributeFormat F, AttributeOption O }
149
import org.elastic4play.services.{ FindSrv, SequenceSrv }
15-
import models.JsonFormat.{ caseImpactStatusFormat, caseResolutionStatusFormat, caseStatusFormat }
10+
import play.api.Logger
11+
import play.api.libs.json.JsValue.jsValueToJsLookup
12+
import play.api.libs.json.Json.toJsFieldJsValueWrapper
13+
import play.api.libs.json._
1614
import services.{ AuditedModel, CaseSrv }
1715

16+
import scala.concurrent.{ ExecutionContext, Future }
17+
import scala.math.BigDecimal.{ int2bigDecimal, long2bigDecimal }
18+
1819
object CaseStatus extends Enumeration with HiveEnumeration {
1920
type Type = Value
2021
val Open, Resolved, Deleted = Value
@@ -42,13 +43,13 @@ trait CaseAttributes { _: AttributeDef ⇒
4243
val flag: A[Boolean] = attribute("flag", F.booleanFmt, "Flag of the case", false)
4344
val tlp: A[Long] = attribute("tlp", F.numberFmt, "TLP level", 2L)
4445
val status: A[CaseStatus.Value] = attribute("status", F.enumFmt(CaseStatus), "Status of the case", CaseStatus.Open)
45-
val metrics: A[Option[JsValue]] = optionalAttribute("metrics", F.metricsFmt, "List of metrics")
46+
val metrics: A[JsValue] = attribute("metrics", F.metricsFmt, "List of metrics")
4647
val resolutionStatus: A[Option[CaseResolutionStatus.Value]] = optionalAttribute("resolutionStatus", F.enumFmt(CaseResolutionStatus), "Resolution status of the case")
4748
val impactStatus: A[Option[CaseImpactStatus.Value]] = optionalAttribute("impactStatus", F.enumFmt(CaseImpactStatus), "Impact status of the case")
4849
val summary: A[Option[String]] = optionalAttribute("summary", F.textFmt, "Summary of the case, to be provided when closing a case")
4950
val mergeInto: A[Option[String]] = optionalAttribute("mergeInto", F.stringFmt, "Id of the case created by the merge")
5051
val mergeFrom: A[Seq[String]] = multiAttribute("mergeFrom", F.stringFmt, "Id of the cases merged")
51-
val customFields: A[Option[JsValue]] = optionalAttribute("customFields", F.customFields, "Custom fields")
52+
val customFields: A[JsValue] = attribute("customFields", F.customFields, "Custom fields")
5253
}
5354

5455
@Singleton

thehive-backend/app/services/CaseMergeSrv.scala

+19-2
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,7 @@ class CaseMergeSrv @Inject() (
101101
private[services] def mergeMetrics(cases: Seq[Case]): JsObject = {
102102
val metrics = for {
103103
caze cases
104-
metrics caze.metrics()
105-
metricsObject metrics.asOpt[JsObject]
104+
metricsObject caze.metrics().asOpt[JsObject]
106105
} yield metricsObject
107106

108107
val mergedMetrics: Seq[(String, JsValue)] = metrics.flatMap(_.keys).distinct.map { key
@@ -116,6 +115,23 @@ class CaseMergeSrv @Inject() (
116115
JsObject(mergedMetrics)
117116
}
118117

118+
private[services] def mergeCustomFields(cases: Seq[Case]): JsObject = {
119+
val customFields = for {
120+
caze cases
121+
customFieldsObject caze.customFields().asOpt[JsObject]
122+
} yield customFieldsObject
123+
124+
val mergedCustomFieldsObject: Seq[(String, JsValue)] = customFields.flatMap(_.keys).distinct.map { key
125+
val customFieldsValues = customFields.flatMap(cf (cf \ key).asOpt[JsObject]).distinct
126+
if (customFieldsValues.size != 1)
127+
key JsNull
128+
else
129+
key customFieldsValues.head
130+
}
131+
132+
JsObject(mergedCustomFieldsObject)
133+
}
134+
119135
private[services] def baseFields(entity: BaseEntity): Fields = Fields(entity.attributes - "_id" - "_routing" - "_parent" - "_type" - "createdBy" - "createdAt" - "updatedBy" - "updatedAt" - "user")
120136

121137
private[services] def mergeLogs(oldTask: Task, newTask: Task)(implicit authContext: AuthContext): Future[Done] = {
@@ -253,6 +269,7 @@ class CaseMergeSrv @Inject() (
253269
.set("tlp", JsNumber(cases.map(_.tlp()).max))
254270
.set("status", JsString(CaseStatus.Open.toString))
255271
.set("metrics", mergeMetrics(cases))
272+
.set("customFields", mergeCustomFields(cases))
256273
.set("resolutionStatus", mergeResolutionStatus(cases))
257274
.set("impactStatus", mergeImpactStatus(cases))
258275
.set("summary", mergeSummary(cases))

0 commit comments

Comments
 (0)