-
Notifications
You must be signed in to change notification settings - Fork 640
/
Copy pathJsonFormat.scala
106 lines (96 loc) · 3.94 KB
/
JsonFormat.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package connectors.misp
import java.util.Date
import play.api.libs.json.JsLookupResult.jsLookupResultToJsLookup
import play.api.libs.json.JsValue.jsValueToJsLookup
import play.api.libs.json._
import org.elastic4play.services.JsonFormat.attachmentFormat
object JsonFormat {
implicit val mispAlertReads: Reads[MispAlert] = Reads[MispAlert] { json =>
for {
org <- (json \ "Orgc" \ "name").validate[String]
info <- (json \ "info").validate[String]
eventId <- (json \ "id").validate[String]
optTags <- (json \ "EventTag").validateOpt[Seq[JsValue]]
tags = optTags.toSeq.flatten.flatMap(t => (t \ "Tag" \ "name").asOpt[String])
tlp = tags
.map(_.toLowerCase)
.collectFirst {
case "tlp:white" => 0L
case "tlp:green" => 1L
case "tlp:amber" => 2L
case "tlp:red" => 3L
}
.getOrElse(2L)
alertTags = s"src:$org" +: tags.filterNot(_.toLowerCase.startsWith("tlp:"))
timestamp <- (json \ "timestamp").validate[String]
date = new Date(timestamp.toLong * 1000)
publishTimestamp <- (json \ "publish_timestamp").validate[String]
publishDate = new Date(publishTimestamp.toLong * 1000)
threatLevelString <- (json \ "threat_level_id").validate[String]
threatLevel = threatLevelString.toLong
isPublished <- (json \ "published").validate[Boolean]
extendsUuid = (json \ "extends_uuid").asOpt[String]
} yield MispAlert(
org,
eventId,
date,
publishDate,
isPublished,
extendsUuid,
s"#$eventId ${info.trim}",
s"Imported from MISP Event #$eventId, created at $date",
if (0 < threatLevel && threatLevel < 4) 4 - threatLevel else 2,
alertTags,
tlp,
""
)
}
implicit val mispAlertWrites: Writes[MispAlert] =
Json.writes[MispAlert].transform((_: JsValue).asInstanceOf[JsObject] - "isPublished" - "extendsUuid")
implicit val attributeReads: Reads[MispAttribute] = Reads(
json =>
for {
id <- (json \ "id").validate[String]
tpe <- (json \ "type").validate[String]
timestamp <- (json \ "timestamp").validate[String]
date = new Date(timestamp.toLong * 1000)
comment <- (json \ "comment").validate[String].orElse(JsSuccess(""))
value <- (json \ "value").validate[String]
category <- (json \ "category").validate[String]
tags <- JsArray(json \ "EventTag" \\ "name").validate[Seq[String]]
toIds <- (json \ "to_ids").validate[Boolean]
} yield MispAttribute(id, category, tpe, date, comment, value, tags, toIds)
)
val tlpWrites: Writes[Long] = Writes[Long] {
case 0 => JsString("tlp:white")
case 1 => JsString("tlp:green")
case 2 => JsString("tlp:amber")
case 3 => JsString("tlp:red")
case _ => JsString("tlp:amber")
}
implicit val exportedAttributeWrites: Writes[ExportedMispAttribute] = Writes[ExportedMispAttribute] { attribute =>
Json.obj(
"category" -> attribute.category,
"type" -> attribute.tpe,
"value" -> attribute.value.fold[String](identity, _.name),
"comment" -> attribute.comment,
"Tag" -> Json.arr(Json.obj("name" -> tlpWrites.writes(attribute.tlp))),
"to_ids" -> attribute.artifact.ioc()
)
}
implicit val mispArtifactWrites: Writes[MispArtifact] = OWrites[MispArtifact] { artifact =>
Json.obj(
"dataType" -> artifact.dataType,
"message" -> artifact.message,
"tlp" -> artifact.tlp,
"tags" -> artifact.tags,
"startDate" -> artifact.startDate,
"ioc" -> artifact.ioc
) + (artifact.value match {
case SimpleArtifactData(data) => "data" -> JsString(data)
case RemoteAttachmentArtifact(filename, reference, tpe) =>
"remoteAttachment" -> Json.obj("filename" -> filename, "reference" -> reference, "type" -> tpe)
case AttachmentArtifact(attachment) => "attachment" -> Json.toJson(attachment)
})
}
}