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