misp_client_rs/apis/
attributes_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_attribute`]
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(untagged)]
21pub enum AddAttributeError {
22    Status403(models::UnauthorizedApiError),
23    DefaultResponse(models::ApiError),
24    UnknownValue(serde_json::Value),
25}
26
27/// struct for typed errors of method [`delete_attribute`]
28#[derive(Debug, Clone, Serialize, Deserialize)]
29#[serde(untagged)]
30pub enum DeleteAttributeError {
31    Status403(models::UnauthorizedApiError),
32    Status404(models::NotFoundApiError),
33    DefaultResponse(models::ApiError),
34    UnknownValue(serde_json::Value),
35}
36
37/// struct for typed errors of method [`describe_attribute_types`]
38#[derive(Debug, Clone, Serialize, Deserialize)]
39#[serde(untagged)]
40pub enum DescribeAttributeTypesError {
41    Status403(models::UnauthorizedApiError),
42    DefaultResponse(models::ApiError),
43    UnknownValue(serde_json::Value),
44}
45
46/// struct for typed errors of method [`edit_attribute`]
47#[derive(Debug, Clone, Serialize, Deserialize)]
48#[serde(untagged)]
49pub enum EditAttributeError {
50    Status403(models::UnauthorizedApiError),
51    Status404(models::NotFoundApiError),
52    DefaultResponse(models::ApiError),
53    UnknownValue(serde_json::Value),
54}
55
56/// struct for typed errors of method [`enrich_attribute`]
57#[derive(Debug, Clone, Serialize, Deserialize)]
58#[serde(untagged)]
59pub enum EnrichAttributeError {
60    Status403(models::UnauthorizedApiError),
61    DefaultResponse(models::ApiError),
62    UnknownValue(serde_json::Value),
63}
64
65/// struct for typed errors of method [`get_attribute_by_id`]
66#[derive(Debug, Clone, Serialize, Deserialize)]
67#[serde(untagged)]
68pub enum GetAttributeByIdError {
69    Status403(models::UnauthorizedApiError),
70    DefaultResponse(models::ApiError),
71    UnknownValue(serde_json::Value),
72}
73
74/// struct for typed errors of method [`get_attribute_statistics`]
75#[derive(Debug, Clone, Serialize, Deserialize)]
76#[serde(untagged)]
77pub enum GetAttributeStatisticsError {
78    Status403(models::UnauthorizedApiError),
79    DefaultResponse(models::ApiError),
80    UnknownValue(serde_json::Value),
81}
82
83/// struct for typed errors of method [`get_attributes`]
84#[derive(Debug, Clone, Serialize, Deserialize)]
85#[serde(untagged)]
86pub enum GetAttributesError {
87    Status403(models::UnauthorizedApiError),
88    DefaultResponse(models::ApiError),
89    UnknownValue(serde_json::Value),
90}
91
92/// struct for typed errors of method [`rest_search_attributes`]
93#[derive(Debug, Clone, Serialize, Deserialize)]
94#[serde(untagged)]
95pub enum RestSearchAttributesError {
96    Status403(models::UnauthorizedApiError),
97    DefaultResponse(models::ApiError),
98    UnknownValue(serde_json::Value),
99}
100
101/// struct for typed errors of method [`restore_attribute`]
102#[derive(Debug, Clone, Serialize, Deserialize)]
103#[serde(untagged)]
104pub enum RestoreAttributeError {
105    Status403(models::UnauthorizedApiError),
106    Status404(models::NotFoundApiError),
107    DefaultResponse(models::ApiError),
108    UnknownValue(serde_json::Value),
109}
110
111/// struct for typed errors of method [`tag_attribute`]
112#[derive(Debug, Clone, Serialize, Deserialize)]
113#[serde(untagged)]
114pub enum TagAttributeError {
115    Status403(models::UnauthorizedApiError),
116    Status404(models::NotFoundApiError),
117    DefaultResponse(models::ApiError),
118    UnknownValue(serde_json::Value),
119}
120
121/// struct for typed errors of method [`untag_attribute`]
122#[derive(Debug, Clone, Serialize, Deserialize)]
123#[serde(untagged)]
124pub enum UntagAttributeError {
125    Status403(models::UnauthorizedApiError),
126    Status404(models::NotFoundApiError),
127    DefaultResponse(models::ApiError),
128    UnknownValue(serde_json::Value),
129}
130
131
132pub async fn add_attribute(configuration: &configuration::Configuration, event_id: &str, attribute_no_id: models::AttributeNoId) -> Result<models::AddAttribute200Response, Error<AddAttributeError>> {
133    // add a prefix to parameters to efficiently prevent name collisions
134    let p_event_id = event_id;
135    let p_attribute_no_id = attribute_no_id;
136
137    let uri_str = format!("{}/attributes/add/{eventId}", configuration.base_path, eventId=p_event_id.to_string());
138    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
139
140    if let Some(ref user_agent) = configuration.user_agent {
141        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
142    }
143    if let Some(ref apikey) = configuration.api_key {
144        let key = apikey.key.clone();
145        let value = match apikey.prefix {
146            Some(ref prefix) => format!("{} {}", prefix, key),
147            None => key,
148        };
149        req_builder = req_builder.header("Authorization", value);
150    };
151    req_builder = req_builder.json(&p_attribute_no_id);
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::AddAttribute200Response`"))),
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::AddAttribute200Response`")))),
170        }
171    } else {
172        let content = resp.text().await?;
173        let entity: Option<AddAttributeError> = serde_json::from_str(&content).ok();
174        Err(Error::ResponseError(ResponseContent { status, content, entity }))
175    }
176}
177
178pub async fn delete_attribute(configuration: &configuration::Configuration, attribute_id: &str) -> Result<models::DeleteAttribute200Response, Error<DeleteAttributeError>> {
179    // add a prefix to parameters to efficiently prevent name collisions
180    let p_attribute_id = attribute_id;
181
182    let uri_str = format!("{}/attributes/delete/{attributeId}", configuration.base_path, attributeId=p_attribute_id.to_string());
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::DeleteAttribute200Response`"))),
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::DeleteAttribute200Response`")))),
214        }
215    } else {
216        let content = resp.text().await?;
217        let entity: Option<DeleteAttributeError> = serde_json::from_str(&content).ok();
218        Err(Error::ResponseError(ResponseContent { status, content, entity }))
219    }
220}
221
222pub async fn describe_attribute_types(configuration: &configuration::Configuration, ) -> Result<models::DescribeAttributeTypesResponse, Error<DescribeAttributeTypesError>> {
223
224    let uri_str = format!("{}/attributes/describeTypes", configuration.base_path);
225    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
226
227    if let Some(ref user_agent) = configuration.user_agent {
228        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
229    }
230    if let Some(ref apikey) = configuration.api_key {
231        let key = apikey.key.clone();
232        let value = match apikey.prefix {
233            Some(ref prefix) => format!("{} {}", prefix, key),
234            None => key,
235        };
236        req_builder = req_builder.header("Authorization", value);
237    };
238
239    let req = req_builder.build()?;
240    let resp = configuration.client.execute(req).await?;
241
242    let status = resp.status();
243    let content_type = resp
244        .headers()
245        .get("content-type")
246        .and_then(|v| v.to_str().ok())
247        .unwrap_or("application/octet-stream");
248    let content_type = super::ContentType::from(content_type);
249
250    if !status.is_client_error() && !status.is_server_error() {
251        let content = resp.text().await?;
252        match content_type {
253            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
254            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::DescribeAttributeTypesResponse`"))),
255            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::DescribeAttributeTypesResponse`")))),
256        }
257    } else {
258        let content = resp.text().await?;
259        let entity: Option<DescribeAttributeTypesError> = serde_json::from_str(&content).ok();
260        Err(Error::ResponseError(ResponseContent { status, content, entity }))
261    }
262}
263
264pub async fn edit_attribute(configuration: &configuration::Configuration, attribute_id: &str, attribute: models::Attribute) -> Result<models::AddAttribute200Response, Error<EditAttributeError>> {
265    // add a prefix to parameters to efficiently prevent name collisions
266    let p_attribute_id = attribute_id;
267    let p_attribute = attribute;
268
269    let uri_str = format!("{}/attributes/edit/{attributeId}", configuration.base_path, attributeId=p_attribute_id.to_string());
270    let mut req_builder = configuration.client.request(reqwest::Method::PUT, &uri_str);
271
272    if let Some(ref user_agent) = configuration.user_agent {
273        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
274    }
275    if let Some(ref apikey) = configuration.api_key {
276        let key = apikey.key.clone();
277        let value = match apikey.prefix {
278            Some(ref prefix) => format!("{} {}", prefix, key),
279            None => key,
280        };
281        req_builder = req_builder.header("Authorization", value);
282    };
283    req_builder = req_builder.json(&p_attribute);
284
285    let req = req_builder.build()?;
286    let resp = configuration.client.execute(req).await?;
287
288    let status = resp.status();
289    let content_type = resp
290        .headers()
291        .get("content-type")
292        .and_then(|v| v.to_str().ok())
293        .unwrap_or("application/octet-stream");
294    let content_type = super::ContentType::from(content_type);
295
296    if !status.is_client_error() && !status.is_server_error() {
297        let content = resp.text().await?;
298        match content_type {
299            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
300            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::AddAttribute200Response`"))),
301            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::AddAttribute200Response`")))),
302        }
303    } else {
304        let content = resp.text().await?;
305        let entity: Option<EditAttributeError> = serde_json::from_str(&content).ok();
306        Err(Error::ResponseError(ResponseContent { status, content, entity }))
307    }
308}
309
310pub async fn enrich_attribute(configuration: &configuration::Configuration, attribute_id: &str, enrich_modules_list: models::EnrichModulesList) -> Result<models::EnrichAttribute200Response, Error<EnrichAttributeError>> {
311    // add a prefix to parameters to efficiently prevent name collisions
312    let p_attribute_id = attribute_id;
313    let p_enrich_modules_list = enrich_modules_list;
314
315    let uri_str = format!("{}/attributes/enrich/{attributeId}", configuration.base_path, attributeId=p_attribute_id.to_string());
316    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
317
318    if let Some(ref user_agent) = configuration.user_agent {
319        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
320    }
321    if let Some(ref apikey) = configuration.api_key {
322        let key = apikey.key.clone();
323        let value = match apikey.prefix {
324            Some(ref prefix) => format!("{} {}", prefix, key),
325            None => key,
326        };
327        req_builder = req_builder.header("Authorization", value);
328    };
329    req_builder = req_builder.json(&p_enrich_modules_list);
330
331    let req = req_builder.build()?;
332    let resp = configuration.client.execute(req).await?;
333
334    let status = resp.status();
335    let content_type = resp
336        .headers()
337        .get("content-type")
338        .and_then(|v| v.to_str().ok())
339        .unwrap_or("application/octet-stream");
340    let content_type = super::ContentType::from(content_type);
341
342    if !status.is_client_error() && !status.is_server_error() {
343        let content = resp.text().await?;
344        match content_type {
345            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
346            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::EnrichAttribute200Response`"))),
347            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::EnrichAttribute200Response`")))),
348        }
349    } else {
350        let content = resp.text().await?;
351        let entity: Option<EnrichAttributeError> = serde_json::from_str(&content).ok();
352        Err(Error::ResponseError(ResponseContent { status, content, entity }))
353    }
354}
355
356pub async fn get_attribute_by_id(configuration: &configuration::Configuration, attribute_id: &str) -> Result<models::AddAttribute200Response, Error<GetAttributeByIdError>> {
357    // add a prefix to parameters to efficiently prevent name collisions
358    let p_attribute_id = attribute_id;
359
360    let uri_str = format!("{}/attributes/view/{attributeId}", configuration.base_path, attributeId=p_attribute_id.to_string());
361    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
362
363    if let Some(ref user_agent) = configuration.user_agent {
364        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
365    }
366    if let Some(ref apikey) = configuration.api_key {
367        let key = apikey.key.clone();
368        let value = match apikey.prefix {
369            Some(ref prefix) => format!("{} {}", prefix, key),
370            None => key,
371        };
372        req_builder = req_builder.header("Authorization", value);
373    };
374
375    let req = req_builder.build()?;
376    let resp = configuration.client.execute(req).await?;
377
378    let status = resp.status();
379    let content_type = resp
380        .headers()
381        .get("content-type")
382        .and_then(|v| v.to_str().ok())
383        .unwrap_or("application/octet-stream");
384    let content_type = super::ContentType::from(content_type);
385
386    if !status.is_client_error() && !status.is_server_error() {
387        let content = resp.text().await?;
388        match content_type {
389            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
390            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::AddAttribute200Response`"))),
391            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::AddAttribute200Response`")))),
392        }
393    } else {
394        let content = resp.text().await?;
395        let entity: Option<GetAttributeByIdError> = serde_json::from_str(&content).ok();
396        Err(Error::ResponseError(ResponseContent { status, content, entity }))
397    }
398}
399
400pub async fn get_attribute_statistics(configuration: &configuration::Configuration, context: &str, percentage: i32) -> Result<serde_json::Value, Error<GetAttributeStatisticsError>> {
401    // add a prefix to parameters to efficiently prevent name collisions
402    let p_context = context;
403    let p_percentage = percentage;
404
405    let uri_str = format!("{}/attributes/attributeStatistics/{context}/{percentage}", configuration.base_path, context=crate::apis::urlencode(p_context), percentage=p_percentage);
406    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
407
408    if let Some(ref user_agent) = configuration.user_agent {
409        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
410    }
411    if let Some(ref apikey) = configuration.api_key {
412        let key = apikey.key.clone();
413        let value = match apikey.prefix {
414            Some(ref prefix) => format!("{} {}", prefix, key),
415            None => key,
416        };
417        req_builder = req_builder.header("Authorization", value);
418    };
419
420    let req = req_builder.build()?;
421    let resp = configuration.client.execute(req).await?;
422
423    let status = resp.status();
424    let content_type = resp
425        .headers()
426        .get("content-type")
427        .and_then(|v| v.to_str().ok())
428        .unwrap_or("application/octet-stream");
429    let content_type = super::ContentType::from(content_type);
430
431    if !status.is_client_error() && !status.is_server_error() {
432        let content = resp.text().await?;
433        match content_type {
434            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
435            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `serde_json::Value`"))),
436            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `serde_json::Value`")))),
437        }
438    } else {
439        let content = resp.text().await?;
440        let entity: Option<GetAttributeStatisticsError> = serde_json::from_str(&content).ok();
441        Err(Error::ResponseError(ResponseContent { status, content, entity }))
442    }
443}
444
445pub async fn get_attributes(configuration: &configuration::Configuration, ) -> Result<Vec<models::Attribute>, Error<GetAttributesError>> {
446
447    let uri_str = format!("{}/attributes", configuration.base_path);
448    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
449
450    if let Some(ref user_agent) = configuration.user_agent {
451        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
452    }
453    if let Some(ref apikey) = configuration.api_key {
454        let key = apikey.key.clone();
455        let value = match apikey.prefix {
456            Some(ref prefix) => format!("{} {}", prefix, key),
457            None => key,
458        };
459        req_builder = req_builder.header("Authorization", value);
460    };
461
462    let req = req_builder.build()?;
463    let resp = configuration.client.execute(req).await?;
464
465    let status = resp.status();
466    let content_type = resp
467        .headers()
468        .get("content-type")
469        .and_then(|v| v.to_str().ok())
470        .unwrap_or("application/octet-stream");
471    let content_type = super::ContentType::from(content_type);
472
473    if !status.is_client_error() && !status.is_server_error() {
474        let content = resp.text().await?;
475        match content_type {
476            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
477            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::Attribute&gt;`"))),
478            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::Attribute&gt;`")))),
479        }
480    } else {
481        let content = resp.text().await?;
482        let entity: Option<GetAttributesError> = serde_json::from_str(&content).ok();
483        Err(Error::ResponseError(ResponseContent { status, content, entity }))
484    }
485}
486
487/// **This is the recommended endpoint for searching attributes.** 
488pub async fn rest_search_attributes(configuration: &configuration::Configuration, attribute_rest_search_filter: models::AttributeRestSearchFilter) -> Result<models::RestSearchAttributes200Response, Error<RestSearchAttributesError>> {
489    // add a prefix to parameters to efficiently prevent name collisions
490    let p_attribute_rest_search_filter = attribute_rest_search_filter;
491
492    let uri_str = format!("{}/attributes/restSearch", configuration.base_path);
493    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
494
495    if let Some(ref user_agent) = configuration.user_agent {
496        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
497    }
498    if let Some(ref apikey) = configuration.api_key {
499        let key = apikey.key.clone();
500        let value = match apikey.prefix {
501            Some(ref prefix) => format!("{} {}", prefix, key),
502            None => key,
503        };
504        req_builder = req_builder.header("Authorization", value);
505    };
506    req_builder = req_builder.json(&p_attribute_rest_search_filter);
507
508    let req = req_builder.build()?;
509    let resp = configuration.client.execute(req).await?;
510
511    let status = resp.status();
512    let content_type = resp
513        .headers()
514        .get("content-type")
515        .and_then(|v| v.to_str().ok())
516        .unwrap_or("application/octet-stream");
517    let content_type = super::ContentType::from(content_type);
518
519    if !status.is_client_error() && !status.is_server_error() {
520        let content = resp.text().await?;
521        match content_type {
522            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
523            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::RestSearchAttributes200Response`"))),
524            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::RestSearchAttributes200Response`")))),
525        }
526    } else {
527        let content = resp.text().await?;
528        let entity: Option<RestSearchAttributesError> = serde_json::from_str(&content).ok();
529        Err(Error::ResponseError(ResponseContent { status, content, entity }))
530    }
531}
532
533pub async fn restore_attribute(configuration: &configuration::Configuration, attribute_id: &str) -> Result<models::AddAttribute200Response, Error<RestoreAttributeError>> {
534    // add a prefix to parameters to efficiently prevent name collisions
535    let p_attribute_id = attribute_id;
536
537    let uri_str = format!("{}/attributes/restore/{attributeId}", configuration.base_path, attributeId=p_attribute_id.to_string());
538    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
539
540    if let Some(ref user_agent) = configuration.user_agent {
541        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
542    }
543    if let Some(ref apikey) = configuration.api_key {
544        let key = apikey.key.clone();
545        let value = match apikey.prefix {
546            Some(ref prefix) => format!("{} {}", prefix, key),
547            None => key,
548        };
549        req_builder = req_builder.header("Authorization", value);
550    };
551
552    let req = req_builder.build()?;
553    let resp = configuration.client.execute(req).await?;
554
555    let status = resp.status();
556    let content_type = resp
557        .headers()
558        .get("content-type")
559        .and_then(|v| v.to_str().ok())
560        .unwrap_or("application/octet-stream");
561    let content_type = super::ContentType::from(content_type);
562
563    if !status.is_client_error() && !status.is_server_error() {
564        let content = resp.text().await?;
565        match content_type {
566            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
567            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::AddAttribute200Response`"))),
568            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::AddAttribute200Response`")))),
569        }
570    } else {
571        let content = resp.text().await?;
572        let entity: Option<RestoreAttributeError> = serde_json::from_str(&content).ok();
573        Err(Error::ResponseError(ResponseContent { status, content, entity }))
574    }
575}
576
577/// Add one or multiple tags to one or multiple attributes
578pub async fn tag_attribute(configuration: &configuration::Configuration, attribute_id: &str, tag_id: &str, local: i32, tag_attribute_request: Option<models::TagAttributeRequest>) -> Result<models::TagAttribute200Response, Error<TagAttributeError>> {
579    // add a prefix to parameters to efficiently prevent name collisions
580    let p_attribute_id = attribute_id;
581    let p_tag_id = tag_id;
582    let p_local = local;
583    let p_tag_attribute_request = tag_attribute_request;
584
585    let uri_str = format!("{}/attributes/addTag/{attributeId}/{tagId}/local:{local}", configuration.base_path, attributeId=crate::apis::urlencode(p_attribute_id), tagId=crate::apis::urlencode(p_tag_id), local=p_local);
586    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
587
588    if let Some(ref user_agent) = configuration.user_agent {
589        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
590    }
591    if let Some(ref apikey) = configuration.api_key {
592        let key = apikey.key.clone();
593        let value = match apikey.prefix {
594            Some(ref prefix) => format!("{} {}", prefix, key),
595            None => key,
596        };
597        req_builder = req_builder.header("Authorization", value);
598    };
599    req_builder = req_builder.json(&p_tag_attribute_request);
600
601    let req = req_builder.build()?;
602    let resp = configuration.client.execute(req).await?;
603
604    let status = resp.status();
605    let content_type = resp
606        .headers()
607        .get("content-type")
608        .and_then(|v| v.to_str().ok())
609        .unwrap_or("application/octet-stream");
610    let content_type = super::ContentType::from(content_type);
611
612    if !status.is_client_error() && !status.is_server_error() {
613        let content = resp.text().await?;
614        match content_type {
615            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
616            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::TagAttribute200Response`"))),
617            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::TagAttribute200Response`")))),
618        }
619    } else {
620        let content = resp.text().await?;
621        let entity: Option<TagAttributeError> = serde_json::from_str(&content).ok();
622        Err(Error::ResponseError(ResponseContent { status, content, entity }))
623    }
624}
625
626pub async fn untag_attribute(configuration: &configuration::Configuration, attribute_id: &str, tag_id: &str) -> Result<models::UntagAttribute200Response, Error<UntagAttributeError>> {
627    // add a prefix to parameters to efficiently prevent name collisions
628    let p_attribute_id = attribute_id;
629    let p_tag_id = tag_id;
630
631    let uri_str = format!("{}/attributes/removeTag/{attributeId}/{tagId}", configuration.base_path, attributeId=p_attribute_id.to_string(), tagId=crate::apis::urlencode(p_tag_id));
632    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
633
634    if let Some(ref user_agent) = configuration.user_agent {
635        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
636    }
637    if let Some(ref apikey) = configuration.api_key {
638        let key = apikey.key.clone();
639        let value = match apikey.prefix {
640            Some(ref prefix) => format!("{} {}", prefix, key),
641            None => key,
642        };
643        req_builder = req_builder.header("Authorization", value);
644    };
645
646    let req = req_builder.build()?;
647    let resp = configuration.client.execute(req).await?;
648
649    let status = resp.status();
650    let content_type = resp
651        .headers()
652        .get("content-type")
653        .and_then(|v| v.to_str().ok())
654        .unwrap_or("application/octet-stream");
655    let content_type = super::ContentType::from(content_type);
656
657    if !status.is_client_error() && !status.is_server_error() {
658        let content = resp.text().await?;
659        match content_type {
660            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
661            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UntagAttribute200Response`"))),
662            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::UntagAttribute200Response`")))),
663        }
664    } else {
665        let content = resp.text().await?;
666        let entity: Option<UntagAttributeError> = serde_json::from_str(&content).ok();
667        Err(Error::ResponseError(ResponseContent { status, content, entity }))
668    }
669}
670