Skip to main content

bitwarden_vault/cipher/attachment_client/admin/
delete.rs

1use bitwarden_core::{ApiError, MissingFieldError};
2use bitwarden_error::bitwarden_error;
3use thiserror::Error;
4#[cfg(feature = "wasm")]
5use wasm_bindgen::prelude::wasm_bindgen;
6
7use crate::{
8    AttachmentAdminClient, Cipher, CipherId, VaultParseError, cipher::cipher::PartialCipher,
9};
10
11#[allow(missing_docs)]
12#[bitwarden_error(flat)]
13#[derive(Debug, Error)]
14pub enum DeleteAttachmentAdminError {
15    #[error(transparent)]
16    Api(#[from] ApiError),
17    #[error(transparent)]
18    MissingField(#[from] MissingFieldError),
19    #[error(transparent)]
20    VaultParse(#[from] VaultParseError),
21}
22
23#[cfg_attr(feature = "wasm", wasm_bindgen)]
24impl AttachmentAdminClient {
25    /// Deletes an attachment from a cipher using the admin endpoint.
26    /// Affects server data only, does not modify local state.
27    pub async fn delete_attachment(
28        &self,
29        cipher_id: CipherId,
30        attachment_id: String,
31    ) -> Result<Cipher, DeleteAttachmentAdminError> {
32        let response = self
33            .api_configurations
34            .api_client
35            .ciphers_api()
36            .delete_attachment_admin(cipher_id.into(), &attachment_id)
37            .await?;
38
39        let cipher_response = response
40            .cipher
41            .map(|c| *c)
42            .ok_or(MissingFieldError("cipher"))?;
43        Ok(cipher_response.merge_with_cipher(None)?)
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use std::sync::Arc;
50
51    use bitwarden_api_api::{
52        apis::ApiClient,
53        models::{CipherMiniResponseModel, DeleteAttachmentResponseModel},
54    };
55    use bitwarden_core::client::ApiConfigurations;
56
57    use super::*;
58
59    const TEST_CIPHER_ID: &str = "5faa9684-c793-4a2d-8a12-b33900187097";
60    const TEST_ATTACHMENT_ID: &str = "uf7bkexzag04d3cw04jsbqqkbpbwhxs0";
61
62    fn client_with_api(api_client: ApiClient) -> AttachmentAdminClient {
63        AttachmentAdminClient {
64            api_configurations: Arc::new(ApiConfigurations::from_api_client(api_client)),
65        }
66    }
67
68    #[tokio::test]
69    async fn test_delete_attachment_as_admin() {
70        let api_client = ApiClient::new_mocked(|mock| {
71            mock.ciphers_api.expect_delete_attachment_admin().returning(
72                move |id, attachment_id| {
73                    assert_eq!(&id.to_string(), TEST_CIPHER_ID);
74                    assert_eq!(attachment_id, TEST_ATTACHMENT_ID);
75                    Ok(DeleteAttachmentResponseModel {
76                        object: None,
77                        cipher: Some(Box::new(CipherMiniResponseModel {
78                            id: Some(TEST_CIPHER_ID.try_into().unwrap()),
79                            name: Some("2.pMS6/icTQABtulw52pq2lg==|XXbxKxDTh+mWiN1HjH2N1w==|Q6PkuT+KX/axrgN9ubD5Ajk2YNwxQkgs3WJM0S0wtG8=".to_string()),
80                            r#type: Some(bitwarden_api_api::models::CipherType::Login),
81                            creation_date: Some("2024-05-31T11:20:58.4566667Z".to_string()),
82                            revision_date: Some("2024-05-31T11:20:58.4566667Z".to_string()),
83                            attachments: None,
84                            ..Default::default()
85                        })),
86                    })
87                },
88            );
89        });
90
91        let client = client_with_api(api_client);
92        let result = client
93            .delete_attachment(
94                TEST_CIPHER_ID.parse().unwrap(),
95                TEST_ATTACHMENT_ID.to_string(),
96            )
97            .await
98            .unwrap();
99
100        assert!(result.attachments.is_none());
101    }
102}