bitwarden_vault/
collection.rs

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