bitwarden_vault/folder/
folder_models.rs1use bitwarden_api_api::models::{FolderResponseModel, FolderWithIdRequestModel};
2use bitwarden_core::{
3 key_management::{KeySlotIds, SymmetricKeySlotId},
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
14use crate::VaultParseError;
15
16uuid_newtype!(pub FolderId);
17
18#[allow(missing_docs)]
19#[derive(Serialize, Deserialize, Debug, Clone)]
20#[serde(rename_all = "camelCase")]
21#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
22#[bitwarden_ffi::wasm_record]
23pub struct Folder {
24 pub id: Option<FolderId>,
25 pub name: EncString,
26 pub revision_date: DateTime<Utc>,
27}
28
29bitwarden_state::register_repository_item!(FolderId => Folder, "Folder");
30
31#[allow(missing_docs)]
32#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
33#[serde(rename_all = "camelCase")]
34#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
35#[bitwarden_ffi::wasm_record]
36pub struct FolderView {
37 pub id: Option<FolderId>,
38 pub name: String,
39 pub revision_date: DateTime<Utc>,
40}
41
42impl IdentifyKey<SymmetricKeySlotId> for Folder {
43 fn key_identifier(&self) -> SymmetricKeySlotId {
44 SymmetricKeySlotId::User
45 }
46}
47impl IdentifyKey<SymmetricKeySlotId> for FolderView {
48 fn key_identifier(&self) -> SymmetricKeySlotId {
49 SymmetricKeySlotId::User
50 }
51}
52
53impl CompositeEncryptable<KeySlotIds, SymmetricKeySlotId, Folder> for FolderView {
54 fn encrypt_composite(
55 &self,
56 ctx: &mut KeyStoreContext<KeySlotIds>,
57 key: SymmetricKeySlotId,
58 ) -> Result<Folder, CryptoError> {
59 Ok(Folder {
60 id: self.id,
61 name: self.name.encrypt(ctx, key)?,
62 revision_date: self.revision_date,
63 })
64 }
65}
66
67impl Decryptable<KeySlotIds, SymmetricKeySlotId, FolderView> for Folder {
68 fn decrypt(
69 &self,
70 ctx: &mut KeyStoreContext<KeySlotIds>,
71 key: SymmetricKeySlotId,
72 ) -> Result<FolderView, CryptoError> {
73 Ok(FolderView {
74 id: self.id,
75 name: self.name.decrypt(ctx, key).ok().unwrap_or_default(),
76 revision_date: self.revision_date,
77 })
78 }
79}
80
81impl TryFrom<FolderResponseModel> for Folder {
82 type Error = VaultParseError;
83
84 fn try_from(folder: FolderResponseModel) -> Result<Self, Self::Error> {
85 Ok(Folder {
86 id: folder.id.map(FolderId::new),
87 name: require!(EncString::try_from_optional(folder.name)?),
88 revision_date: require!(folder.revision_date).parse()?,
89 })
90 }
91}
92
93impl From<&Folder> for FolderWithIdRequestModel {
94 fn from(val: &Folder) -> Self {
95 FolderWithIdRequestModel {
96 name: val.name.to_string(),
97 id: val.id.map(|id| id.0),
98 }
99 }
100}