Page MenuHomePhabricator

D12935.id42928.diff
No OneTemporary

D12935.id42928.diff

diff --git a/services/tunnelbroker/src/notifs/wns/error.rs b/services/tunnelbroker/src/notifs/wns/error.rs
--- a/services/tunnelbroker/src/notifs/wns/error.rs
+++ b/services/tunnelbroker/src/notifs/wns/error.rs
@@ -12,4 +12,18 @@
ReadLock,
#[display(fmt = "Failed to acquire write lock")]
WriteLock,
+ #[display(fmt = "WNS Notification Error: {}", _0)]
+ WNSNotification(WNSNotificationError),
+ #[display(fmt = "Missing WNS ID")]
+ MissingWNSID,
}
+
+#[derive(Debug, Display)]
+pub enum WNSNotificationError {
+ #[display(fmt = "HTTP Error: {}", _0)]
+ Http(reqwest::Error),
+ #[display(fmt = "Unknown Error: {}", _0)]
+ Unknown(String),
+}
+
+impl std::error::Error for WNSNotificationError {}
diff --git a/services/tunnelbroker/src/notifs/wns/mod.rs b/services/tunnelbroker/src/notifs/wns/mod.rs
--- a/services/tunnelbroker/src/notifs/wns/mod.rs
+++ b/services/tunnelbroker/src/notifs/wns/mod.rs
@@ -13,6 +13,12 @@
expires: SystemTime,
}
+#[derive(Debug, Clone)]
+pub struct WNSNotif {
+ pub device_token: String,
+ pub payload: String,
+}
+
#[derive(Clone)]
pub struct WNSClient {
http_client: reqwest::Client,
@@ -30,9 +36,51 @@
})
}
- pub async fn get_wns_token(
- &mut self,
- ) -> Result<Option<String>, error::Error> {
+ pub async fn send(&self, notif: WNSNotif) -> Result<(), error::Error> {
+ let token = self.get_wns_token().await?.ok_or(
+ error::WNSNotificationError::Unknown(
+ "Failed to get WNS token".to_string(),
+ ),
+ )?;
+
+ let url = format!(
+ "https://dm3p.notify.windows.com/?token={}",
+ notif.device_token
+ );
+
+ // Send the notification
+ let response = self
+ .http_client
+ .post(&url)
+ .header("Content-Type", "application/octet-stream")
+ .header("X-WNS-Type", "wns/raw")
+ .bearer_auth(token)
+ .body(notif.payload)
+ .send()
+ .await?;
+
+ if !response.status().is_success() {
+ return Err(
+ error::WNSNotificationError::Unknown(
+ response
+ .text()
+ .await
+ .unwrap_or_else(|_| "Unknown error".to_string()),
+ )
+ .into(),
+ );
+ }
+
+ response
+ .headers()
+ .get("X-WNS-MSG-ID")
+ .and_then(|val| val.to_str().ok())
+ .ok_or(error::Error::MissingWNSID)?;
+
+ Ok(())
+ }
+
+ pub async fn get_wns_token(&self) -> Result<Option<String>, error::Error> {
let expiry_window_in_secs = 10;
{
diff --git a/services/tunnelbroker/src/websockets/session.rs b/services/tunnelbroker/src/websockets/session.rs
--- a/services/tunnelbroker/src/websockets/session.rs
+++ b/services/tunnelbroker/src/websockets/session.rs
@@ -34,6 +34,7 @@
AndroidConfig, AndroidMessagePriority, FCMMessage,
};
use crate::notifs::web_push::WebPushNotif;
+use crate::notifs::wns::WNSNotif;
use crate::notifs::NotifClient;
pub struct DeviceInfo {
@@ -70,6 +71,7 @@
MissingAPNsClient,
MissingFCMClient,
MissingWebPushClient,
+ MissingWNSClient,
MissingDeviceToken,
}
@@ -496,6 +498,43 @@
self.get_message_to_device_status(&notif.client_message_id, result),
)
}
+ DeviceToTunnelbrokerMessage::WNSNotif(notif) => {
+ if !self.device_info.is_authenticated {
+ debug!(
+ "Unauthenticated device {} tried to send WNS notif. Aborting.",
+ self.device_info.device_id
+ );
+ return Some(MessageSentStatus::Unauthenticated);
+ }
+ debug!("Received WNS notif for {}", notif.device_id);
+
+ let Some(wns_client) = self.notif_client.wns.clone() else {
+ return Some(self.get_message_to_device_status(
+ &notif.client_message_id,
+ Err(SessionError::MissingWNSClient),
+ ));
+ };
+
+ let device_token = match self.get_device_token(notif.device_id).await {
+ Ok(token) => token,
+ Err(e) => {
+ return Some(
+ self
+ .get_message_to_device_status(&notif.client_message_id, Err(e)),
+ )
+ }
+ };
+
+ let wns_notif = WNSNotif {
+ device_token,
+ payload: notif.payload,
+ };
+
+ let result = wns_client.send(wns_notif).await;
+ Some(
+ self.get_message_to_device_status(&notif.client_message_id, result),
+ )
+ }
_ => {
error!("Client sent invalid message type");
Some(MessageSentStatus::InvalidRequest)
diff --git a/shared/tunnelbroker_messages/src/messages/mod.rs b/shared/tunnelbroker_messages/src/messages/mod.rs
--- a/shared/tunnelbroker_messages/src/messages/mod.rs
+++ b/shared/tunnelbroker_messages/src/messages/mod.rs
@@ -44,6 +44,7 @@
APNsNotif(APNsNotif),
FCMNotif(FCMNotif),
WebPushNotif(WebPushNotif),
+ WNSNotif(WNSNotif),
MessageToDeviceRequest(MessageToDeviceRequest),
MessageReceiveConfirmation(MessageReceiveConfirmation),
MessageToTunnelbrokerRequest(MessageToTunnelbrokerRequest),
diff --git a/shared/tunnelbroker_messages/src/messages/notif.rs b/shared/tunnelbroker_messages/src/messages/notif.rs
--- a/shared/tunnelbroker_messages/src/messages/notif.rs
+++ b/shared/tunnelbroker_messages/src/messages/notif.rs
@@ -35,3 +35,14 @@
pub device_id: String,
pub payload: String,
}
+
+/// WNS notif built on client.
+#[derive(Serialize, Deserialize, PartialEq, Debug)]
+#[serde(tag = "type", rename_all = "camelCase")]
+pub struct WNSNotif {
+ #[serde(rename = "clientMessageID")]
+ pub client_message_id: String,
+ #[serde(rename = "deviceID")]
+ pub device_id: String,
+ pub payload: String,
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Sep 20, 9:15 AM (18 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2147843
Default Alt Text
D12935.id42928.diff (5 KB)

Event Timeline