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