bitwarden_vault/folder/
folder_models.rs1use 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
44impl IdentifyKey<SymmetricKeyId> for Folder {
45 fn key_identifier(&self) -> SymmetricKeyId {
46 SymmetricKeyId::User
47 }
48}
49impl IdentifyKey<SymmetricKeyId> for FolderView {
50 fn key_identifier(&self) -> SymmetricKeyId {
51 SymmetricKeyId::User
52 }
53}
54
55impl CompositeEncryptable<KeyIds, SymmetricKeyId, Folder> for FolderView {
56 fn encrypt_composite(
57 &self,
58 ctx: &mut KeyStoreContext<KeyIds>,
59 key: SymmetricKeyId,
60 ) -> Result<Folder, CryptoError> {
61 Ok(Folder {
62 id: self.id,
63 name: self.name.encrypt(ctx, key)?,
64 revision_date: self.revision_date,
65 })
66 }
67}
68
69impl Decryptable<KeyIds, SymmetricKeyId, FolderView> for Folder {
70 fn decrypt(
71 &self,
72 ctx: &mut KeyStoreContext<KeyIds>,
73 key: SymmetricKeyId,
74 ) -> Result<FolderView, CryptoError> {
75 Ok(FolderView {
76 id: self.id,
77 name: self.name.decrypt(ctx, key).ok().unwrap_or_default(),
78 revision_date: self.revision_date,
79 })
80 }
81}
82
83impl TryFrom<FolderResponseModel> for Folder {
84 type Error = VaultParseError;
85
86 fn try_from(folder: FolderResponseModel) -> Result<Self, Self::Error> {
87 Ok(Folder {
88 id: folder.id.map(FolderId::new),
89 name: require!(EncString::try_from_optional(folder.name)?),
90 revision_date: require!(folder.revision_date).parse()?,
91 })
92 }
93}