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