Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: switch to latest release a2 library #362

Merged
merged 9 commits into from May 26, 2023
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.

2 changes: 1 addition & 1 deletion autoendpoint/Cargo.toml
Expand Up @@ -45,7 +45,7 @@ tokio.workspace = true
url.workspace = true
uuid.workspace = true

a2 = {version = "0.8", git = "https://github.com/mozilla-services/a2"}
a2 = {version = "0.8", git = "https://github.com/mozilla-services/a2", branch="master"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking more of a specific sha (thinking of reproducable builds) but then again we weren't doing this before by pointing to the autoendpoint branch, so never mind I guess.

bytebuffer = "2.1"
again = { version = "0.1.2", default-features = false, features = ["log", "rand"] }
async-trait = "0.1"
Expand Down
241 changes: 130 additions & 111 deletions autoendpoint/src/routers/apns/router.rs
Expand Up @@ -244,6 +244,127 @@ impl ApnsRouter {
pub fn active(&self) -> bool {
!self.clients.is_empty()
}

/// Derive an APS message from the replacement JSON block.
///
/// This requires an external "holder" that contains the data that APS will refer to.
/// The holder should live in the same context as the `aps.build()` method.
fn derive_aps<'a>(
&self,
replacement: Value,
holder: &'a mut ApsAlertHolder,
) -> Result<DefaultNotificationBuilder<'a>, ApnsError> {
let mut aps = Self::default_aps();
// a2 does not have a way to bulk replace these values, so do them by hand.
// these could probably be turned into a macro, but hopefully, this is
// more one off and I didn't want to fight with the macro generator.
// This whole thing was included as a byproduct of
// https://bugzilla.mozilla.org/show_bug.cgi?id=1364403 which was put
// in place to help debug the iOS build. It was supposed to be temporary,
// but apparently bit-lock set in and now no one is super sure if it's
// still needed or used. (I want to get rid of this.)
if let Some(v) = replacement.get("title") {
if let Some(v) = v.as_str() {
holder.title = v.to_owned();
aps = aps.set_title(&holder.title);
} else {
return Err(ApnsError::InvalidApsData);
}
}
if let Some(v) = replacement.get("subtitle") {
if let Some(v) = v.as_str() {
holder.subtitle = v.to_owned();
aps = aps.set_subtitle(&holder.subtitle);
} else {
return Err(ApnsError::InvalidApsData);
}
}
if let Some(v) = replacement.get("body") {
if let Some(v) = v.as_str() {
holder.body = v.to_owned();
aps = aps.set_body(&holder.body);
} else {
return Err(ApnsError::InvalidApsData);
}
}
if let Some(v) = replacement.get("title_loc_key") {
if let Some(v) = v.as_str() {
holder.title_loc_key = v.to_owned();
aps = aps.set_title_loc_key(&holder.title_loc_key);
} else {
return Err(ApnsError::InvalidApsData);
}
}
if let Some(v) = replacement.get("title_loc_args") {
if let Some(v) = v.as_array() {
let mut args: Vec<String> = Vec::new();
for val in v {
if let Some(value) = val.as_str() {
args.push(value.to_owned())
} else {
return Err(ApnsError::InvalidApsData);
}
}
holder.title_loc_args = args;
aps = aps.set_title_loc_args(&holder.title_loc_args);
} else {
return Err(ApnsError::InvalidApsData);
}
}
if let Some(v) = replacement.get("action_loc_key") {
if let Some(v) = v.as_str() {
holder.action_loc_key = v.to_owned();
aps = aps.set_action_loc_key(&holder.action_loc_key);
} else {
return Err(ApnsError::InvalidApsData);
}
}
if let Some(v) = replacement.get("loc_key") {
if let Some(v) = v.as_str() {
holder.loc_key = v.to_owned();
aps = aps.set_loc_key(&holder.loc_key);
} else {
return Err(ApnsError::InvalidApsData);
}
}
if let Some(v) = replacement.get("loc_args") {
if let Some(v) = v.as_array() {
let mut args: Vec<String> = Vec::new();
for val in v {
if let Some(value) = val.as_str() {
args.push(value.to_owned())
} else {
return Err(ApnsError::InvalidApsData);
}
}
holder.loc_args = args;
aps = aps.set_loc_args(&holder.loc_args);
} else {
return Err(ApnsError::InvalidApsData);
}
}
if let Some(v) = replacement.get("launch_image") {
if let Some(v) = v.as_str() {
holder.launch_image = v.to_owned();
aps = aps.set_launch_image(&holder.launch_image);
} else {
return Err(ApnsError::InvalidApsData);
}
}
// Honestly, we should just check to see if this is present
// we don't really care what the value is since we'll never
// use
if let Some(v) = replacement.get("mutable-content") {
if let Some(v) = v.as_i64() {
if v != 0 {
aps = aps.set_mutable_content();
}
} else {
return Err(ApnsError::InvalidApsData);
}
}
Ok(aps)
}
}

#[async_trait(?Send)]
Expand Down Expand Up @@ -317,119 +438,17 @@ impl Router for ApnsRouter {
.clients
.get(channel)
.ok_or(ApnsError::InvalidReleaseChannel)?;
let mut aps = Self::default_aps();

// A simple bucket variable so that I don't have to deal with fun lifetime issues.
// A simple bucket variable so that I don't have to deal with fun lifetime issues if we need
// to derive.
let mut holder = ApsAlertHolder::default();
if let Some(replacement) = aps_json {
// a2 does not have a way to bulk replace these values, so do them by hand.
// these could probably be turned into a macro, but hopefully, this is
// more one off and I didn't want to fight with the macro generator.
// This whole thing was included as a byproduct of
// https://bugzilla.mozilla.org/show_bug.cgi?id=1364403 which was put
// in place to help debug the iOS build. It was supposed to be temporary,
// but apparently bit-lock set in and now no one is super sure if it's
// still needed or used. (I want to get rid of this.)
if let Some(v) = replacement.get("title") {
if let Some(v) = v.as_str() {
holder.title = v.to_owned();
aps = aps.set_title(&holder.title);
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
if let Some(v) = replacement.get("subtitle") {
if let Some(v) = v.as_str() {
holder.subtitle = v.to_owned();
aps = aps.set_subtitle(&holder.subtitle);
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
if let Some(v) = replacement.get("body") {
if let Some(v) = v.as_str() {
holder.body = v.to_owned();
aps = aps.set_body(&holder.body);
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
if let Some(v) = replacement.get("title_loc_key") {
if let Some(v) = v.as_str() {
holder.title_loc_key = v.to_owned();
aps = aps.set_title_loc_key(&holder.title_loc_key);
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
if let Some(v) = replacement.get("title_loc_args") {
if let Some(v) = v.as_array() {
let mut args: Vec<String> = Vec::new();
for val in v {
if let Some(value) = val.as_str() {
args.push(value.to_owned())
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
holder.title_loc_args = args;
aps = aps.set_title_loc_args(&holder.title_loc_args);
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
if let Some(v) = replacement.get("action_loc_key") {
if let Some(v) = v.as_str() {
holder.action_loc_key = v.to_owned();
aps = aps.set_action_loc_key(&holder.action_loc_key);
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
if let Some(v) = replacement.get("loc_key") {
if let Some(v) = v.as_str() {
holder.loc_key = v.to_owned();
aps = aps.set_loc_key(&holder.loc_key);
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
if let Some(v) = replacement.get("loc_args") {
if let Some(v) = v.as_array() {
let mut args: Vec<String> = Vec::new();
for val in v {
if let Some(value) = val.as_str() {
args.push(value.to_owned())
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
holder.loc_args = args;
aps = aps.set_loc_args(&holder.loc_args);
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
if let Some(v) = replacement.get("launch_image") {
if let Some(v) = v.as_str() {
holder.launch_image = v.to_owned();
aps = aps.set_launch_image(&holder.launch_image);
} else {
return Err(ApnsError::InvalidApsData.into());
}
}
// Honestly, we should just check to see if this is present
// we don't really care what the value is since we'll never
// use
if let Some(v) = replacement.get("mutable-content") {
if let Some(v) = v.as_i64() {
if v != 0 {
aps = aps.set_mutable_content();
}
} else {
return Err(ApnsError::InvalidApsData.into());
}
}

// If we are provided a replacement APS block, derive an APS message from it, otherwise
// start with a blank APS message.
let aps = if let Some(replacement) = aps_json {
self.derive_aps(replacement, &mut holder)?
} else {
Self::default_aps()
};

// Finalize the APS object.
Expand Down