diff --git a/services/tunnelbroker/src/constants.rs b/services/tunnelbroker/src/constants.rs --- a/services/tunnelbroker/src/constants.rs +++ b/services/tunnelbroker/src/constants.rs @@ -15,6 +15,7 @@ pub const ENV_FCM_CONFIG: &str = "FCM_CONFIG"; pub const LOG_LEVEL_ENV_VAR: &str = tracing_subscriber::filter::EnvFilter::DEFAULT_ENV; +pub const FCM_ACCESS_TOKEN_GENERATION_THRESHOLD: u64 = 5 * 60; pub mod dynamodb { // This table holds messages which could not be immediately delivered to diff --git a/services/tunnelbroker/src/notifs/fcm/token.rs b/services/tunnelbroker/src/notifs/fcm/token.rs --- a/services/tunnelbroker/src/notifs/fcm/token.rs +++ b/services/tunnelbroker/src/notifs/fcm/token.rs @@ -1,3 +1,4 @@ +use crate::constants::FCM_ACCESS_TOKEN_GENERATION_THRESHOLD; use crate::notifs::fcm::config::FCMConfig; use crate::notifs::fcm::error::Error; use crate::notifs::fcm::error::Error::FCMTokenNotInitialized; @@ -40,6 +41,10 @@ } pub async fn get_auth_bearer(&self) -> Result { + if self.fcm_token_needs_generation().await { + self.generate_fcm_token().await?; + } + let bearer = self.token.read().await; match &*bearer { Some(token) => Ok(format!("{} {}", token.token_type, token.access_token)), @@ -89,4 +94,39 @@ let access_token = response.json::().await?; Ok(access_token) } + + async fn fcm_token_needs_generation(&self) -> bool { + let token = self.token.read().await; + match &*token { + None => true, + Some(token) => { + get_time() - FCM_ACCESS_TOKEN_GENERATION_THRESHOLD + >= token.expiration_time + } + } + } + async fn generate_fcm_token(&self) -> Result<(), Error> { + debug!("Generating FCM access token"); + let mut token = self.token.write().await; + + let created_at = get_time(); + let new_jwt_token = self.get_jwt_token(created_at)?; + let access_token_response = + self.get_fcm_access_token(new_jwt_token).await?; + + *token = Some(FCMAccessToken { + access_token: access_token_response.access_token, + token_type: access_token_response.token_type, + expiration_time: created_at + access_token_response.expires_in, + }); + + Ok(()) + } +} + +fn get_time() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() }