bitwarden_vault/folder/
folder_models.rs

1use bitwarden_api_api::models::FolderResponseModel;
2use bitwarden_core::{
3    key_management::{KeyIds, SymmetricKeyId},
4    require,
5};
6use bitwarden_crypto::{
7    CompositeEncryptable, CryptoError, Decryptable, EncString, IdentifyKey, KeyStoreContext,
8    PrimitiveEncryptable,
9};
10use bitwarden_uuid::uuid_newtype;
11use chrono::{DateTime, Utc};
12use serde::{Deserialize, Serialize};
13#[cfg(feature = "wasm")]
14use {tsify::Tsify, wasm_bindgen::prelude::*};
15
16use crate::VaultParseError;
17
18uuid_newtype!(pub FolderId);
19
20#[allow(missing_docs)]
21#[derive(Serialize, Deserialize, Debug, Clone)]
22#[serde(rename_all = "camelCase")]
23#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
24#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
25pub struct Folder {
26    pub id: Option<FolderId>,
27    pub name: EncString,
28    pub revision_date: DateTime<Utc>,
29}
30
31bitwarden_state::register_repository_item!(Folder, "Folder");
32
33#[allow(missing_docs)]
34#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
35#[serde(rename_all = "camelCase")]
36#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
37#[cfg_attr(feature = "wasm", derive(Tsify), tsify(into_wasm_abi, from_wasm_abi))]
38pub struct FolderView {
39    pub id: Option<FolderId>,
40    pub name: String,
41    pub revision_date: DateTime<Utc>,
42}
43
44#[cfg(feature = "wasm")]
45impl wasm_bindgen::__rt::VectorIntoJsValue for FolderView {
46    fn vector_into_jsvalue(
47        vector: wasm_bindgen::__rt::std::boxed::Box<[Self]>,
48    ) -> wasm_bindgen::JsValue {
49        wasm_bindgen::__rt::js_value_vector_into_jsvalue(vector)
50    }
51}
52
53impl IdentifyKey<SymmetricKeyId> for Folder {
54    fn key_identifier(&self) -> SymmetricKeyId {
55        SymmetricKeyId::User
56    }
57}
58impl IdentifyKey<SymmetricKeyId> for FolderView {
59    fn key_identifier(&self) -> SymmetricKeyId {
60        SymmetricKeyId::User
61    }
62}
63
64impl CompositeEncryptable<KeyIds, SymmetricKeyId, Folder> for FolderView {
65    fn encrypt_composite(
66        &self,
67        ctx: &mut KeyStoreContext<KeyIds>,
68        key: SymmetricKeyId,
69    ) -> Result<Folder, CryptoError> {
70        Ok(Folder {
71            id: self.id,
72            name: self.name.encrypt(ctx, key)?,
73            revision_date: self.revision_date,
74        })
75    }
76}
77
78impl Decryptable<KeyIds, SymmetricKeyId, FolderView> for Folder {
79    fn decrypt(
80        &self,
81        ctx: &mut KeyStoreContext<KeyIds>,
82        key: SymmetricKeyId,
83    ) -> Result<FolderView, CryptoError> {
84        Ok(FolderView {
85            id: self.id,
86            name: self.name.decrypt(ctx, key).ok().unwrap_or_default(),
87            revision_date: self.revision_date,
88        })
89    }
90}
91
92impl TryFrom<FolderResponseModel> for Folder {
93    type Error = VaultParseError;
94
95    fn try_from(folder: FolderResponseModel) -> Result<Self, Self::Error> {
96        Ok(Folder {
97            id: folder.id.map(FolderId::new),
98            name: require!(EncString::try_from_optional(folder.name)?),
99            revision_date: require!(folder.revision_date).parse()?,
100        })
101    }
102}