bitwarden_sm/secrets/
secret_response.rs

1use bitwarden_api_api::models::{
2    BaseSecretResponseModel, BaseSecretResponseModelListResponseModel, SecretResponseModel,
3};
4use bitwarden_core::{
5    key_management::{KeyIds, SymmetricKeyId},
6    require,
7};
8use bitwarden_crypto::{Decryptable, EncString, KeyStoreContext};
9use chrono::{DateTime, Utc};
10use schemars::JsonSchema;
11use serde::{Deserialize, Serialize};
12use uuid::Uuid;
13
14use crate::error::SecretsManagerError;
15
16#[derive(Serialize, Deserialize, Debug, JsonSchema)]
17#[serde(rename_all = "camelCase", deny_unknown_fields)]
18pub struct SecretResponse {
19    pub id: Uuid,
20    pub organization_id: Uuid,
21    pub project_id: Option<Uuid>,
22
23    pub key: String,
24    pub value: String,
25    pub note: String,
26
27    pub creation_date: DateTime<Utc>,
28    pub revision_date: DateTime<Utc>,
29}
30
31impl SecretResponse {
32    pub(crate) fn process_response(
33        response: SecretResponseModel,
34        ctx: &mut KeyStoreContext<KeyIds>,
35    ) -> Result<SecretResponse, SecretsManagerError> {
36        let base = BaseSecretResponseModel {
37            object: response.object,
38            id: response.id,
39            organization_id: response.organization_id,
40            key: response.key,
41            value: response.value,
42            note: response.note,
43            creation_date: response.creation_date,
44            revision_date: response.revision_date,
45            projects: response.projects,
46        };
47        Self::process_base_response(base, ctx)
48    }
49    pub(crate) fn process_base_response(
50        response: BaseSecretResponseModel,
51        ctx: &mut KeyStoreContext<KeyIds>,
52    ) -> Result<SecretResponse, SecretsManagerError> {
53        let organization_id = require!(response.organization_id);
54        let enc_key = SymmetricKeyId::Organization(organization_id);
55
56        let key = require!(response.key)
57            .parse::<EncString>()?
58            .decrypt(ctx, enc_key)?;
59
60        let value = require!(response.value)
61            .parse::<EncString>()?
62            .decrypt(ctx, enc_key)?;
63
64        let note = require!(response.note)
65            .parse::<EncString>()?
66            .decrypt(ctx, enc_key)?;
67
68        let project = response
69            .projects
70            .and_then(|p| p.into_iter().next())
71            .and_then(|p| p.id);
72
73        Ok(SecretResponse {
74            id: require!(response.id),
75            organization_id,
76            project_id: project,
77            key,
78            value,
79            note,
80
81            creation_date: require!(response.creation_date).parse()?,
82            revision_date: require!(response.revision_date).parse()?,
83        })
84    }
85}
86
87#[derive(Serialize, Deserialize, Debug, JsonSchema)]
88#[serde(rename_all = "camelCase", deny_unknown_fields)]
89pub struct SecretsResponse {
90    pub data: Vec<SecretResponse>,
91}
92
93impl SecretsResponse {
94    pub(crate) fn process_response(
95        response: BaseSecretResponseModelListResponseModel,
96        ctx: &mut KeyStoreContext<KeyIds>,
97    ) -> Result<SecretsResponse, SecretsManagerError> {
98        Ok(SecretsResponse {
99            data: response
100                .data
101                .unwrap_or_default()
102                .into_iter()
103                .map(|r| SecretResponse::process_base_response(r, ctx))
104                .collect::<Result<_, _>>()?,
105        })
106    }
107}