diff --git a/services/tunnelbroker/src/main.rs b/services/tunnelbroker/src/main.rs index ce27590cb..bb5cf26b4 100644 --- a/services/tunnelbroker/src/main.rs +++ b/services/tunnelbroker/src/main.rs @@ -1,10 +1,11 @@ pub mod constants; pub mod cxx_bridge; +pub mod notifications; pub mod server; use anyhow::Result; #[tokio::main] async fn main() -> Result<()> { cxx_bridge::ffi::initialize(); server::run_grpc_server().await } diff --git a/services/tunnelbroker/src/notifications/apns.rs b/services/tunnelbroker/src/notifications/apns.rs index 5d77e9517..5f1656c02 100644 --- a/services/tunnelbroker/src/notifications/apns.rs +++ b/services/tunnelbroker/src/notifications/apns.rs @@ -1,56 +1,60 @@ -use crate::ffi::apns_status; +use super::CONFIG; use a2::{ Client, Endpoint, Error, ErrorReason::{BadDeviceToken, Unregistered}, NotificationBuilder, NotificationOptions, PlainNotificationBuilder, }; -use anyhow::{bail, Result}; use std::fs::File; +pub enum ApnsError { + BadDeviceToken, + Unregistered, + CommonError(anyhow::Error), +} + pub async fn send_by_a2_client( - certificate_path: &str, - certificate_password: &str, device_token: &str, - topic: &str, message: &str, - sandbox: bool, -) -> Result { - let mut certificate = File::open(certificate_path)?; - let endpoint = if sandbox { +) -> Result<(), ApnsError> { + let mut certificate = File::open(&CONFIG.apns_certificate_path) + .expect("Error opening apns certificate file"); + let endpoint = if CONFIG.is_sandbox { Endpoint::Sandbox } else { Endpoint::Production }; - let client = - Client::certificate(&mut certificate, certificate_password, endpoint)?; + let client = Client::certificate( + &mut certificate, + &CONFIG.apns_certificate_password, + endpoint, + ) + .expect("Error creating client on apns certificate"); let options = NotificationOptions { - apns_topic: Some(topic), + apns_topic: Some(&CONFIG.apns_topic), ..Default::default() }; let builder = PlainNotificationBuilder::new(message); let mut payload = builder.build(device_token, options); payload.aps.content_available = Some(1); match client.send(payload).await { - Ok(_) => Ok(apns_status::Ok), + Ok(_) => Ok(()), Err(Error::ResponseError(response)) => { if let Some(error_body) = response.error { match error_body.reason { - // We are returning `Ok` with the error types here to distinguish the exact - // error type in a C++ side - BadDeviceToken => Ok(apns_status::BadDeviceToken), - Unregistered => Ok(apns_status::Unregistered), - _ => bail!( + BadDeviceToken => Err(ApnsError::BadDeviceToken), + Unregistered => Err(ApnsError::Unregistered), + _ => Err(ApnsError::CommonError(anyhow::Error::msg(format!( "Notification was not accepted by APNs, reason: {:?}", error_body.reason - ), + )))), } } else { - bail!( + Err(ApnsError::CommonError(anyhow::Error::msg(format!( "Unhandled response error from APNs, response: {:?}", response - ) + )))) } } - Err(error) => Err(anyhow::Error::new(error)), + Err(error) => Err(ApnsError::CommonError(anyhow::Error::new(error))), } } diff --git a/services/tunnelbroker/src/notifications/fcm.rs b/services/tunnelbroker/src/notifications/fcm.rs index 74d176bec..2cce5cb8a 100644 --- a/services/tunnelbroker/src/notifications/fcm.rs +++ b/services/tunnelbroker/src/notifications/fcm.rs @@ -1,44 +1,60 @@ -use crate::ffi::fcm_status; -use anyhow::{bail, ensure, Result}; +use super::CONFIG; +use anyhow::Result; use fcm::{ response::ErrorReason::{InvalidRegistration, NotRegistered}, Client, MessageBuilder, NotificationBuilder, }; +pub enum FcmError { + InvalidRegistration, + NotRegistered, + CommonError(anyhow::Error), +} + pub async fn send_by_fcm_client( - fcm_api_key: &str, device_registration_id: &str, message_title: &str, message_body: &str, -) -> Result { +) -> Result<(), FcmError> { let client = Client::new(); let mut notification_builder = NotificationBuilder::new(); notification_builder.title(message_title); notification_builder.body(message_body); let notification = notification_builder.finalize(); let mut message_builder = - MessageBuilder::new(fcm_api_key, device_registration_id); + MessageBuilder::new(&CONFIG.fcm_api_key, device_registration_id); message_builder.notification(notification); - let result = client.send(message_builder.finalize()).await?; - match result.results { - Some(results) => { - ensure!(results.len() > 0, "FCM client returned zero size results"); - if let Some(result_error) = results[0].error { - match result_error { - // We are returning `Ok` with the error types here to distinguish the exact - // error type in a C++ side - InvalidRegistration => return Ok(fcm_status::InvalidRegistration), - NotRegistered => return Ok(fcm_status::NotRegistered), - _ => bail!( - "Notification was not accepted by FCM, reason: {:?}", - result_error, - ), + let result = client.send(message_builder.finalize()).await; + match result { + Ok(result) => match result.results { + Some(results) => { + if results.len() == 0 { + return Err(FcmError::CommonError(anyhow::Error::msg( + "FCM client returned zero size results", + ))); + }; + if let Some(result_error) = results[0].error { + match result_error { + InvalidRegistration => return Err(FcmError::InvalidRegistration), + NotRegistered => return Err(FcmError::NotRegistered), + _ => { + return Err(FcmError::CommonError(anyhow::Error::msg(format!( + "Notification was not accepted by FCM, reason: {:?}", + result_error + )))) + } + } } } - } - None => bail!("FCM client has no results set"), + None => { + return Err(FcmError::CommonError(anyhow::Error::msg( + "FCM client has no results set", + ))) + } + }, + Err(err) => return Err(FcmError::CommonError(anyhow::Error::from(err))), } - Ok(fcm_status::Ok) + Ok(()) }