use std::collections::HashMap;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_with::{SerializeDisplay, DeserializeFromStr};
use struct_metadata::Described;
use crate::{MD5, Sha256, Sha1, Domain, IP, Uri, ElasticMeta};
use super::workflow::{Statuses, Priorities};
#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described)]
#[metadata_type(ElasticMeta)]
#[strum(serialize_all = "lowercase")]
pub enum ExtendedScanValues {
Submitted,
Skipped,
Incomplete,
Complete,
}
#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described)]
#[metadata_type(ElasticMeta)]
#[strum(serialize_all = "lowercase")]
pub enum ItemVerdict {
Safe,
Info,
Suspicious,
Malicious,
}
#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described)]
#[metadata_type(ElasticMeta)]
#[strum(serialize_all = "lowercase")]
pub enum EntityType {
User,
Workflow,
}
#[derive(SerializeDisplay, DeserializeFromStr, strum::Display, strum::EnumString, Described)]
#[metadata_type(ElasticMeta)]
#[strum(serialize_all = "UPPERCASE")]
pub enum Subtype {
Exp,
Cfg,
Ob,
Imp,
Ta,
}
#[derive(Serialize, Deserialize, Described)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=false)]
pub struct DetailedItem {
#[serde(rename = "type")]
pub item_type: String,
pub value: String,
pub verdict: ItemVerdict,
pub subtype: Option<Subtype>,
}
#[derive(Serialize, Deserialize, Described)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=false)]
pub struct DetailedResults {
#[serde(default)]
pub attack_pattern: Vec<DetailedItem>,
#[serde(default)]
pub attack_category: Vec<DetailedItem>,
#[serde(default)]
pub attrib: Vec<DetailedItem>,
#[serde(default)]
pub av: Vec<DetailedItem>,
#[serde(default)]
pub behavior: Vec<DetailedItem>,
#[serde(default)]
pub domain: Vec<DetailedItem>,
#[serde(default)]
pub heuristic: Vec<DetailedItem>,
#[serde(default)]
pub ip: Vec<DetailedItem>,
#[serde(default)]
pub uri: Vec<DetailedItem>,
#[serde(default)]
pub yara: Vec<DetailedItem>,
}
#[derive(Serialize, Deserialize, Described)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=false)]
pub struct ALResults {
#[serde(default)]
#[metadata(store=true, copyto="__text__")]
pub attrib: Vec<String>,
#[serde(default)]
#[metadata(store=true, copyto="__text__")]
pub av: Vec<String>,
#[serde(default)]
#[metadata(copyto="__text__")]
pub behavior: Vec<String>,
pub detailed: DetailedResults,
#[serde(default)]
#[metadata(copyto="__text__")]
pub domain: Vec<Domain>,
#[serde(default)]
pub domain_dynamic: Vec<Domain>,
#[serde(default)]
pub domain_static: Vec<Domain>,
#[serde(default)]
#[metadata(copyto="__text__")]
pub ip: Vec<IP>,
#[serde(default)]
pub ip_dynamic: Vec<IP>,
#[serde(default)]
pub ip_static: Vec<IP>,
#[serde(default)]
#[metadata(index=false)]
pub request_end_time: DateTime<Utc>,
#[serde(default)]
#[metadata(store=true)]
pub score: i64,
#[serde(default)]
#[metadata(copyto="__text__")]
pub uri: Vec<Uri>,
#[serde(default)]
pub uri_dynamic: Vec<Uri>,
#[serde(default)]
pub uri_static: Vec<Uri>,
#[serde(default)]
#[metadata(copyto="__text__")]
pub yara: Vec<String>,
}
#[derive(Serialize, Deserialize, Described)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=true)]
pub struct File {
#[metadata(copyto="__text__")]
pub md5: MD5,
#[metadata(copyto="__text__")]
pub name: String,
#[metadata(copyto="__text__")]
pub sha1: Sha1,
#[metadata(copyto="__text__")]
pub sha256: Sha256,
#[metadata(store=false)]
pub size: u64,
#[serde(rename = "type")]
#[metadata(copyto="__text__")]
pub file_type: String,
}
#[derive(Serialize, Deserialize, Default, Described)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=false)]
pub struct Verdict {
#[serde(default)]
pub malicious: Vec<String>,
#[serde(default)]
pub non_malicious: Vec<String>,
}
#[derive(Serialize, Deserialize, Described)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=false)]
pub struct Heuristic {
#[serde(default)]
pub name: Vec<String>,
}
#[derive(Serialize, Deserialize, Described)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=false)]
pub struct Attack {
#[serde(default)]
pub pattern: Vec<String>,
#[serde(default)]
pub category: Vec<String>,
}
#[derive(Serialize, Deserialize, Described)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=true)]
pub struct Event {
pub entity_type: EntityType,
pub entity_id: String,
pub entity_name: String,
pub ts: DateTime<Utc>,
pub labels: Vec<String>,
pub status: Option<Statuses>,
pub priority: Option<Priorities>,
}
#[derive(Serialize, Deserialize, Described)]
#[metadata_type(ElasticMeta)]
#[metadata(index=true, store=true)]
pub struct Alert {
#[metadata(copyto="__text__")]
pub alert_id: String,
pub al: ALResults,
pub attack: Attack,
pub classification: String,
#[metadata(store=false)]
pub expiry_ts: Option<DateTime<Utc>>,
pub extended_scan: ExtendedScanValues,
pub file: File,
#[serde(default)]
pub filtered: bool,
pub heuristic: Heuristic,
#[serde(default)]
#[metadata(copyto="__text__")]
pub label: Vec<String>,
#[serde(default)]
#[metadata(store=false)]
pub metadata: HashMap<String, String>,
pub owner: Option<String>,
pub priority: Option<Priorities>,
pub reporting_ts: DateTime<Utc>,
pub sid: String,
pub status: Option<Statuses>,
pub ts: DateTime<Utc>,
#[serde(rename = "type")]
pub alert_type: String,
#[serde(default)]
pub verdict: Verdict,
#[serde(default)]
pub events: Vec<Event>,
#[serde(default)]
pub workflows_completed: bool,
}