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(
76 cipher_id,
77 &self.client.internal.get_api_configurations().api_client,
78 )
79 .await?)
80 }
81
82 pub async fn soft_delete(&self, cipher_id: CipherId) -> Result<(), DeleteCipherAdminError> {
85 Ok(soft_delete(
86 cipher_id,
87 &self.client.internal.get_api_configurations().api_client,
88 )
89 .await?)
90 }
91
92 pub async fn delete_many(
95 &self,
96 cipher_ids: Vec<CipherId>,
97 organization_id: OrganizationId,
98 ) -> Result<(), DeleteCipherAdminError> {
99 Ok(delete_ciphers_many(
100 cipher_ids,
101 organization_id,
102 &self.client.internal.get_api_configurations().api_client,
103 )
104 .await?)
105 }
106
107 pub async fn soft_delete_many(
110 &self,
111 cipher_ids: Vec<CipherId>,
112 organization_id: OrganizationId,
113 ) -> Result<(), DeleteCipherAdminError> {
114 Ok(soft_delete_many(
115 cipher_ids,
116 organization_id,
117 &self.client.internal.get_api_configurations().api_client,
118 )
119 .await?)
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 const TEST_CIPHER_ID: &str = "5faa9684-c793-4a2d-8a12-b33900187097";
128 const TEST_CIPHER_ID_2: &str = "6faa9684-c793-4a2d-8a12-b33900187098";
129 const TEST_ORG_ID: &str = "1bc9ac1e-f5aa-45f2-94bf-b181009709b8";
130
131 #[tokio::test]
132 async fn test_delete_as_admin() {
133 delete_cipher(
134 TEST_CIPHER_ID.parse().unwrap(),
135 &bitwarden_api_api::apis::ApiClient::new_mocked(|mock| {
136 mock.ciphers_api.expect_delete_admin().returning(move |id| {
137 assert_eq!(&id.to_string(), TEST_CIPHER_ID);
138 Ok(())
139 });
140 }),
141 )
142 .await
143 .unwrap()
144 }
145
146 #[tokio::test]
147 async fn test_soft_delete_as_admin() {
148 soft_delete(
149 TEST_CIPHER_ID.parse().unwrap(),
150 &bitwarden_api_api::apis::ApiClient::new_mocked(|mock| {
151 mock.ciphers_api
152 .expect_put_delete_admin()
153 .returning(move |id| {
154 assert_eq!(&id.to_string(), TEST_CIPHER_ID);
155 Ok(())
156 });
157 }),
158 )
159 .await
160 .unwrap()
161 }
162
163 #[tokio::test]
164 async fn test_delete_many_as_admin() {
165 delete_ciphers_many(
166 vec![
167 TEST_CIPHER_ID.parse().unwrap(),
168 TEST_CIPHER_ID_2.parse().unwrap(),
169 ],
170 TEST_ORG_ID.parse().unwrap(),
171 &bitwarden_api_api::apis::ApiClient::new_mocked(|mock| {
172 mock.ciphers_api
173 .expect_delete_many_admin()
174 .returning(move |request| {
175 let CipherBulkDeleteRequestModel {
176 ids,
177 organization_id,
178 } = request.unwrap();
179
180 assert_eq!(
181 ids,
182 vec![TEST_CIPHER_ID.to_string(), TEST_CIPHER_ID_2.to_string(),],
183 );
184 assert_eq!(organization_id, Some(TEST_ORG_ID.to_string()));
185 Ok(())
186 });
187 }),
188 )
189 .await
190 .unwrap()
191 }
192
193 #[tokio::test]
194 async fn test_soft_delete_many_as_admin() {
195 soft_delete_many(
196 vec![
197 TEST_CIPHER_ID.parse().unwrap(),
198 TEST_CIPHER_ID_2.parse().unwrap(),
199 ],
200 TEST_ORG_ID.parse().unwrap(),
201 &bitwarden_api_api::apis::ApiClient::new_mocked(|mock| {
202 mock.ciphers_api
203 .expect_put_delete_many_admin()
204 .returning(move |request| {
205 let CipherBulkDeleteRequestModel {
206 ids,
207 organization_id,
208 } = request.unwrap();
209
210 assert_eq!(
211 ids,
212 vec![TEST_CIPHER_ID.to_string(), TEST_CIPHER_ID_2.to_string()],
213 );
214 assert_eq!(organization_id, Some(TEST_ORG_ID.to_string()));
215 Ok(())
216 });
217 }),
218 )
219 .await
220 .unwrap()
221 }
222}