bitwarden_vault/
folder.rs

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