usiem/components/dataset/
mod.rs

1pub mod calendar;
2pub mod geo_ip;
3pub mod holder;
4pub mod i18n;
5pub mod ip_map;
6pub mod ip_map_list;
7pub mod ip_net;
8pub mod ip_set;
9pub mod rules;
10pub mod text_map;
11pub mod text_map_list;
12pub mod text_set;
13
14use crate::prelude::types::LogString;
15use calendar::{CalendarSynDataset, UpdateCalendar};
16use geo_ip::{GeoIpSynDataset, UpdateGeoIp};
17use i18n::{I18nSynDataset, UpdateI18n};
18use ip_map::{IpMapSynDataset, UpdateIpMap};
19use ip_map_list::{IpMapListSynDataset, UpdateIpMapList};
20use ip_net::{IpNetSynDataset, UpdateNetIp};
21use ip_set::{IpSetSynDataset, UpdateIpSet};
22use serde::ser::{SerializeStruct, Serializer};
23use serde::{Deserialize, Serialize};
24use std::cmp::Ordering;
25use std::convert::TryFrom;
26use std::fmt;
27use text_map::{TextMapSynDataset, UpdateTextMap};
28use text_map_list::{TextMapListSynDataset, UpdateTextMapList};
29use text_set::{TextSetSynDataset, UpdateTextSet};
30
31/// Commonly used datasets. They are filled with the information extracted form logs, from the CMDB, from user commands or from repetitive Task like GeoIP.
32/// Dataset are used, but not exclusivally, in the enrichment phase.
33///
34#[derive(Debug, Clone)]
35#[non_exhaustive]
36pub enum SiemDataset {
37    /// Correlation Rules that can be updated in real-time
38    CorrelationRules(GeoIpSynDataset),
39    /// Map IP to country, city, latitude and longitude
40    GeoIp(GeoIpSynDataset),
41    /// IP associated with a MAC address
42    IpMac(IpMapSynDataset),
43    /// IP associated with a resolved domain
44    IpDNS(IpMapListSynDataset),
45    /// MAC address associated with a Hostname
46    MacHost(TextMapSynDataset),
47    /// Hostname associated with a username
48    HostUser(TextMapSynDataset),
49    /// List of IPs in the block list
50    BlockIp(IpSetSynDataset),
51    /// List of domain in the block list
52    BlockDomain(TextSetSynDataset),
53    /// List of email senders in the block list
54    BlockEmailSender(TextSetSynDataset),
55    /// List of countries in the block list
56    BlockCountry(TextSetSynDataset),
57    /// Association of hostname with a vulnerability.
58    HostVulnerable(TextMapListSynDataset),
59    /// Tag each user with roles => user.roles = [vip, admin, extern, guest, director, super_user, local_user]
60    UserTag(TextMapListSynDataset),
61    /// Tag each host with categories => [web_server, sec_related, critical, ad_related, net_related]
62    AssetTag(TextMapListSynDataset),
63    /// Cloud service => Office 365, G Suit ...
64    IpCloudService(IpNetSynDataset),
65    /// Cloud Provider => Azure, Google Cloud, AWS
66    IpCloudProvider(IpNetSynDataset),
67    /// User associated with a headquarter
68    UserHeadquarters(TextMapSynDataset),
69    /// IP net associated with a headquarter
70    IpHeadquarters(IpNetSynDataset),
71    /// Working hours of each headquarter
72    HeadquartersWorkingHours,
73    /// User custom dataset IP_NET => Text
74    CustomMapIpNet((LogString, IpNetSynDataset)),
75    /// User custom dataset Text => Text
76    CustomMapText((LogString, TextMapSynDataset)),
77    /// User custom dataset Text => Text
78    CustomMapTextList((LogString, TextMapListSynDataset)),
79    /// User custom dataset IP list
80    CustomIpList((LogString, IpSetSynDataset)),
81    /// User custom dataset IP list
82    CustomIpMap((LogString, IpMapSynDataset)),
83    /// User custom dataset Text list
84    CustomTextList((LogString, TextSetSynDataset)),
85    /// Mantaince Calendar
86    MantainceCalendar(CalendarSynDataset),
87    /// Configuration of components. Allows modifications of component parameters in real time.
88    Configuration(TextMapSynDataset),
89    /// Internacionalization of SIEM texts
90    I18n(I18nSynDataset),
91    /// Secret store. A component will only be able to access his own secrets.
92    Secrets((LogString, TextMapSynDataset)),
93}
94
95impl SiemDataset {
96    /// Creates an empty CustomMapIpNet. Used only for testing.
97    pub fn empty_custom_map_ip_net<S: Into<LogString>>(name: S) -> Self {
98        SiemDataset::CustomMapIpNet((name.into(), IpNetSynDataset::empty()))
99    }
100    /// Creates an empty CustomMapText. Used only for testing.
101    pub fn empty_custom_map_text<S: Into<LogString>>(name: S) -> Self {
102        SiemDataset::CustomMapText((name.into(), TextMapSynDataset::empty()))
103    }
104    /// Creates an empty CustomMapTextList. Used only for testing.
105    pub fn empty_custom_map_text_list<S: Into<LogString>>(name: S) -> Self {
106        SiemDataset::CustomMapTextList((name.into(), TextMapListSynDataset::empty()))
107    }
108    /// Creates an empty CustomIpList. Used only for testing.
109    pub fn empty_custom_ip_list<S: Into<LogString>>(name: S) -> Self {
110        SiemDataset::CustomIpList((name.into(), IpSetSynDataset::empty()))
111    }
112    /// Creates an empty CustomIpMap. Used only for testing.
113    pub fn empty_custom_ip_map<S: Into<LogString>>(name: S) -> Self {
114        SiemDataset::CustomIpMap((name.into(), IpMapSynDataset::empty()))
115    }
116    /// Creates an empty CustomTextList. Used only for testing.
117    pub fn empty_custom_ip_text_list<S: Into<LogString>>(name: S) -> Self {
118        SiemDataset::CustomTextList((name.into(), TextSetSynDataset::empty()))
119    }
120}
121
122/// Tries to cast a SiemDataset into a CustomMapIpNet with the defined name
123///
124/// # Example
125///
126/// ```rust
127/// use usiem::components::dataset::{SiemDataset, try_to_custom_map_ip_net_ref, ip_net::IpNetSynDataset};
128/// let dataset = SiemDataset::empty_custom_map_ip_net("MyDataset");
129/// let casted_dataset : &IpNetSynDataset = try_to_custom_map_ip_net_ref(&dataset, "MyDataset").unwrap();
130/// ```
131pub fn try_to_custom_map_ip_net_ref<'a>(
132    dataset: &'a SiemDataset,
133    name: &str,
134) -> Result<&'a IpNetSynDataset, &'static str> {
135    match dataset {
136        SiemDataset::CustomMapIpNet((n, dataset)) => {
137            if n == name {
138                Ok(dataset)
139            } else {
140                Err("Cannot cast dataset")
141            }
142        }
143        _ => Err("Cannot cast dataset"),
144    }
145}
146/// Tries to cast a SiemDataset into a CustomMapIpNet with the defined name
147///
148/// # Example
149///
150/// ```rust
151/// use usiem::components::dataset::{SiemDataset, try_to_custom_map_ip_net, ip_net::IpNetSynDataset};
152/// let dataset = SiemDataset::empty_custom_map_ip_net("MyDataset");
153/// let casted_dataset : IpNetSynDataset = try_to_custom_map_ip_net(dataset, "MyDataset").unwrap();
154/// ```
155pub fn try_to_custom_map_ip_net(
156    dataset: SiemDataset,
157    name: &str,
158) -> Result<IpNetSynDataset, &'static str> {
159    match dataset {
160        SiemDataset::CustomMapIpNet((n, dataset)) => {
161            if n == name {
162                Ok(dataset)
163            } else {
164                Err("Cannot cast dataset")
165            }
166        }
167        _ => Err("Cannot cast dataset"),
168    }
169}
170/// Tries to cast a SiemDataset into a CustomMapText with the defined name
171///
172/// # Example
173///
174/// ```rust
175/// use usiem::components::dataset::{SiemDataset, try_to_custom_map_text_ref, text_map::TextMapSynDataset};
176/// let dataset = SiemDataset::empty_custom_map_text("MyDataset");
177/// let casted_dataset : &TextMapSynDataset = try_to_custom_map_text_ref(&dataset, "MyDataset").unwrap();
178/// ```
179pub fn try_to_custom_map_text_ref<'a>(
180    dataset: &'a SiemDataset,
181    name: &str,
182) -> Result<&'a TextMapSynDataset, &'static str> {
183    match dataset {
184        SiemDataset::CustomMapText((n, dataset)) => {
185            if n == name {
186                Ok(dataset)
187            } else {
188                Err("Cannot cast dataset")
189            }
190        }
191        _ => Err("Cannot cast dataset"),
192    }
193}
194/// Tries to cast a SiemDataset into a CustomMapText with the defined name
195///
196/// # Example
197///
198/// ```rust
199/// use usiem::components::dataset::{SiemDataset, try_to_custom_map_text, text_map::TextMapSynDataset};
200/// let dataset = SiemDataset::empty_custom_map_text("MyDataset");
201/// let casted_dataset : TextMapSynDataset = try_to_custom_map_text(dataset, "MyDataset").unwrap();
202/// ```
203pub fn try_to_custom_map_text(
204    dataset: SiemDataset,
205    name: &str,
206) -> Result<TextMapSynDataset, &'static str> {
207    match dataset {
208        SiemDataset::CustomMapText((n, dataset)) => {
209            if n == name {
210                Ok(dataset)
211            } else {
212                Err("Cannot cast dataset")
213            }
214        }
215        _ => Err("Cannot cast dataset"),
216    }
217}
218/// Tries to cast a SiemDataset into a CustomMapTextList with the defined name
219///
220/// # Example
221///
222/// ```rust
223/// use usiem::components::dataset::{SiemDataset, try_to_custom_map_text_list_ref, text_map_list::TextMapListSynDataset};
224/// let dataset = SiemDataset::empty_custom_map_text_list("MyDataset");
225/// let casted_dataset : &TextMapListSynDataset = try_to_custom_map_text_list_ref(&dataset, "MyDataset").unwrap();
226/// ```
227pub fn try_to_custom_map_text_list_ref<'a>(
228    dataset: &'a SiemDataset,
229    name: &str,
230) -> Result<&'a TextMapListSynDataset, &'static str> {
231    match dataset {
232        SiemDataset::CustomMapTextList((n, dataset)) => {
233            if n == name {
234                Ok(dataset)
235            } else {
236                Err("Cannot cast dataset")
237            }
238        }
239        _ => Err("Cannot cast dataset"),
240    }
241}
242/// Tries to cast a SiemDataset into a CustomMapTextList with the defined name
243///
244/// # Example
245///
246/// ```rust
247/// use usiem::components::dataset::{SiemDataset, try_to_custom_map_text_list, text_map_list::TextMapListSynDataset};
248/// let dataset = SiemDataset::empty_custom_map_text_list("MyDataset");
249/// let casted_dataset : TextMapListSynDataset = try_to_custom_map_text_list(dataset, "MyDataset").unwrap();
250/// ```
251pub fn try_to_custom_map_text_list(
252    dataset: SiemDataset,
253    name: &str,
254) -> Result<TextMapListSynDataset, &'static str> {
255    match dataset {
256        SiemDataset::CustomMapTextList((n, dataset)) => {
257            if n == name {
258                Ok(dataset)
259            } else {
260                Err("Cannot cast dataset")
261            }
262        }
263        _ => Err("Cannot cast dataset"),
264    }
265}
266
267/// Tries to cast a SiemDataset into a CustomIpList with the defined name
268///
269/// # Example
270///
271/// ```rust
272/// use usiem::components::dataset::{SiemDataset, try_to_custom_ip_list_ref, ip_set::IpSetSynDataset};
273/// let dataset = SiemDataset::empty_custom_ip_list("MyDataset");
274/// let casted_dataset : &IpSetSynDataset = try_to_custom_ip_list_ref(&dataset, "MyDataset").unwrap();
275/// ```
276pub fn try_to_custom_ip_list_ref<'a>(
277    dataset: &'a SiemDataset,
278    name: &str,
279) -> Result<&'a IpSetSynDataset, &'static str> {
280    match dataset {
281        SiemDataset::CustomIpList((n, dataset)) => {
282            if n == name {
283                Ok(dataset)
284            } else {
285                Err("Cannot cast dataset")
286            }
287        }
288        _ => Err("Cannot cast dataset"),
289    }
290}
291/// Tries to cast a SiemDataset into a CustomIpList with the defined name
292///
293/// # Example
294///
295/// ```rust
296/// use usiem::components::dataset::{SiemDataset, try_to_custom_ip_list, ip_set::IpSetSynDataset};
297/// let dataset = SiemDataset::empty_custom_ip_list("MyDataset");
298/// let casted_dataset : IpSetSynDataset = try_to_custom_ip_list(dataset, "MyDataset").unwrap();
299/// ```
300pub fn try_to_custom_ip_list(
301    dataset: SiemDataset,
302    name: &str,
303) -> Result<IpSetSynDataset, &'static str> {
304    match dataset {
305        SiemDataset::CustomIpList((n, dataset)) => {
306            if n == name {
307                Ok(dataset)
308            } else {
309                Err("Cannot cast dataset")
310            }
311        }
312        _ => Err("Cannot cast dataset"),
313    }
314}
315/// Tries to cast a SiemDataset into a CustomIpMap with the defined name
316///
317/// # Example
318///
319/// ```rust
320/// use usiem::components::dataset::{SiemDataset, try_to_custom_ip_map_ref, ip_map::IpMapSynDataset};
321/// let dataset = SiemDataset::empty_custom_ip_map("MyDataset");
322/// let casted_dataset : &IpMapSynDataset = try_to_custom_ip_map_ref(&dataset, "MyDataset").unwrap();
323/// ```
324pub fn try_to_custom_ip_map_ref<'a>(
325    dataset: &'a SiemDataset,
326    name: &str,
327) -> Result<&'a IpMapSynDataset, &'static str> {
328    match dataset {
329        SiemDataset::CustomIpMap((n, dataset)) => {
330            if n == name {
331                Ok(dataset)
332            } else {
333                Err("Cannot cast dataset")
334            }
335        }
336        _ => Err("Cannot cast dataset"),
337    }
338}
339/// Tries to cast a SiemDataset into a CustomIpMap with the defined name
340///
341/// # Example
342///
343/// ```rust
344/// use usiem::components::dataset::{SiemDataset, try_to_custom_ip_map, ip_map::IpMapSynDataset};
345/// let dataset = SiemDataset::empty_custom_ip_map("MyDataset");
346/// let casted_dataset : IpMapSynDataset = try_to_custom_ip_map(dataset, "MyDataset").unwrap();
347/// ```
348pub fn try_to_custom_ip_map(
349    dataset: SiemDataset,
350    name: &str,
351) -> Result<IpMapSynDataset, &'static str> {
352    match dataset {
353        SiemDataset::CustomIpMap((n, dataset)) => {
354            if n == name {
355                Ok(dataset)
356            } else {
357                Err("Cannot cast dataset")
358            }
359        }
360        _ => Err("Cannot cast dataset"),
361    }
362}
363/// Tries to cast a SiemDataset into a CustomIpMap with the defined name
364///
365/// # Example
366///
367/// ```rust
368/// use usiem::components::dataset::{SiemDataset, try_to_custom_text_list_ref, text_set::TextSetSynDataset};
369/// let dataset = SiemDataset::empty_custom_ip_text_list("MyDataset");
370/// let casted_dataset : &TextSetSynDataset = try_to_custom_text_list_ref(&dataset, "MyDataset").unwrap();
371/// ```
372pub fn try_to_custom_text_list_ref<'a>(
373    dataset: &'a SiemDataset,
374    name: &str,
375) -> Result<&'a TextSetSynDataset, &'static str> {
376    match dataset {
377        SiemDataset::CustomTextList((n, dataset)) => {
378            if n == name {
379                Ok(dataset)
380            } else {
381                Err("Cannot cast dataset")
382            }
383        }
384        _ => Err("Cannot cast dataset"),
385    }
386}
387/// Tries to cast a SiemDataset into a CustomIpMap with the defined name
388///
389/// # Example
390///
391/// ```rust
392/// use usiem::components::dataset::{SiemDataset, try_to_custom_text_list, text_set::TextSetSynDataset};
393/// let dataset = SiemDataset::empty_custom_ip_text_list("MyDataset");
394/// let casted_dataset : TextSetSynDataset = try_to_custom_text_list(dataset, "MyDataset").unwrap();
395/// ```
396pub fn try_to_custom_text_list(
397    dataset: SiemDataset,
398    name: &str,
399) -> Result<TextSetSynDataset, &'static str> {
400    match dataset {
401        SiemDataset::CustomTextList((n, dataset)) => {
402            if n == name {
403                Ok(dataset)
404            } else {
405                Err("Cannot cast dataset")
406            }
407        }
408        _ => Err("Cannot cast dataset"),
409    }
410}
411
412impl TryFrom<(SiemDatasetType, GeoIpSynDataset)> for SiemDataset {
413    type Error = &'static str;
414
415    fn try_from(value: (SiemDatasetType, GeoIpSynDataset)) -> Result<Self, Self::Error> {
416        if value.0 == SiemDatasetType::GeoIp {
417            Err("GeoIPSynDataset is only valid for GeoIP dataset!")
418        } else {
419            Ok(SiemDataset::GeoIp(value.1))
420        }
421    }
422}
423impl TryFrom<SiemDataset> for GeoIpSynDataset {
424    type Error = &'static str;
425
426    fn try_from(value: SiemDataset) -> Result<Self, Self::Error> {
427        if let SiemDataset::GeoIp(geoip) = value {
428            Ok(geoip)
429        } else {
430            Err("GeoIPSynDataset is only valid for GeoIP dataset!")
431        }
432    }
433}
434impl<'a> TryFrom<&'a SiemDataset> for &'a GeoIpSynDataset {
435    type Error = &'static str;
436
437    fn try_from(value: &'a SiemDataset) -> Result<Self, Self::Error> {
438        if let SiemDataset::GeoIp(geoip) = value {
439            Ok(geoip)
440        } else {
441            Err("GeoIPSynDataset is only valid for GeoIP dataset!")
442        }
443    }
444}
445
446impl TryFrom<(SiemDatasetType, IpMapSynDataset)> for SiemDataset {
447    type Error = &'static str;
448
449    fn try_from(value: (SiemDatasetType, IpMapSynDataset)) -> Result<Self, Self::Error> {
450        match value.0 {
451            SiemDatasetType::IpMac => Ok(SiemDataset::IpMac(value.1)),
452            SiemDatasetType::CustomIpMap(name) => {
453                Ok(SiemDataset::CustomIpMap((name.clone(), value.1)))
454            }
455            _ => Err("IpMapSynDataset not valid for this type"),
456        }
457    }
458}
459impl TryFrom<SiemDataset> for IpMapSynDataset {
460    type Error = &'static str;
461
462    fn try_from(value: SiemDataset) -> Result<Self, Self::Error> {
463        match value {
464            SiemDataset::IpMac(v) => Ok(v),
465            SiemDataset::CustomIpMap((_name, v)) => Ok(v),
466            _ => Err("IpMapSynDataset not valid for this type"),
467        }
468    }
469}
470impl<'a> TryFrom<&'a SiemDataset> for &'a IpMapSynDataset {
471    type Error = &'static str;
472
473    fn try_from(value: &'a SiemDataset) -> Result<Self, Self::Error> {
474        match value {
475            SiemDataset::IpMac(v) => Ok(v),
476            SiemDataset::CustomIpMap((_name, v)) => Ok(v),
477            _ => Err("IpMapSynDataset not valid for this type"),
478        }
479    }
480}
481
482impl TryFrom<(SiemDatasetType, TextMapSynDataset)> for SiemDataset {
483    type Error = &'static str;
484
485    fn try_from(value: (SiemDatasetType, TextMapSynDataset)) -> Result<Self, Self::Error> {
486        match value.0 {
487            SiemDatasetType::MacHost => Ok(SiemDataset::MacHost(value.1)),
488            SiemDatasetType::HostUser => Ok(SiemDataset::HostUser(value.1)),
489            SiemDatasetType::UserHeadquarters => Ok(SiemDataset::UserHeadquarters(value.1)),
490            SiemDatasetType::Configuration => Ok(SiemDataset::Configuration(value.1)),
491            SiemDatasetType::CustomMapText(name) => {
492                Ok(SiemDataset::CustomMapText((name.clone(), value.1)))
493            }
494            SiemDatasetType::Secrets(name) => Ok(SiemDataset::Secrets((name.clone(), value.1))),
495            _ => Err("TextMapSynDataset not valid for this type"),
496        }
497    }
498}
499impl TryFrom<SiemDataset> for TextMapSynDataset {
500    type Error = &'static str;
501
502    fn try_from(value: SiemDataset) -> Result<Self, Self::Error> {
503        match value {
504            SiemDataset::MacHost(v) => Ok(v),
505            SiemDataset::HostUser(v) => Ok(v),
506            SiemDataset::UserHeadquarters(v) => Ok(v),
507            SiemDataset::Configuration(v) => Ok(v),
508            SiemDataset::CustomMapText((_name, v)) => Ok(v),
509            SiemDataset::Secrets((_name, v)) => Ok(v),
510            _ => Err("TextMapSynDataset not valid for this type"),
511        }
512    }
513}
514impl<'a> TryFrom<&'a SiemDataset> for &'a TextMapSynDataset {
515    type Error = &'static str;
516
517    fn try_from(value: &'a SiemDataset) -> Result<Self, Self::Error> {
518        match value {
519            SiemDataset::MacHost(v) => Ok(v),
520            SiemDataset::HostUser(v) => Ok(v),
521            SiemDataset::UserHeadquarters(v) => Ok(v),
522            SiemDataset::Configuration(v) => Ok(v),
523            SiemDataset::CustomMapText((_name, v)) => Ok(v),
524            SiemDataset::Secrets((_name, v)) => Ok(v),
525            _ => Err("TextMapSynDataset not valid for this type"),
526        }
527    }
528}
529
530impl TryFrom<(SiemDatasetType, IpMapListSynDataset)> for SiemDataset {
531    type Error = &'static str;
532
533    fn try_from(value: (SiemDatasetType, IpMapListSynDataset)) -> Result<Self, Self::Error> {
534        match value.0 {
535            SiemDatasetType::IpDNS => Ok(SiemDataset::IpDNS(value.1)),
536            _ => Err("IpMapSynDataset not valid for this type"),
537        }
538    }
539}
540impl TryFrom<SiemDataset> for IpMapListSynDataset {
541    type Error = &'static str;
542
543    fn try_from(value: SiemDataset) -> Result<Self, Self::Error> {
544        match value {
545            SiemDataset::IpDNS(v) => Ok(v),
546            _ => Err("IpMapListSynDataset not valid for this type"),
547        }
548    }
549}
550impl<'a> TryFrom<&'a SiemDataset> for &'a IpMapListSynDataset {
551    type Error = &'static str;
552
553    fn try_from(value: &'a SiemDataset) -> Result<Self, Self::Error> {
554        match value {
555            SiemDataset::IpDNS(v) => Ok(v),
556            _ => Err("IpMapListSynDataset not valid for this type"),
557        }
558    }
559}
560
561impl TryFrom<(SiemDatasetType, IpSetSynDataset)> for SiemDataset {
562    type Error = &'static str;
563
564    fn try_from(value: (SiemDatasetType, IpSetSynDataset)) -> Result<Self, Self::Error> {
565        match value.0 {
566            SiemDatasetType::BlockIp => Ok(SiemDataset::BlockIp(value.1)),
567            SiemDatasetType::CustomIpList(name) => {
568                Ok(SiemDataset::CustomIpList((name.clone(), value.1)))
569            }
570            _ => Err("IpMapSynDataset not valid for this type"),
571        }
572    }
573}
574impl TryFrom<SiemDataset> for IpSetSynDataset {
575    type Error = &'static str;
576
577    fn try_from(value: SiemDataset) -> Result<Self, Self::Error> {
578        match value {
579            SiemDataset::BlockIp(v) => Ok(v),
580            SiemDataset::CustomIpList((_name, v)) => Ok(v),
581            _ => Err("IpSetSynDataset not valid for this type"),
582        }
583    }
584}
585impl<'a> TryFrom<&'a SiemDataset> for &'a IpSetSynDataset {
586    type Error = &'static str;
587
588    fn try_from(value: &'a SiemDataset) -> Result<Self, Self::Error> {
589        match value {
590            SiemDataset::BlockIp(v) => Ok(v),
591            SiemDataset::CustomIpList((_name, v)) => Ok(v),
592            _ => Err("IpSetSynDataset not valid for this type"),
593        }
594    }
595}
596
597impl TryFrom<(SiemDatasetType, TextSetSynDataset)> for SiemDataset {
598    type Error = &'static str;
599
600    fn try_from(value: (SiemDatasetType, TextSetSynDataset)) -> Result<Self, Self::Error> {
601        match value.0 {
602            SiemDatasetType::BlockDomain => Ok(SiemDataset::BlockDomain(value.1)),
603            SiemDatasetType::BlockEmailSender => Ok(SiemDataset::BlockEmailSender(value.1)),
604            SiemDatasetType::BlockCountry => Ok(SiemDataset::BlockCountry(value.1)),
605            SiemDatasetType::CustomTextList(name) => {
606                Ok(SiemDataset::CustomTextList((name.clone(), value.1)))
607            }
608            _ => Err("IpMapSynDataset not valid for this type"),
609        }
610    }
611}
612impl TryFrom<SiemDataset> for TextSetSynDataset {
613    type Error = &'static str;
614
615    fn try_from(value: SiemDataset) -> Result<Self, Self::Error> {
616        match value {
617            SiemDataset::BlockDomain(v) => Ok(v),
618            SiemDataset::BlockEmailSender(v) => Ok(v),
619            SiemDataset::BlockCountry(v) => Ok(v),
620            SiemDataset::CustomTextList((_name, v)) => Ok(v),
621            _ => Err("TextSetSynDataset not valid for this type"),
622        }
623    }
624}
625impl<'a> TryFrom<&'a SiemDataset> for &'a TextSetSynDataset {
626    type Error = &'static str;
627
628    fn try_from(value: &'a SiemDataset) -> Result<Self, Self::Error> {
629        match value {
630            SiemDataset::BlockDomain(v) => Ok(v),
631            SiemDataset::BlockEmailSender(v) => Ok(v),
632            SiemDataset::BlockCountry(v) => Ok(v),
633            SiemDataset::CustomTextList((_name, v)) => Ok(v),
634            _ => Err("TextSetSynDataset not valid for this type"),
635        }
636    }
637}
638
639impl TryFrom<(SiemDatasetType, TextMapListSynDataset)> for SiemDataset {
640    type Error = &'static str;
641
642    fn try_from(value: (SiemDatasetType, TextMapListSynDataset)) -> Result<Self, Self::Error> {
643        match value.0 {
644            SiemDatasetType::HostVulnerable => Ok(SiemDataset::HostVulnerable(value.1)),
645            SiemDatasetType::UserTag => Ok(SiemDataset::UserTag(value.1)),
646            SiemDatasetType::AssetTag => Ok(SiemDataset::AssetTag(value.1)),
647            SiemDatasetType::CustomMapTextList(name) => {
648                Ok(SiemDataset::CustomMapTextList((name.clone(), value.1)))
649            }
650            _ => Err("IpMapSynDataset not valid for this type"),
651        }
652    }
653}
654impl TryFrom<SiemDataset> for TextMapListSynDataset {
655    type Error = &'static str;
656
657    fn try_from(value: SiemDataset) -> Result<Self, Self::Error> {
658        match value {
659            SiemDataset::HostVulnerable(v) => Ok(v),
660            SiemDataset::UserTag(v) => Ok(v),
661            SiemDataset::AssetTag(v) => Ok(v),
662            SiemDataset::CustomMapTextList((_name, v)) => Ok(v),
663            _ => Err("TextMapListSynDataset not valid for this type"),
664        }
665    }
666}
667impl<'a> TryFrom<&'a SiemDataset> for &'a TextMapListSynDataset {
668    type Error = &'static str;
669
670    fn try_from(value: &'a SiemDataset) -> Result<Self, Self::Error> {
671        match value {
672            SiemDataset::HostVulnerable(v) => Ok(v),
673            SiemDataset::UserTag(v) => Ok(v),
674            SiemDataset::AssetTag(v) => Ok(v),
675            SiemDataset::CustomMapTextList((_name, v)) => Ok(v),
676            _ => Err("TextMapListSynDataset not valid for this type"),
677        }
678    }
679}
680
681impl TryFrom<(SiemDatasetType, IpNetSynDataset)> for SiemDataset {
682    type Error = &'static str;
683
684    fn try_from(value: (SiemDatasetType, IpNetSynDataset)) -> Result<Self, Self::Error> {
685        match value.0 {
686            SiemDatasetType::IpCloudService => Ok(SiemDataset::IpCloudService(value.1)),
687            SiemDatasetType::IpCloudProvider => Ok(SiemDataset::IpCloudProvider(value.1)),
688            SiemDatasetType::IpHeadquarters => Ok(SiemDataset::IpHeadquarters(value.1)),
689            SiemDatasetType::CustomMapIpNet(name) => {
690                Ok(SiemDataset::CustomMapIpNet((name.clone(), value.1)))
691            }
692            _ => Err("IpMapSynDataset not valid for this type"),
693        }
694    }
695}
696impl TryFrom<SiemDataset> for IpNetSynDataset {
697    type Error = &'static str;
698
699    fn try_from(value: SiemDataset) -> Result<Self, Self::Error> {
700        match value {
701            SiemDataset::IpCloudService(v) => Ok(v),
702            SiemDataset::IpCloudProvider(v) => Ok(v),
703            SiemDataset::IpHeadquarters(v) => Ok(v),
704            SiemDataset::CustomMapIpNet((_name, v)) => Ok(v),
705            _ => Err("IpNetSynDataset not valid for this type"),
706        }
707    }
708}
709impl<'a> TryFrom<&'a SiemDataset> for &'a IpNetSynDataset {
710    type Error = &'static str;
711
712    fn try_from(value: &'a SiemDataset) -> Result<Self, Self::Error> {
713        match value {
714            SiemDataset::IpCloudService(v) => Ok(v),
715            SiemDataset::IpCloudProvider(v) => Ok(v),
716            SiemDataset::IpHeadquarters(v) => Ok(v),
717            SiemDataset::CustomMapIpNet((_name, v)) => Ok(v),
718            _ => Err("IpNetSynDataset not valid for this type"),
719        }
720    }
721}
722
723#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
724#[non_exhaustive]
725pub enum SiemDatasetType {
726    /// Map IP to country, city, latitude and longitude
727    GeoIp,
728    /// IP associated with a MAC address
729    IpMac,
730    /// IP associated with a resolved domain
731    IpDNS,
732    /// MAC address associated with a Hostname
733    MacHost,
734    /// Hostname associated with a username
735    HostUser,
736    /// List of IPs in the block list
737    BlockIp,
738    /// List of domain in the block list
739    BlockDomain,
740    /// List of email senders in the block list
741    BlockEmailSender,
742    /// List of countries in the block list
743    BlockCountry,
744    /// Tag each user with roles => user.roles = [vip, admin, extern, guest, director, super_user, local_user]
745    UserTag,
746    /// Tag each host with categories => [web_server, sec_related, critical, ad_related, net_related]
747    AssetTag,
748    /// Cloud service => Office 365, G Suit ...
749    IpCloudService,
750    /// Cloud Provider => Azure, Google Cloud, AWS
751    IpCloudProvider,
752    /// User associated with a headquarter
753    UserHeadquarters,
754    /// IP net associated with a headquarter
755    IpHeadquarters,
756    /// Working hours of each headquarter
757    HeadquartersWorkingHours,
758    /// Vulnerabilities on a computer  
759    HostVulnerable,
760    CorrelationRules,
761    /// User custom dataset IP_NET => Text
762    CustomMapIpNet(LogString),
763    /// User custom dataset Text => Text
764    CustomMapText(LogString),
765    /// User custom dataset Text => Text[]
766    CustomMapTextList(LogString),
767    /// User custom dataset IP list
768    CustomIpList(LogString),
769    CustomIpMap(LogString),
770    /// User custom dataset Text list
771    CustomTextList(LogString),
772    /// Mantaince Calendar
773    MantainceCalendar,
774    Configuration,
775    Secrets(LogString),
776    /// Internacionalization
777    I18n,
778}
779
780impl SiemDataset {
781    pub fn dataset_type(&self) -> SiemDatasetType {
782        match self {
783            SiemDataset::CorrelationRules(_) => SiemDatasetType::CorrelationRules,
784            SiemDataset::GeoIp(_) => SiemDatasetType::GeoIp,
785            SiemDataset::IpMac(_) => SiemDatasetType::IpMac,
786            SiemDataset::IpDNS(_) => SiemDatasetType::IpDNS,
787            SiemDataset::MacHost(_) => SiemDatasetType::MacHost,
788            SiemDataset::HostUser(_) => SiemDatasetType::HostUser,
789            SiemDataset::BlockIp(_) => SiemDatasetType::BlockIp,
790            SiemDataset::BlockDomain(_) => SiemDatasetType::BlockDomain,
791            SiemDataset::BlockEmailSender(_) => SiemDatasetType::BlockEmailSender,
792            SiemDataset::BlockCountry(_) => SiemDatasetType::BlockCountry,
793            SiemDataset::UserTag(_) => SiemDatasetType::UserTag,
794            SiemDataset::AssetTag(_) => SiemDatasetType::AssetTag,
795            SiemDataset::IpCloudService(_) => SiemDatasetType::IpCloudService,
796            SiemDataset::IpCloudProvider(_) => SiemDatasetType::IpCloudProvider,
797            SiemDataset::UserHeadquarters(_) => SiemDatasetType::UserHeadquarters,
798            SiemDataset::IpHeadquarters(_) => SiemDatasetType::IpHeadquarters,
799            SiemDataset::HeadquartersWorkingHours => SiemDatasetType::HeadquartersWorkingHours,
800            SiemDataset::MantainceCalendar(_) => SiemDatasetType::MantainceCalendar,
801            SiemDataset::Configuration(_) => SiemDatasetType::Configuration,
802            SiemDataset::HostVulnerable(_) => SiemDatasetType::HostVulnerable,
803            SiemDataset::CustomMapIpNet((name, _)) => SiemDatasetType::CustomMapIpNet(name.clone()),
804            SiemDataset::CustomMapText((name, _)) => SiemDatasetType::CustomMapText(name.clone()),
805            SiemDataset::CustomIpList((name, _)) => SiemDatasetType::CustomIpList(name.clone()),
806            SiemDataset::CustomIpMap((name, _)) => SiemDatasetType::CustomIpMap(name.clone()),
807            SiemDataset::CustomTextList((name, _)) => SiemDatasetType::CustomTextList(name.clone()),
808            SiemDataset::CustomMapTextList((name, _)) => {
809                SiemDatasetType::CustomMapTextList(name.clone())
810            }
811            SiemDataset::I18n(_) => SiemDatasetType::I18n,
812            SiemDataset::Secrets((name, _)) => SiemDatasetType::Secrets(name.clone()),
813        }
814    }
815}
816impl fmt::Display for SiemDataset {
817    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
818        write!(f, "{:?}", self)
819        // or, alternatively:
820        // fmt::Debug::fmt(self, f)
821    }
822}
823impl PartialEq for SiemDataset {
824    fn eq(&self, other: &Self) -> bool {
825        self.dataset_type() == other.dataset_type()
826    }
827}
828impl Eq for SiemDataset {}
829
830impl PartialOrd for SiemDataset {
831    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
832        Some(self.cmp(other))
833    }
834}
835impl Ord for SiemDataset {
836    fn cmp(&self, other: &Self) -> Ordering {
837        self.dataset_type().cmp(&other.dataset_type())
838    }
839}
840
841impl Serialize for SiemDataset {
842    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
843    where
844        S: Serializer,
845    {
846        let mut state = serializer.serialize_struct("SiemDataset", 2)?;
847        let typ = match self {
848            SiemDataset::CorrelationRules(_) => "CorrelationRules",
849            SiemDataset::GeoIp(_) => "GeoIp",
850            SiemDataset::IpMac(_) => "IpMac",
851            SiemDataset::IpDNS(_) => "IpDNS",
852            SiemDataset::MacHost(_) => "MacHost",
853            SiemDataset::HostUser(_) => "HostUser",
854            SiemDataset::BlockIp(_) => "BlockIp",
855            SiemDataset::BlockDomain(_) => "BlockDomain",
856            SiemDataset::BlockEmailSender(_) => "BlockEmailSender",
857            SiemDataset::BlockCountry(_) => "BlockCountry",
858            SiemDataset::UserTag(_) => "UserTag",
859            SiemDataset::AssetTag(_) => "AssetTag",
860            SiemDataset::IpCloudService(_) => "IpCloudService",
861            SiemDataset::IpCloudProvider(_) => "IpCloudProvider",
862            SiemDataset::UserHeadquarters(_) => "UserHeadquarters",
863            SiemDataset::IpHeadquarters(_) => "IpHeadquarters",
864            SiemDataset::HeadquartersWorkingHours => "HeadquartersWorkingHours",
865            SiemDataset::MantainceCalendar(_) => "MantainceCalendar",
866            SiemDataset::Configuration(_) => "Configuration",
867            SiemDataset::HostVulnerable(_) => "HostVulnerable",
868            SiemDataset::I18n(_) => "I18n",
869            SiemDataset::CustomMapIpNet((name, _)) => {
870                state.serialize_field("name", name)?;
871                "CustomMapIpNet"
872            }
873            SiemDataset::CustomMapText((name, _)) => {
874                state.serialize_field("name", name)?;
875                "CustomMapText"
876            }
877            SiemDataset::CustomIpList((name, _)) => {
878                state.serialize_field("name", name)?;
879                "CustomIpList"
880            }
881            SiemDataset::CustomIpMap((name, _)) => {
882                state.serialize_field("name", name)?;
883                "CustomIpMap"
884            }
885            SiemDataset::CustomTextList((name, _)) => {
886                state.serialize_field("name", name)?;
887                "CustomTextList"
888            }
889            SiemDataset::CustomMapTextList((name, _)) => {
890                state.serialize_field("name", name)?;
891                "CustomMapTextList"
892            }
893            SiemDataset::Secrets((name, _)) => {
894                state.serialize_field("name", name)?;
895                "Secrets"
896            }
897        };
898        state.serialize_field("type", typ)?;
899        state.end()
900    }
901}
902
903#[derive(Serialize, Debug)]
904#[non_exhaustive]
905pub enum UpdateDataset {
906    GeoIp(UpdateGeoIp),
907    IpCloudService(UpdateNetIp),
908    IpCloudProvider(UpdateNetIp),
909    IpHeadquarters(UpdateNetIp),
910    CustomMapIpNet(UpdateNetIp),
911    IpMac(UpdateIpMap),
912    IpDNS(UpdateIpMapList),
913    MacHost(UpdateTextMap),
914    HostUser(UpdateTextMap),
915    UserTag(UpdateTextMap),
916    AssetTag(UpdateTextMap),
917    UserHeadquarters(UpdateTextMap),
918    CustomMapText(UpdateTextMap),
919    BlockIp(UpdateIpSet),
920    CustomIpList(UpdateIpSet),
921    BlockDomain(UpdateTextSet),
922    BlockEmailSender(UpdateTextSet),
923    BlockCountry(UpdateTextSet),
924    CustomTextList(UpdateTextSet),
925    CustomMapTextList(UpdateTextMapList),
926    MantainceCalendar(UpdateCalendar),
927    Configuration(UpdateTextMap),
928    Secrets(UpdateTextMap),
929    HostVulnerable(UpdateTextMapList),
930    CorrelationRules(UpdateGeoIp),
931    I18n(UpdateI18n),
932}