Skip to content

Commit 95c9900

Browse files
committed
#237 Migrate MISP alert file
1 parent f84eafd commit 95c9900

File tree

1 file changed

+47
-20
lines changed

1 file changed

+47
-20
lines changed

thehive-backend/app/models/Migration.scala

+47-20
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import akka.NotUsed
77
import akka.stream.Materializer
88
import akka.stream.scaladsl.Source
99
import org.elastic4play.models.BaseModelDef
10-
import org.elastic4play.services._
1110
import org.elastic4play.services.JsonFormat.attachmentFormat
11+
import org.elastic4play.services._
1212
import org.elastic4play.utils
1313
import org.elastic4play.utils.{ Hasher, RichJson }
1414
import play.api.libs.json.JsValue.jsValueToJsLookup
@@ -164,26 +164,47 @@ class Migration(
164164
Operation((f: String Source[JsObject, NotUsed]) {
165165
case "alert" f("alert").flatMapConcat { alert
166166
val artifactsAndData = Future.traverse((alert \ "artifacts").asOpt[List[JsObject]].getOrElse(Nil)) { artifact
167-
(artifact \ "data").asOpt[String]
168-
.collect {
169-
case AlertSrv.dataExtractor(filename, contentType, data @ Base64(rawData))
170-
val attachmentId = mainHasher.fromByteArray(rawData).head.toString()
171-
ds.getEntity(datastoreName, s"${attachmentId}_0")
172-
.map(_ Nil)
173-
.recover {
174-
case _ if containsOrAdd(attachmentId) Nil
175-
case _
176-
Seq(Json.obj(
177-
"_type" datastoreName,
178-
"_id" s"${attachmentId}_0",
179-
"data" data))
180-
}
181-
.map { dataEntity
182-
val attachment = Attachment(filename, extraHashers.fromByteArray(rawData), rawData.length.toLong, contentType, attachmentId)
183-
(artifact - "data" + ("attachment" Json.toJson(attachment))) dataEntity
167+
val isFile = (artifact \ "dataType").asOpt[String].contains("file")
168+
// get MISP attachment
169+
if (!isFile)
170+
Future.successful(artifact Nil)
171+
else {
172+
(for {
173+
dataStr (artifact \ "data").asOpt[String]
174+
dataJson Try(Json.parse(dataStr)).toOption
175+
dataObj dataJson.asOpt[JsObject]
176+
filename (dataObj \ "filename").asOpt[String].map(_.split("|").head)
177+
attributeId (dataObj \ "attributeId").asOpt[String]
178+
attributeType (dataObj \ "attributeType").asOpt[String]
179+
} yield Future.successful((artifact - "data" + ("remoteAttachment" Json.obj(
180+
"reference" attributeId,
181+
"filename" filename,
182+
"type" attributeType))) Nil))
183+
.orElse {
184+
(artifact \ "data").asOpt[String]
185+
.collect {
186+
// get attachment encoded in data field
187+
case AlertSrv.dataExtractor(filename, contentType, data @ Base64(rawData))
188+
val attachmentId = mainHasher.fromByteArray(rawData).head.toString()
189+
ds.getEntity(datastoreName, s"${attachmentId}_0")
190+
.map(_ Nil)
191+
.recover {
192+
case _ if containsOrAdd(attachmentId) Nil
193+
case _
194+
Seq(Json.obj(
195+
"_type" datastoreName,
196+
"_id" s"${attachmentId}_0",
197+
"data" data))
198+
}
199+
.map { dataEntity
200+
val attachment = Attachment(filename, extraHashers.fromByteArray(rawData), rawData.length.toLong, contentType, attachmentId)
201+
(artifact - "data" + ("attachment" Json.toJson(attachment))) dataEntity
202+
}
184203
}
185-
}
186-
.getOrElse(Future.successful(artifact Nil))
204+
205+
}
206+
.getOrElse(Future.successful(artifact Nil))
207+
}
187208
}
188209
Source.fromFuture(artifactsAndData)
189210
.mapConcat { ad
@@ -206,6 +227,12 @@ class Migration(
206227
dblist + ("value" value)
207228
}
208229
case other other
230+
},
231+
// Add empty metrics and custom fields in cases
232+
mapEntity("case") { caze
233+
val metrics = (caze \ "metrics").asOpt[JsObject].getOrElse(JsObject(Nil))
234+
val customFields = (caze \ "customFields").asOpt[JsObject].getOrElse(JsObject(Nil))
235+
caze + ("metrics" metrics) + ("customFields" customFields)
209236
})
210237
}
211238

0 commit comments

Comments
 (0)