csaf_walker/model/
metadata.rs

1use chrono::{DateTime, Utc};
2use url::Url;
3
4#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
5pub struct Distribution {
6    #[serde(default, skip_serializing_if = "Option::is_none")]
7    pub directory_url: Option<Url>,
8    #[serde(default, skip_serializing_if = "Option::is_none")]
9    pub rolie: Option<Rolie>,
10}
11
12#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
13pub struct Rolie {
14    #[serde(default)]
15    pub categories: Vec<Url>,
16    #[serde(default, skip_serializing_if = "Vec::is_empty")]
17    pub feeds: Vec<Feed>,
18    #[serde(default)]
19    pub services: Vec<Url>,
20}
21
22#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
23pub struct Feed {
24    #[serde(default, skip_serializing_if = "Option::is_none")]
25    pub summary: Option<String>,
26    pub tlp_label: TlpLabel,
27    pub url: Url,
28}
29
30#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
31#[serde(rename_all = "UPPERCASE")]
32pub enum TlpLabel {
33    Unlabeled,
34    White,
35    Green,
36    Amber,
37    Red,
38}
39
40#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
41pub struct Key {
42    #[serde(default, skip_serializing_if = "Option::is_none")]
43    pub fingerprint: Option<String>,
44    pub url: Url,
45}
46
47impl<'a> From<&'a Key> for walker_common::validate::source::Key<'a> {
48    fn from(value: &'a Key) -> Self {
49        walker_common::validate::source::Key {
50            fingerprint: value.fingerprint.as_deref(),
51            url: &value.url,
52        }
53    }
54}
55
56#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
57pub struct Publisher {
58    pub category: String,
59    pub contact_details: String,
60    #[serde(default, skip_serializing_if = "Option::is_none")]
61    pub issuing_authority: Option<String>,
62    pub name: String,
63    pub namespace: String,
64}
65
66#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
67pub struct ProviderMetadata {
68    pub canonical_url: Url,
69
70    #[serde(default)]
71    pub distributions: Vec<Distribution>,
72
73    pub last_updated: DateTime<Utc>,
74
75    #[serde(rename = "list_on_CSAF_aggregators")]
76    #[serde(default)]
77    pub list_on_csaf_aggregators: bool,
78
79    pub metadata_version: String,
80
81    #[serde(rename = "mirror_on_CSAF_aggregators")]
82    #[serde(default)]
83    pub mirror_on_csaf_aggregators: bool,
84
85    #[serde(default)]
86    pub public_openpgp_keys: Vec<Key>,
87
88    pub publisher: Publisher,
89
90    /// Contains the role of the issuing party according to section 7 in the CSAF standard.
91    #[serde(default = "default_role")]
92    pub role: Role,
93}
94
95const fn default_role() -> Role {
96    Role::Provider
97}
98
99#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Deserialize, serde::Serialize)]
100pub enum Role {
101    #[serde(rename = "csaf_publisher")]
102    Publisher,
103    #[serde(rename = "csaf_provider")]
104    Provider,
105    #[serde(rename = "csaf_trusted_provider")]
106    TrustedProvider,
107}