Skip to main content

bitwarden_vault/cipher/attachment_client/admin/
create.rs

1use bitwarden_core::{ApiError, MissingFieldError};
2use bitwarden_error::bitwarden_error;
3use thiserror::Error;
4
5use super::super::create::{CreateAttachmentFailure, create_attachment};
6use crate::{
7    AttachmentAdminClient, CipherId, CreateAttachmentRequest, CreatedAttachment, VaultParseError,
8    cipher::cipher::PartialCipher,
9};
10
11#[allow(missing_docs)]
12#[bitwarden_error(flat)]
13#[derive(Debug, Error)]
14pub enum CreateAttachmentAdminError {
15    #[error(transparent)]
16    Api(#[from] ApiError),
17    #[error(transparent)]
18    MissingField(#[from] MissingFieldError),
19    #[error(transparent)]
20    VaultParse(#[from] VaultParseError),
21    #[error("Server returned an unsupported file upload type")]
22    UnsupportedFileUploadType,
23}
24
25impl CreateAttachmentFailure for CreateAttachmentAdminError {
26    fn unsupported_file_upload_type() -> Self {
27        Self::UnsupportedFileUploadType
28    }
29}
30
31#[bitwarden_ffi::wasm_export]
32impl AttachmentAdminClient {
33    /// Creates a new attachment slot on the server using the admin endpoint.
34    /// Affects server data only, does not modify local state.
35    ///
36    /// The caller must upload the encrypted bytes to [`CreatedAttachment::upload_url`]
37    /// using the transport in [`CreatedAttachment::file_upload_type`].
38    ///
39    /// If a later step fails after slot creation, the SDK best-effort deletes the
40    /// orphaned slot via the admin endpoint and returns the original error.
41    pub async fn create_attachment(
42        &self,
43        cipher_id: CipherId,
44        request: CreateAttachmentRequest,
45    ) -> Result<CreatedAttachment, CreateAttachmentAdminError> {
46        create_attachment(
47            &self.api_configurations.api_client,
48            cipher_id,
49            request,
50            true,
51            async |response| {
52                let cipher_mini = response
53                    .cipher_mini_response
54                    .ok_or(MissingFieldError("cipher_mini_response"))?;
55                Ok((*cipher_mini).merge_with_cipher(None)?)
56            },
57        )
58        .await
59    }
60}