bitwarden_sm/secrets/
secret_response.rs1use 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}