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