webex_message_handler/
message_decryptor.rs1use crate::errors::WebexError;
4use crate::jwe;
5use crate::kms_client::KmsClient;
6use crate::types::MercuryActivity;
7use tracing::warn;
8
9pub struct MessageDecryptor<'a> {
11 kms_client: &'a mut KmsClient,
12}
13
14impl<'a> MessageDecryptor<'a> {
15 pub fn new(kms_client: &'a mut KmsClient) -> Self {
16 Self { kms_client }
17 }
18
19 pub async fn decrypt_activity(
24 &mut self,
25 activity: &MercuryActivity,
26 ) -> Result<MercuryActivity, WebexError> {
27 let encryption_key_url = activity
29 .encryption_key_url
30 .as_deref()
31 .filter(|s| !s.is_empty())
32 .or_else(|| {
33 activity
34 .object
35 .encryption_key_url
36 .as_deref()
37 .filter(|s| !s.is_empty())
38 })
39 .or_else(|| {
40 activity
41 .target
42 .encryption_key_url
43 .as_deref()
44 .filter(|s| !s.is_empty())
45 });
46
47 let encryption_key_url = match encryption_key_url {
49 Some(url) => url.to_string(),
50 None => return Ok(activity.clone()),
51 };
52
53 let key = self
55 .kms_client
56 .get_key(&encryption_key_url)
57 .await
58 .map_err(|e| {
59 WebexError::decryption(format!(
60 "Failed to fetch encryption key from {encryption_key_url}: {e}"
61 ))
62 })?;
63
64 let mut decrypted = activity.clone();
66
67 if let Some(ref display_name) = decrypted.object.display_name {
69 if !display_name.is_empty() {
70 match jwe::decrypt_message_jwe(display_name, &key) {
71 Ok(plaintext) => {
72 decrypted.object.display_name = Some(
73 String::from_utf8(plaintext).unwrap_or_else(|_| {
74 display_name.clone()
75 }),
76 );
77 }
78 Err(e) => {
79 warn!(
80 "Failed to decrypt displayName in activity {}: {e}",
81 activity.id
82 );
83 }
84 }
85 }
86 }
87
88 if let Some(ref content) = decrypted.object.content {
90 if !content.is_empty() {
91 match jwe::decrypt_message_jwe(content, &key) {
92 Ok(plaintext) => {
93 decrypted.object.content = Some(
94 String::from_utf8(plaintext).unwrap_or_else(|_| {
95 content.clone()
96 }),
97 );
98 }
99 Err(e) => {
100 warn!(
101 "Failed to decrypt content in activity {}: {e}",
102 activity.id
103 );
104 }
105 }
106 }
107 }
108
109 Ok(decrypted)
110 }
111}