webex_message_handler/
device_manager.rs1use crate::errors::{Result, WebexError};
4use crate::types::DeviceRegistration;
5use serde_json::json;
6use tracing::{debug, error, info};
7
8const WDM_API_BASE: &str = "https://wdm-a.wbx2.com/wdm/api/v1/devices";
9
10fn device_body() -> serde_json::Value {
11 json!({
12 "deviceName": "webex-message-handler",
13 "deviceType": "DESKTOP",
14 "localizedModel": "rust",
15 "model": "rust",
16 "name": "webex-message-handler",
17 "systemName": "webex-message-handler",
18 "systemVersion": "1.0.0"
19 })
20}
21
22pub struct DeviceManager {
24 device_url: Option<String>,
25 client: reqwest::Client,
26}
27
28impl DeviceManager {
29 pub fn new(client: reqwest::Client) -> Self {
30 Self {
31 device_url: None,
32 client,
33 }
34 }
35
36 pub async fn register(&mut self, token: &str) -> Result<DeviceRegistration> {
38 debug!("Registering device with WDM");
39
40 let response = self
41 .client
42 .post(WDM_API_BASE)
43 .header("Authorization", format!("Bearer {}", token))
44 .header("Content-Type", "application/json")
45 .json(&device_body())
46 .send()
47 .await
48 .map_err(|e| WebexError::device_registration(format!("Failed to register device: {e}"), None))?;
49
50 let status = response.status().as_u16();
51
52 if status == 401 {
53 error!("Device registration failed: Unauthorized");
54 return Err(WebexError::auth("Unauthorized to register device"));
55 }
56
57 if !response.status().is_success() {
58 error!("Device registration failed with status {status}");
59 return Err(WebexError::device_registration("Failed to register device", Some(status)));
60 }
61
62 let mut reg: DeviceRegistration = response
63 .json()
64 .await
65 .map_err(|e| WebexError::device_registration(format!("Failed to parse response: {e}"), None))?;
66
67 reg.encryption_service_url = reg.services.get("encryptionServiceUrl").cloned().unwrap_or_default();
68 self.device_url = Some(reg.device_url.clone());
69
70 info!("Device registered successfully");
71 Ok(reg)
72 }
73
74 pub async fn refresh(&self, token: &str) -> Result<DeviceRegistration> {
76 let device_url = self.device_url.as_deref().ok_or_else(|| {
77 WebexError::device_registration("Device not registered. Call register() first.", None)
78 })?;
79
80 debug!("Refreshing device registration");
81
82 let response = self
83 .client
84 .put(device_url)
85 .header("Authorization", format!("Bearer {}", token))
86 .header("Content-Type", "application/json")
87 .json(&device_body())
88 .send()
89 .await
90 .map_err(|e| WebexError::device_registration(format!("Failed to refresh device: {e}"), None))?;
91
92 let status = response.status().as_u16();
93
94 if status == 401 {
95 error!("Device refresh failed: Unauthorized");
96 return Err(WebexError::auth("Unauthorized to refresh device"));
97 }
98
99 if !response.status().is_success() {
100 error!("Device refresh failed with status {status}");
101 return Err(WebexError::device_registration("Failed to refresh device", Some(status)));
102 }
103
104 let mut reg: DeviceRegistration = response
105 .json()
106 .await
107 .map_err(|e| WebexError::device_registration(format!("Failed to parse response: {e}"), None))?;
108
109 reg.encryption_service_url = reg.services.get("encryptionServiceUrl").cloned().unwrap_or_default();
110
111 info!("Device refreshed successfully");
112 Ok(reg)
113 }
114
115 pub async fn unregister(&mut self, token: &str) -> Result<()> {
117 let device_url = self.device_url.as_deref().ok_or_else(|| {
118 WebexError::device_registration("Device not registered. Call register() first.", None)
119 })?;
120
121 debug!("Unregistering device");
122
123 let response = self
124 .client
125 .delete(device_url)
126 .header("Authorization", format!("Bearer {}", token))
127 .header("Content-Type", "application/json")
128 .send()
129 .await
130 .map_err(|e| WebexError::device_registration(format!("Failed to unregister device: {e}"), None))?;
131
132 let status = response.status().as_u16();
133
134 if status == 401 {
135 error!("Device unregistration failed: Unauthorized");
136 return Err(WebexError::auth("Unauthorized to unregister device"));
137 }
138
139 if !response.status().is_success() && status != 404 {
140 error!("Device unregistration failed with status {status}");
141 return Err(WebexError::device_registration("Failed to unregister device", Some(status)));
142 }
143
144 self.device_url = None;
145 info!("Device unregistered successfully");
146 Ok(())
147 }
148}