Skip to content

Commit

Permalink
fix: ensure all data provided (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
HarryET committed Jul 20, 2023
1 parent d8a1352 commit 6dc5949
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 38 deletions.
8 changes: 7 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@ FCM_API_KEY=
# APNS
APNS_CERTIFICATE= # base64 encoded .p12 APNS Certificate
APNS_CERTIFICATE_PASSWORD= # Password for provided certificate
APNS_TOPIC= # bundle ID/app ID
APNS_TOPIC= # bundle ID/app ID

# Analytics
ANALYTICS_S3_ENDPOINT=
ANALYTICS_EXPORT_BUCKET=
ANALYTICS_GEOIP_DB_BUCKET=
ANALYTICS_GEOIP_DB_KEY=
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

110 changes: 75 additions & 35 deletions src/handlers/push_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use {
analytics::message_info::MessageInfo,
blob::ENCRYPTED_FLAG,
error::{
Error,
Error::{ClientNotFound, Store},
Result,
},
handlers::DECENTRALIZED_IDENTIFIER_PREFIX,
increment_counter,
Expand Down Expand Up @@ -51,7 +51,7 @@ pub async fn handler(
StateExtractor(state): StateExtractor<Arc<AppState>>,
headers: HeaderMap,
RequireValidSignature(Json(body)): RequireValidSignature<Json<PushMessageBody>>,
) -> Result<axum::response::Response> {
) -> Result<axum::response::Response, Error> {
let res = handler_internal(
Path((tenant_id.clone(), id.clone())),
StateExtractor(state.clone()),
Expand All @@ -64,31 +64,27 @@ pub async fn handler(

let (status, response, analytics_option) = match res {

Check warning on line 65 in src/handlers/push_message.rs

View workflow job for this annotation

GitHub Actions / [ubuntu-latest/rust-stable] Clippy

unused variable: `status`

Check warning on line 65 in src/handlers/push_message.rs

View workflow job for this annotation

GitHub Actions / [ubuntu-latest/rust-stable] Clippy

unused variable: `analytics_option`
Ok((res, analytics_options_inner)) => (res.status().as_u16(), res, analytics_options_inner),
Err(error) => {
Err((error, analytics_option_inner)) => {
#[cfg(feature = "analytics")]
let error_str = format!("{:?}", &error);
let res = error.into_response();
let status_code = res.status().clone().as_u16();

#[cfg(feature = "analytics")]
let analytics_option = Some(MessageInfo {
msg_id: body.clone().id.into(),
region: None,
country: None,
continent: None,
project_id: tenant_id.clone().into(),
client_id: id.clone().into(),
topic: None,
push_provider: "unknown".into(),
encrypted: false,
flags: body.clone().payload.flags,
status: status_code,
response_message: Some(error_str.into()),
received_at: Default::default(),
});
let mut analytics_option = None;
if let Some(analytics_unwrapped) = analytics_option_inner {
#[cfg(feature = "analytics")]
{
analytics_option = Some(MessageInfo {
response_message: Some(error_str.into()),
..analytics_unwrapped
});
}

#[cfg(not(feature = "analytics"))]
let analytics_option = None;
#[cfg(not(feature = "analytics"))]
{
analytics_option = Some(analytics_unwrapped);
}
}

(status_code, res, analytics_option)
}
Expand Down Expand Up @@ -133,7 +129,7 @@ pub async fn handler_internal(
StateExtractor(state): StateExtractor<Arc<AppState>>,
headers: HeaderMap,
RequireValidSignature(Json(body)): RequireValidSignature<Json<PushMessageBody>>,
) -> Result<(axum::response::Response, Option<MessageInfo>)> {
) -> Result<(axum::response::Response, Option<MessageInfo>), (Error, Option<MessageInfo>)> {
#[cfg(feature = "analytics")]
let topic: Option<Arc<str>> = body
.payload
Expand All @@ -149,10 +145,33 @@ pub async fn handler_internal(
Ok(c) => Ok(c),
Err(StoreError::NotFound(_, _)) => Err(ClientNotFound),
Err(e) => Err(Store(e)),
}?;
}
.map_err(|e| {
(
e,
#[cfg(feature = "analytics")]
Some(MessageInfo {
msg_id: body.id.clone().into(),
region: None,
country: None,
continent: None,
project_id: tenant_id.clone().into(),
client_id: id.clone().into(),
topic: topic.clone(),
push_provider: "unknown".into(),
encrypted,
flags,
status: 0,
response_message: None,
received_at: gorgon::time::now(),
}),
#[cfg(not(feature = "analytics"))]
None,
)
})?;

#[cfg(feature = "analytics")]
let mut analytics = MessageInfo {
let mut analytics = Some(MessageInfo {
msg_id: body.id.clone().into(),
region: None,
country: None,
Expand All @@ -166,7 +185,10 @@ pub async fn handler_internal(
status: 0,
response_message: None,
received_at: gorgon::time::now(),
};
});

#[cfg(not(feature = "analytics"))]
let analytics = None;

let request_id = get_req_id(&headers);

Expand Down Expand Up @@ -199,20 +221,25 @@ pub async fn handler_internal(

#[cfg(feature = "analytics")]
{
analytics.response_message = Some("Notification has already been received".into());
analytics = Some(MessageInfo {
response_message: Some("Notification has already been received".into()),
..analytics.unwrap()
});
}

#[cfg(not(feature = "analytics"))]
return Ok(((StatusCode::OK).into_response(), None));

#[cfg(feature = "analytics")]
return Ok(((StatusCode::OK).into_response(), Some(analytics)));
return Ok(((StatusCode::OK).into_response(), analytics));
}

let notification = state
.notification_store
.create_or_update_notification(&body.id, &tenant_id, &id, &body.payload)
.await?;
.await
.map_err(|e| (Error::Store(e), analytics.clone()))?;

info!(
%request_id,
%tenant_id,
Expand All @@ -235,17 +262,24 @@ pub async fn handler_internal(

#[cfg(feature = "analytics")]
{
analytics.response_message = Some("Notification has already been processed".into());
analytics = Some(MessageInfo {
response_message: Some("Notification has already been processed".into()),
..analytics.unwrap()
});
}

#[cfg(not(feature = "analytics"))]
return Ok(((StatusCode::OK).into_response(), None));

#[cfg(feature = "analytics")]
return Ok(((StatusCode::OK).into_response(), Some(analytics)));
return Ok(((StatusCode::OK).into_response(), analytics));
}

let tenant = state.tenant_store.get_tenant(&tenant_id).await?;
let tenant = state
.tenant_store
.get_tenant(&tenant_id)
.await
.map_err(|e| (e, analytics.clone()))?;
debug!(
%request_id,
%tenant_id,
Expand All @@ -254,7 +288,9 @@ pub async fn handler_internal(
"fetched tenant"
);

let mut provider = tenant.provider(&client.push_type)?;
let mut provider = tenant
.provider(&client.push_type)
.map_err(|e| (e, analytics.clone()))?;
debug!(
%request_id,
%tenant_id,
Expand All @@ -266,7 +302,8 @@ pub async fn handler_internal(

provider
.send_notification(client.token, body.payload)
.await?;
.await
.map_err(|e| (e, analytics.clone()))?;

info!(
%request_id,
Expand All @@ -287,11 +324,14 @@ pub async fn handler_internal(

#[cfg(feature = "analytics")]
{
analytics.response_message = Some("Delivered".into());
analytics = Some(MessageInfo {
response_message: Some("Delivered".into()),
..analytics.unwrap()
});
}

#[cfg(feature = "analytics")]
return Ok(((StatusCode::ACCEPTED).into_response(), Some(analytics)));
return Ok(((StatusCode::ACCEPTED).into_response(), analytics));

#[cfg(not(feature = "analytics"))]
Ok(((StatusCode::ACCEPTED).into_response(), None))
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/single_tenant_wrappers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub async fn delete_handler(
#[cfg(feature = "multitenant")]
return Err(MissingTenantId);

#[cfg(all(not(feature = "multitenant")))]
#[cfg(not(feature = "multitenant"))]
crate::handlers::delete_client::handler(
Path((DEFAULT_TENANT_ID.to_string(), id)),
state,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub mod analytics;
#[cfg(not(feature = "analytics"))]
pub mod analytics {
pub mod message_info {
#[derive(Debug, Clone, serde::Serialize)]
pub struct MessageInfo;
}
}
Expand Down

0 comments on commit 6dc5949

Please sign in to comment.