malwaredb/
types.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use pyo3::{pyclass, pymethods};
4
5/// Information about a label
6#[pyclass(frozen)]
7#[derive(Debug, Clone)]
8pub struct Label {
9    /// Label ID
10    #[pyo3(get)]
11    pub id: u64,
12
13    /// Label value
14    #[pyo3(get)]
15    pub name: String,
16
17    /// Label parent
18    #[pyo3(get)]
19    pub parent: Option<String>,
20}
21
22#[pymethods]
23impl Label {
24    /// Label printable representation
25    #[must_use]
26    pub fn __repr__(&self) -> String {
27        if let Some(parent) = &self.parent {
28            format!("Label {}: {parent}/{}", self.id, self.name)
29        } else {
30            format!("Label {}: {}", self.id, self.name)
31        }
32    }
33
34    /// Label information, just the name
35    #[must_use]
36    pub fn __str__(&self) -> String {
37        self.name.clone()
38    }
39}
40
41impl From<malwaredb_client::malwaredb_api::Label> for Label {
42    fn from(label: malwaredb_client::malwaredb_api::Label) -> Self {
43        Self {
44            id: label.id,
45            name: label.name,
46            parent: label.parent,
47        }
48    }
49}
50
51/// Information about the Malware DB server
52#[pyclass(frozen)]
53#[derive(Debug, Clone)]
54pub struct ServerInfo {
55    /// Operating System used
56    #[pyo3(get)]
57    pub os_name: String,
58
59    /// Memory footprint
60    #[pyo3(get)]
61    pub memory_used: String,
62
63    /// MDB version
64    #[pyo3(get)]
65    pub mdb_version: String,
66
67    /// Type and version of the database
68    #[pyo3(get)]
69    pub db_version: String,
70
71    /// Size of the database on disk
72    #[pyo3(get)]
73    pub db_size: String,
74
75    /// Total number of samples
76    #[pyo3(get)]
77    pub num_samples: u64,
78
79    /// Total number of users
80    #[pyo3(get)]
81    pub num_users: u32,
82
83    /// Uptime of Malware DB in a human-readable format
84    #[pyo3(get)]
85    pub uptime: String,
86
87    /// The name of the Malware DB instance
88    #[pyo3(get)]
89    pub instance_name: String,
90}
91
92#[pymethods]
93impl ServerInfo {
94    /// Server Info printable representation
95    #[must_use]
96    pub fn __repr__(&self) -> String {
97        format!(
98            "MalwareDB {} running on {} for {}",
99            self.mdb_version, self.os_name, self.uptime
100        )
101    }
102
103    /// Server info, just the version
104    #[must_use]
105    pub fn __str__(&self) -> String {
106        format!("MalwareDB {}", self.mdb_version)
107    }
108}
109
110impl From<malwaredb_client::malwaredb_api::ServerInfo> for ServerInfo {
111    fn from(value: malwaredb_client::malwaredb_api::ServerInfo) -> Self {
112        Self {
113            os_name: value.os_name,
114            memory_used: value.memory_used,
115            mdb_version: value.mdb_version.to_string(),
116            db_version: value.db_version,
117            db_size: value.db_size,
118            num_samples: value.num_samples,
119            num_users: value.num_users,
120            uptime: value.uptime,
121            instance_name: value.instance_name,
122        }
123    }
124}
125
126/// Information about a sample source
127#[pyclass(frozen)]
128#[derive(Debug, Clone)]
129pub struct Source {
130    /// Identifier of the source
131    #[pyo3(get)]
132    pub id: u32,
133
134    /// Name of the source
135    #[pyo3(get)]
136    pub name: String,
137
138    /// Description of the source
139    #[pyo3(get)]
140    pub description: Option<String>,
141
142    /// URL of the source, or where the files were found
143    #[pyo3(get)]
144    pub url: Option<String>,
145
146    /// Creation date or first acquisition date of or from the source
147    #[pyo3(get)]
148    pub first_acquisition: String,
149
150    /// Whether the source holds malware
151    #[pyo3(get)]
152    pub malicious: Option<bool>,
153}
154
155#[pymethods]
156impl Source {
157    /// Source printable representation
158    #[must_use]
159    pub fn __repr__(&self) -> String {
160        let url = if let Some(url) = &self.url {
161            format!(" from {url}")
162        } else {
163            String::new()
164        };
165
166        let desc = if let Some(desc) = &self.description {
167            format!(" -- {desc}")
168        } else {
169            String::new()
170        };
171
172        format!("{}({}){url}{desc}", self.name, self.id)
173    }
174
175    /// Simpler source printable representation
176    #[must_use]
177    pub fn __str__(&self) -> String {
178        self.name.clone()
179    }
180}
181
182impl From<malwaredb_client::malwaredb_api::SourceInfo> for Source {
183    fn from(value: malwaredb_client::malwaredb_api::SourceInfo) -> Self {
184        Self {
185            id: value.id,
186            name: value.name,
187            description: value.description,
188            url: value.url,
189            first_acquisition: value.first_acquisition.to_rfc3339(),
190            malicious: value.malicious,
191        }
192    }
193}
194
195/// Information about a file type supported by Malware DB
196#[pyclass(frozen)]
197#[derive(Debug, Clone)]
198pub struct SupportedFileType {
199    /// Common name of the file type
200    #[pyo3(get)]
201    pub name: String,
202
203    /// Magic number bytes in hex of the file type
204    #[pyo3(get)]
205    pub magic: Vec<String>,
206
207    /// Whether the file type is executable
208    #[pyo3(get)]
209    pub is_executable: bool,
210
211    /// Description of the file type
212    #[pyo3(get)]
213    pub description: Option<String>,
214}
215
216#[pymethods]
217impl SupportedFileType {
218    /// Supported file type as a printable representation
219    #[must_use]
220    pub fn __repr__(&self) -> String {
221        format!("{}, starting with {}", self.name, self.magic.join(" or "))
222    }
223
224    /// Supported file type as a printable simpler representation
225    #[must_use]
226    pub fn __str__(&self) -> String {
227        self.name.clone()
228    }
229}
230
231impl From<malwaredb_client::malwaredb_api::SupportedFileType> for SupportedFileType {
232    fn from(value: malwaredb_client::malwaredb_api::SupportedFileType) -> Self {
233        Self {
234            name: value.name,
235            magic: value.magic,
236            is_executable: value.is_executable,
237            description: value.description,
238        }
239    }
240}
241
242/// Information about the user's account
243#[pyclass(frozen)]
244#[derive(Debug, Clone)]
245pub struct UserInfo {
246    /// User's numeric ID
247    #[pyo3(get)]
248    pub id: u32,
249
250    /// User's name
251    #[pyo3(get)]
252    pub username: String,
253
254    /// User's group memberships, if any
255    #[pyo3(get)]
256    pub groups: Vec<String>,
257
258    /// User's available sample sources, if any
259    #[pyo3(get)]
260    pub sources: Vec<String>,
261
262    /// If the user is an admin
263    #[pyo3(get)]
264    pub is_admin: bool,
265
266    /// When the account was created
267    #[pyo3(get)]
268    pub created: String,
269
270    /// User has read-only access, perhaps a guest or demo account
271    #[pyo3(get)]
272    pub is_readonly: bool,
273}
274
275#[pymethods]
276impl UserInfo {
277    /// Simple user information
278    #[must_use]
279    pub fn __str__(&self) -> String {
280        self.username.clone()
281    }
282}
283
284impl From<malwaredb_client::malwaredb_api::GetUserInfoResponse> for UserInfo {
285    fn from(value: malwaredb_client::malwaredb_api::GetUserInfoResponse) -> Self {
286        Self {
287            id: value.id,
288            username: value.username,
289            groups: value.groups,
290            sources: value.sources,
291            is_admin: value.is_admin,
292            created: value.created.to_rfc3339(),
293            is_readonly: value.is_readonly,
294        }
295    }
296}