misp_client_rs/apis/
users_api.rs

1//!
2//! MISP Automation API
3//!
4//!  ### Getting Started  MISP API allows you to query, create, modify data models, such as [Events](https://www.circl.lu/doc/misp/GLOSSARY.html#misp-event), [Objects](https://www.circl.lu/doc/misp/misp-objects/), [Attributes](https://www.circl.lu/doc/misp/GLOSSARY.html#misp-attribute). This is extremly useful for interconnecting MISP with external tools and feeding other systems with threat intel data.  It also lets you perform administrative tasks such as creating users, organisations, altering MISP settings, and much more.  To get an API key there are several options: * **[UI]** Go to [My Profile -> Auth Keys](/auth_keys/index) section and click on `+ Add authentication key`  * **[UI]** As an admin go to the the [Administration -> List Users -> View](/admin/users/view/[id]) page of the user you want to create an auth key for and on the `Auth keys` section click on `+ Add authentication key`  * **[CLI]** Use the following command: `./app/Console/cake user change_authkey [e-mail/user_id]`  * **API** Provided you already have an admin level API key, you can create an API key for another user using the `[POST]/auth_keys/add/{{user_id}}` endpoint.  > **NOTE:** The authentication key will only be displayed once, so take note of it or store it properly in your application secrets.  #### Accept and Content-Type headers  When performing your request, depending on the type of request, you might need to explicitly specify in what content  type you want to get your results. This is done by setting one of the below `Accept` headers:      Accept: application/json     Accept: application/xml  When submitting data in a `POST`, `PUT` or `DELETE` operation you also need to specify in what content-type you encoded the payload.  This is done by setting one of the below `Content-Type` headers:      Content-Type: application/json     Content-Type: application/xml  Example: ``` curl  --header \"Authorization: YOUR_API_KEY\" \\       --header \"Accept: application/json\" \\       --header \"Content-Type: application/json\" https://<misp url>/  ```  > **NOTE**: By appending .json or .xml the content type can also be set without the need for a header.  #### Automation using PyMISP  [PyMISP](https://github.com/MISP/PyMISP) is a Python library to access MISP platforms via their REST [API](https://www.circl.lu/doc/misp/GLOSSARY.html#api). It allows you to fetch events, add or update events/attributes, add or update samples or search for attributes.  ### FAQ * [Dev FAQ](https://www.circl.lu/doc/misp/dev-faq/) * [GitHub project FAQ](https://github.com/MISP/MISP/wiki/Frequently-Asked-Questions) 
5//!
6//! The version of the OpenAPI document: 2.4
7//! 
8//! Generated by: https://openapi-generator.tech
9//! 
10
11
12use reqwest;
13use serde::{Deserialize, Serialize, de::Error as _};
14use crate::{apis::ResponseContent, models};
15use super::{Error, configuration, ContentType};
16
17
18/// struct for typed errors of method [`add_user`]
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(untagged)]
21pub enum AddUserError {
22    Status403(models::UnauthorizedApiError),
23    Status404(models::NotFoundApiError),
24    DefaultResponse(models::ApiError),
25    UnknownValue(serde_json::Value),
26}
27
28/// struct for typed errors of method [`delete_user`]
29#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(untagged)]
31pub enum DeleteUserError {
32    Status403(models::UnauthorizedApiError),
33    Status404(models::NotFoundApiError),
34    DefaultResponse(models::ApiError),
35    UnknownValue(serde_json::Value),
36}
37
38/// struct for typed errors of method [`delete_user_totp`]
39#[derive(Debug, Clone, Serialize, Deserialize)]
40#[serde(untagged)]
41pub enum DeleteUserTotpError {
42    Status403(models::UnauthorizedApiError),
43    Status404(models::NotFoundUserTotpDeleteError),
44    DefaultResponse(models::ApiError),
45    UnknownValue(serde_json::Value),
46}
47
48/// struct for typed errors of method [`edit_user`]
49#[derive(Debug, Clone, Serialize, Deserialize)]
50#[serde(untagged)]
51pub enum EditUserError {
52    Status403(models::UnauthorizedApiError),
53    Status404(models::NotFoundApiError),
54    DefaultResponse(models::ApiError),
55    UnknownValue(serde_json::Value),
56}
57
58/// struct for typed errors of method [`get_user_by_id`]
59#[derive(Debug, Clone, Serialize, Deserialize)]
60#[serde(untagged)]
61pub enum GetUserByIdError {
62    Status403(models::UnauthorizedApiError),
63    Status404(models::NotFoundApiError),
64    DefaultResponse(models::ApiError),
65    UnknownValue(serde_json::Value),
66}
67
68/// struct for typed errors of method [`get_users`]
69#[derive(Debug, Clone, Serialize, Deserialize)]
70#[serde(untagged)]
71pub enum GetUsersError {
72    Status403(models::UnauthorizedApiError),
73    Status404(models::NotFoundApiError),
74    DefaultResponse(models::ApiError),
75    UnknownValue(serde_json::Value),
76}
77
78/// struct for typed errors of method [`reset_user_password`]
79#[derive(Debug, Clone, Serialize, Deserialize)]
80#[serde(untagged)]
81pub enum ResetUserPasswordError {
82    Status403(models::UnauthorizedApiError),
83    Status404(models::NotFoundApiError),
84    DefaultResponse(models::ApiError),
85    UnknownValue(serde_json::Value),
86}
87
88
89pub async fn add_user(configuration: &configuration::Configuration, user_no_id: Option<models::UserNoId>) -> Result<models::User, Error<AddUserError>> {
90    // add a prefix to parameters to efficiently prevent name collisions
91    let p_user_no_id = user_no_id;
92
93    let uri_str = format!("{}/admin/users/add", configuration.base_path);
94    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
95
96    if let Some(ref user_agent) = configuration.user_agent {
97        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
98    }
99    if let Some(ref apikey) = configuration.api_key {
100        let key = apikey.key.clone();
101        let value = match apikey.prefix {
102            Some(ref prefix) => format!("{} {}", prefix, key),
103            None => key,
104        };
105        req_builder = req_builder.header("Authorization", value);
106    };
107    req_builder = req_builder.json(&p_user_no_id);
108
109    let req = req_builder.build()?;
110    let resp = configuration.client.execute(req).await?;
111
112    let status = resp.status();
113    let content_type = resp
114        .headers()
115        .get("content-type")
116        .and_then(|v| v.to_str().ok())
117        .unwrap_or("application/octet-stream");
118    let content_type = super::ContentType::from(content_type);
119
120    if !status.is_client_error() && !status.is_server_error() {
121        let content = resp.text().await?;
122        match content_type {
123            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
124            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::User`"))),
125            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::User`")))),
126        }
127    } else {
128        let content = resp.text().await?;
129        let entity: Option<AddUserError> = serde_json::from_str(&content).ok();
130        Err(Error::ResponseError(ResponseContent { status, content, entity }))
131    }
132}
133
134pub async fn delete_user(configuration: &configuration::Configuration, user_id: &str) -> Result<models::DeleteUser200Response, Error<DeleteUserError>> {
135    // add a prefix to parameters to efficiently prevent name collisions
136    let p_user_id = user_id;
137
138    let uri_str = format!("{}/admin/users/delete/{userId}", configuration.base_path, userId=crate::apis::urlencode(p_user_id));
139    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
140
141    if let Some(ref user_agent) = configuration.user_agent {
142        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
143    }
144    if let Some(ref apikey) = configuration.api_key {
145        let key = apikey.key.clone();
146        let value = match apikey.prefix {
147            Some(ref prefix) => format!("{} {}", prefix, key),
148            None => key,
149        };
150        req_builder = req_builder.header("Authorization", value);
151    };
152
153    let req = req_builder.build()?;
154    let resp = configuration.client.execute(req).await?;
155
156    let status = resp.status();
157    let content_type = resp
158        .headers()
159        .get("content-type")
160        .and_then(|v| v.to_str().ok())
161        .unwrap_or("application/octet-stream");
162    let content_type = super::ContentType::from(content_type);
163
164    if !status.is_client_error() && !status.is_server_error() {
165        let content = resp.text().await?;
166        match content_type {
167            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
168            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DeleteUser200Response`"))),
169            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::DeleteUser200Response`")))),
170        }
171    } else {
172        let content = resp.text().await?;
173        let entity: Option<DeleteUserError> = serde_json::from_str(&content).ok();
174        Err(Error::ResponseError(ResponseContent { status, content, entity }))
175    }
176}
177
178pub async fn delete_user_totp(configuration: &configuration::Configuration, user_id: &str) -> Result<models::DeleteUserTotp200Response, Error<DeleteUserTotpError>> {
179    // add a prefix to parameters to efficiently prevent name collisions
180    let p_user_id = user_id;
181
182    let uri_str = format!("{}/users/totp_delete/{userId}", configuration.base_path, userId=crate::apis::urlencode(p_user_id));
183    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
184
185    if let Some(ref user_agent) = configuration.user_agent {
186        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
187    }
188    if let Some(ref apikey) = configuration.api_key {
189        let key = apikey.key.clone();
190        let value = match apikey.prefix {
191            Some(ref prefix) => format!("{} {}", prefix, key),
192            None => key,
193        };
194        req_builder = req_builder.header("Authorization", value);
195    };
196
197    let req = req_builder.build()?;
198    let resp = configuration.client.execute(req).await?;
199
200    let status = resp.status();
201    let content_type = resp
202        .headers()
203        .get("content-type")
204        .and_then(|v| v.to_str().ok())
205        .unwrap_or("application/octet-stream");
206    let content_type = super::ContentType::from(content_type);
207
208    if !status.is_client_error() && !status.is_server_error() {
209        let content = resp.text().await?;
210        match content_type {
211            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
212            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DeleteUserTotp200Response`"))),
213            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::DeleteUserTotp200Response`")))),
214        }
215    } else {
216        let content = resp.text().await?;
217        let entity: Option<DeleteUserTotpError> = serde_json::from_str(&content).ok();
218        Err(Error::ResponseError(ResponseContent { status, content, entity }))
219    }
220}
221
222pub async fn edit_user(configuration: &configuration::Configuration, user_id: &str, user: Option<models::User>) -> Result<models::User, Error<EditUserError>> {
223    // add a prefix to parameters to efficiently prevent name collisions
224    let p_user_id = user_id;
225    let p_user = user;
226
227    let uri_str = format!("{}/admin/users/edit/{userId}", configuration.base_path, userId=crate::apis::urlencode(p_user_id));
228    let mut req_builder = configuration.client.request(reqwest::Method::PUT, &uri_str);
229
230    if let Some(ref user_agent) = configuration.user_agent {
231        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
232    }
233    if let Some(ref apikey) = configuration.api_key {
234        let key = apikey.key.clone();
235        let value = match apikey.prefix {
236            Some(ref prefix) => format!("{} {}", prefix, key),
237            None => key,
238        };
239        req_builder = req_builder.header("Authorization", value);
240    };
241    req_builder = req_builder.json(&p_user);
242
243    let req = req_builder.build()?;
244    let resp = configuration.client.execute(req).await?;
245
246    let status = resp.status();
247    let content_type = resp
248        .headers()
249        .get("content-type")
250        .and_then(|v| v.to_str().ok())
251        .unwrap_or("application/octet-stream");
252    let content_type = super::ContentType::from(content_type);
253
254    if !status.is_client_error() && !status.is_server_error() {
255        let content = resp.text().await?;
256        match content_type {
257            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
258            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::User`"))),
259            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::User`")))),
260        }
261    } else {
262        let content = resp.text().await?;
263        let entity: Option<EditUserError> = serde_json::from_str(&content).ok();
264        Err(Error::ResponseError(ResponseContent { status, content, entity }))
265    }
266}
267
268pub async fn get_user_by_id(configuration: &configuration::Configuration, user_id: &str) -> Result<models::ExtendedUser, Error<GetUserByIdError>> {
269    // add a prefix to parameters to efficiently prevent name collisions
270    let p_user_id = user_id;
271
272    let uri_str = format!("{}/admin/users/view/{userId}", configuration.base_path, userId=crate::apis::urlencode(p_user_id));
273    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
274
275    if let Some(ref user_agent) = configuration.user_agent {
276        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
277    }
278    if let Some(ref apikey) = configuration.api_key {
279        let key = apikey.key.clone();
280        let value = match apikey.prefix {
281            Some(ref prefix) => format!("{} {}", prefix, key),
282            None => key,
283        };
284        req_builder = req_builder.header("Authorization", value);
285    };
286
287    let req = req_builder.build()?;
288    let resp = configuration.client.execute(req).await?;
289
290    let status = resp.status();
291    let content_type = resp
292        .headers()
293        .get("content-type")
294        .and_then(|v| v.to_str().ok())
295        .unwrap_or("application/octet-stream");
296    let content_type = super::ContentType::from(content_type);
297
298    if !status.is_client_error() && !status.is_server_error() {
299        let content = resp.text().await?;
300        match content_type {
301            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
302            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ExtendedUser`"))),
303            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ExtendedUser`")))),
304        }
305    } else {
306        let content = resp.text().await?;
307        let entity: Option<GetUserByIdError> = serde_json::from_str(&content).ok();
308        Err(Error::ResponseError(ResponseContent { status, content, entity }))
309    }
310}
311
312pub async fn get_users(configuration: &configuration::Configuration, ) -> Result<Vec<models::UserListItem>, Error<GetUsersError>> {
313
314    let uri_str = format!("{}/admin/users", configuration.base_path);
315    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
316
317    if let Some(ref user_agent) = configuration.user_agent {
318        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
319    }
320    if let Some(ref apikey) = configuration.api_key {
321        let key = apikey.key.clone();
322        let value = match apikey.prefix {
323            Some(ref prefix) => format!("{} {}", prefix, key),
324            None => key,
325        };
326        req_builder = req_builder.header("Authorization", value);
327    };
328
329    let req = req_builder.build()?;
330    let resp = configuration.client.execute(req).await?;
331
332    let status = resp.status();
333    let content_type = resp
334        .headers()
335        .get("content-type")
336        .and_then(|v| v.to_str().ok())
337        .unwrap_or("application/octet-stream");
338    let content_type = super::ContentType::from(content_type);
339
340    if !status.is_client_error() && !status.is_server_error() {
341        let content = resp.text().await?;
342        match content_type {
343            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
344            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::UserListItem&gt;`"))),
345            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::UserListItem&gt;`")))),
346        }
347    } else {
348        let content = resp.text().await?;
349        let entity: Option<GetUsersError> = serde_json::from_str(&content).ok();
350        Err(Error::ResponseError(ResponseContent { status, content, entity }))
351    }
352}
353
354pub async fn reset_user_password(configuration: &configuration::Configuration, user_id: &str, first_time_reset: &str) -> Result<models::ResetUserPassword200Response, Error<ResetUserPasswordError>> {
355    // add a prefix to parameters to efficiently prevent name collisions
356    let p_user_id = user_id;
357    let p_first_time_reset = first_time_reset;
358
359    let uri_str = format!("{}/users/initiatePasswordReset/{userId}/{firstTimeReset}", configuration.base_path, userId=crate::apis::urlencode(p_user_id), firstTimeReset=crate::apis::urlencode(p_first_time_reset));
360    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
361
362    if let Some(ref user_agent) = configuration.user_agent {
363        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
364    }
365    if let Some(ref apikey) = configuration.api_key {
366        let key = apikey.key.clone();
367        let value = match apikey.prefix {
368            Some(ref prefix) => format!("{} {}", prefix, key),
369            None => key,
370        };
371        req_builder = req_builder.header("Authorization", value);
372    };
373
374    let req = req_builder.build()?;
375    let resp = configuration.client.execute(req).await?;
376
377    let status = resp.status();
378    let content_type = resp
379        .headers()
380        .get("content-type")
381        .and_then(|v| v.to_str().ok())
382        .unwrap_or("application/octet-stream");
383    let content_type = super::ContentType::from(content_type);
384
385    if !status.is_client_error() && !status.is_server_error() {
386        let content = resp.text().await?;
387        match content_type {
388            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
389            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ResetUserPassword200Response`"))),
390            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ResetUserPassword200Response`")))),
391        }
392    } else {
393        let content = resp.text().await?;
394        let entity: Option<ResetUserPasswordError> = serde_json::from_str(&content).ok();
395        Err(Error::ResponseError(ResponseContent { status, content, entity }))
396    }
397}
398