bitwarden_vault/cipher/cipher_client/admin/
delete.rs1use bitwarden_api_api::models::CipherBulkDeleteRequestModel;
2use bitwarden_core::{ApiError, OrganizationId};
3use bitwarden_error::bitwarden_error;
4use thiserror::Error;
5#[cfg(feature = "wasm")]
6use wasm_bindgen::prelude::wasm_bindgen;
7
8use crate::{CipherId, cipher_client::admin::CipherAdminClient};
9
10#[allow(missing_docs)]
11#[bitwarden_error(flat)]
12#[derive(Debug, Error)]
13pub enum DeleteCipherAdminError {
15 #[error(transparent)]
18 Api(#[from] ApiError),
19}
20
21async fn delete_cipher(
22 cipher_id: CipherId,
23 api_client: &bitwarden_api_api::apis::ApiClient,
24) -> Result<(), ApiError> {
25 let api = api_client.ciphers_api();
26 api.delete_admin(cipher_id.into()).await?;
27 Ok(())
28}
29
30async fn delete_ciphers_many(
31 cipher_ids: Vec<CipherId>,
32 organization_id: OrganizationId,
33 api_client: &bitwarden_api_api::apis::ApiClient,
34) -> Result<(), ApiError> {
35 let api = api_client.ciphers_api();
36
37 api.delete_many_admin(Some(CipherBulkDeleteRequestModel {
38 ids: cipher_ids.iter().map(|id| id.to_string()).collect(),
39 organization_id: Some(organization_id.to_string()),
40 }))
41 .await?;
42
43 Ok(())
44}
45
46async fn soft_delete(
47 cipher_id: CipherId,
48 api_client: &bitwarden_api_api::apis::ApiClient,
49) -> Result<(), ApiError> {
50 let api = api_client.ciphers_api();
51 api.put_delete_admin(cipher_id.into()).await?;
52 Ok(())
53}
54
55async fn soft_delete_many(
56 cipher_ids: Vec<CipherId>,
57 organization_id: OrganizationId,
58 api_client: &bitwarden_api_api::apis::ApiClient,
59) -> Result<(), ApiError> {
60 let api = api_client.ciphers_api();
61
62 api.put_delete_many_admin(Some(CipherBulkDeleteRequestModel {
63 ids: cipher_ids.iter().map(|id| id.to_string()).collect(),
64 organization_id: Some(organization_id.to_string()),
65 }))
66 .await?;
67 Ok(())
68}
69
70#[cfg_attr(feature = "wasm", wasm_bindgen)]
71impl CipherAdminClient {
72 pub async fn delete(&self, cipher_id: CipherId) -> Result<(), DeleteCipherAdminError> {
75 Ok(delete_cipher(cipher_id, &self.api_configurations.api_client).await?)
76 }
77
78 pub async fn soft_delete(&self, cipher_id: CipherId) -> Result<(), DeleteCipherAdminError> {
81 Ok(soft_delete(cipher_id, &self.api_configurations.api_client).await?)
82 }
83
84 pub async fn delete_many(
87 &self,
88 cipher_ids: Vec<CipherId>,
89 organization_id: OrganizationId,
90 ) -> Result<(), DeleteCipherAdminError> {
91 Ok(delete_ciphers_many(
92 cipher_ids,
93 organization_id,
94 &self.api_configurations.api_client,
95 )
96 .await?)
97 }
98
99 pub async fn soft_delete_many(
102 &self,
103 cipher_ids: Vec<CipherId>,
104 organization_id: OrganizationId,
105 ) -> Result<(), DeleteCipherAdminError> {
106 Ok(soft_delete_many(
107 cipher_ids,
108 organization_id,
109 &self.api_configurations.api_client,
110 )
111 .await?)
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 const TEST_CIPHER_ID: &str = "5faa9684-c793-4a2d-8a12-b33900187097";
120 const TEST_CIPHER_ID_2: &str = "6faa9684-c793-4a2d-8a12-b33900187098";
121 const TEST_ORG_ID: &str = "1bc9ac1e-f5aa-45f2-94bf-b181009709b8";
122
123 #[tokio::test]
124 async fn test_delete_as_admin() {
125 delete_cipher(
126 TEST_CIPHER_ID.parse().unwrap(),
127 &bitwarden_api_api::apis::ApiClient::new_mocked(|mock| {
128 mock.ciphers_api.expect_delete_admin().returning(move |id| {
129 assert_eq!(&id.to_string(), TEST_CIPHER_ID);
130 Ok(())
131 });
132 }),
133 )
134 .await
135 .unwrap()
136 }
137
138 #[tokio::test]
139 async fn test_soft_delete_as_admin() {
140 soft_delete(
141 TEST_CIPHER_ID.parse().unwrap(),
142 &bitwarden_api_api::apis::ApiClient::new_mocked(|mock| {
143 mock.ciphers_api
144 .expect_put_delete_admin()
145 .returning(move |id| {
146 assert_eq!(&id.to_string(), TEST_CIPHER_ID);
147 Ok(())
148 });
149 }),
150 )
151 .await
152 .unwrap()
153 }
154
155 #[tokio::test]
156 async fn test_delete_many_as_admin() {
157 delete_ciphers_many(
158 vec![
159 TEST_CIPHER_ID.parse().unwrap(),
160 TEST_CIPHER_ID_2.parse().unwrap(),
161 ],
162 TEST_ORG_ID.parse().unwrap(),
163 &bitwarden_api_api::apis::ApiClient::new_mocked(|mock| {
164 mock.ciphers_api
165 .expect_delete_many_admin()
166 .returning(move |request| {
167 let CipherBulkDeleteRequestModel {
168 ids,
169 organization_id,
170 } = request.unwrap();
171
172 assert_eq!(
173 ids,
174 vec![TEST_CIPHER_ID.to_string(), TEST_CIPHER_ID_2.to_string(),],
175 );
176 assert_eq!(organization_id, Some(TEST_ORG_ID.to_string()));
177 Ok(())
178 });
179 }),
180 )
181 .await
182 .unwrap()
183 }
184
185 #[tokio::test]
186 async fn test_soft_delete_many_as_admin() {
187 soft_delete_many(
188 vec![
189 TEST_CIPHER_ID.parse().unwrap(),
190 TEST_CIPHER_ID_2.parse().unwrap(),
191 ],
192 TEST_ORG_ID.parse().unwrap(),
193 &bitwarden_api_api::apis::ApiClient::new_mocked(|mock| {
194 mock.ciphers_api
195 .expect_put_delete_many_admin()
196 .returning(move |request| {
197 let CipherBulkDeleteRequestModel {
198 ids,
199 organization_id,
200 } = request.unwrap();
201
202 assert_eq!(
203 ids,
204 vec![TEST_CIPHER_ID.to_string(), TEST_CIPHER_ID_2.to_string()],
205 );
206 assert_eq!(organization_id, Some(TEST_ORG_ID.to_string()));
207 Ok(())
208 });
209 }),
210 )
211 .await
212 .unwrap()
213 }
214}