azure_communications/
communication.rs1use crate::utils::{create_authorization_signature, format_utc_string};
2use anyhow::Result;
3use base64::{engine::general_purpose::STANDARD as base64, Engine};
4use regex::Regex;
5use reqwest::{
6 header::{HeaderMap, HeaderValue, AUTHORIZATION, CONTENT_TYPE},
7 Client, Url,
8};
9use ring::digest::{digest, SHA256};
10use time::OffsetDateTime;
11
12pub mod email;
13pub mod sms;
14
15#[derive(Debug, Clone)]
16pub struct AzureCommunicationService {
17 pub endpoint: String,
18 pub access_key: String,
19 pub request_client: Client,
20}
21
22impl AzureCommunicationService {
23 pub fn new(connection_string: &str, request_client: Option<Client>) -> Self {
24 let re = Regex::new(r"endpoint=(.*?);accesskey=(.*)").expect("Invalid regex");
25 let caps = re
26 .captures(connection_string)
27 .expect("Invalid connection string");
28
29 let endpoint = caps[1].to_string();
30 let access_key = caps[2].to_string();
31 let request_client = request_client.unwrap_or_default();
32
33 AzureCommunicationService {
34 endpoint: endpoint.to_string(),
35 access_key: access_key.to_string(),
36 request_client,
37 }
38 }
39}
40
41impl AzureCommunicationService {
42 fn create_az_request(&self, url: Url, body: String) -> Result<reqwest::RequestBuilder> {
43 let access_key = &self.access_key;
44 let client = &self.request_client;
45
46 let content_hash = digest(&SHA256, body.as_bytes());
47 let content_hash_base64 = base64.encode(content_hash);
48
49 let now = OffsetDateTime::now_utc();
50 let date = format_utc_string(now)?;
51
52 let signature = create_authorization_signature(&url, &body, access_key, &date)?;
53
54 let mut headers = HeaderMap::new();
55 headers.insert("x-ms-date", HeaderValue::from_str(&date)?);
56 headers.insert(
57 "x-ms-content-sha256",
58 HeaderValue::from_str(&content_hash_base64)?,
59 );
60 headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));
61 headers.insert(
62 AUTHORIZATION,
63 HeaderValue::from_str(&format!(
64 "HMAC-SHA256 SignedHeaders=x-ms-date;host;x-ms-content-sha256&Signature={}",
65 signature
66 ))?,
67 );
68
69 let request = client.post(url).headers(headers).body(body);
70
71 Ok(request)
72 }
73}