From 53abec1222b652d0d0565dba7d5a2c3d1a2060e6 Mon Sep 17 00:00:00 2001 From: Mauro D Date: Mon, 16 May 2022 17:24:27 +0000 Subject: [PATCH] Fixes and use of rustls. --- Cargo.toml | 2 +- src/core/get.rs | 23 ++++++++----- src/core/mod.rs | 4 +++ src/core/set.rs | 27 +++++++++------ src/email/mod.rs | 17 +++++++++- src/email_submission/mod.rs | 14 +++++++- src/event_source/mod.rs | 11 ++++++- src/event_source/parser.rs | 13 ++++++++ src/identity/mod.rs | 14 ++++++++ src/mailbox/mod.rs | 16 +++++++-- src/push_subscription/get.rs | 4 +++ src/push_subscription/helpers.rs | 56 ++++++++++++++++++++++++++++++-- src/push_subscription/mod.rs | 15 ++++++++- src/thread/mod.rs | 8 +++++ src/vacation_response/mod.rs | 14 ++++++++ 15 files changed, 211 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 55470d1..9ede690 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ readme = "README.md" serde = { version = "1.0", features = ["derive"]} serde_json = "1.0" chrono = { version = "0.4", features = ["serde"]} -reqwest = { version = "0.11", features = ["stream"]} +reqwest = { version = "0.11", default-features = false, features = ["stream", "rustls-tls"]} futures-util = "0.3" async-stream = "0.3.3" base64 = "0.13" diff --git a/src/core/get.rs b/src/core/get.rs index 3108ee4..a95934b 100644 --- a/src/core/get.rs +++ b/src/core/get.rs @@ -4,15 +4,16 @@ use serde::{Deserialize, Serialize}; use crate::Method; -use super::{request::ResultReference, RequestParams}; +use super::{request::ResultReference, RequestParams, Type}; #[derive(Debug, Clone, Serialize)] -pub struct GetRequest { +pub struct GetRequest { #[serde(skip)] method: (Method, usize), #[serde(rename = "accountId")] - account_id: String, + #[serde(skip_serializing_if = "Option::is_none")] + account_id: Option, #[serde(skip_serializing_if = "Option::is_none")] ids: Option>, @@ -32,7 +33,7 @@ pub struct GetRequest { #[derive(Debug, Clone, Deserialize)] pub struct GetResponse { #[serde(rename = "accountId")] - account_id: String, + account_id: Option, state: String, @@ -42,10 +43,14 @@ pub struct GetResponse { not_found: Vec, } -impl GetRequest { +impl GetRequest { pub fn new(params: RequestParams) -> Self { GetRequest { - account_id: params.account_id, + account_id: if T::requires_account_id() { + params.account_id.into() + } else { + None + }, method: (params.method, params.call_id), ids: None, ids_ref: None, @@ -55,7 +60,9 @@ impl GetRequest { } pub fn account_id(&mut self, account_id: impl Into) -> &mut Self { - self.account_id = account_id.into(); + if T::requires_account_id() { + self.account_id = Some(account_id.into()); + } self } @@ -95,7 +102,7 @@ impl GetRequest { impl GetResponse { pub fn account_id(&self) -> &str { - &self.account_id + self.account_id.as_ref().unwrap() } pub fn state(&self) -> &str { diff --git a/src/core/mod.rs b/src/core/mod.rs index 02f3860..efb45a1 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -26,3 +26,7 @@ impl RequestParams { } } } + +pub trait Type { + fn requires_account_id() -> bool; +} diff --git a/src/core/set.rs b/src/core/set.rs index b97b843..4deef2a 100644 --- a/src/core/set.rs +++ b/src/core/set.rs @@ -7,12 +7,13 @@ use std::{ use crate::Error; -use super::{request::ResultReference, RequestParams}; +use super::{request::ResultReference, RequestParams, Type}; #[derive(Debug, Clone, Serialize)] -pub struct SetRequest { +pub struct SetRequest { #[serde(rename = "accountId")] - account_id: String, + #[serde(skip_serializing_if = "Option::is_none")] + account_id: Option, #[serde(rename = "ifInState")] #[serde(skip_serializing_if = "Option::is_none")] @@ -39,13 +40,13 @@ pub struct SetRequest { #[derive(Debug, Clone, Deserialize)] pub struct SetResponse { #[serde(rename = "accountId")] - account_id: String, + account_id: Option, #[serde(rename = "oldState")] old_state: Option, #[serde(rename = "newState")] - new_state: String, + new_state: Option, #[serde(rename = "created")] created: Option>, @@ -130,10 +131,14 @@ pub trait Create: Sized { fn create_id(&self) -> Option; } -impl SetRequest { +impl SetRequest { pub fn new(params: RequestParams) -> Self { Self { - account_id: params.account_id, + account_id: if T::requires_account_id() { + params.account_id.into() + } else { + None + }, if_in_state: None, create: None, update: None, @@ -144,7 +149,9 @@ impl SetRequest { } pub fn account_id(&mut self, account_id: impl Into) -> &mut Self { - self.account_id = account_id.into(); + if T::requires_account_id() { + self.account_id = Some(account_id.into()); + } self } @@ -214,7 +221,7 @@ impl SetRequest { impl SetResponse { pub fn account_id(&self) -> &str { - &self.account_id + self.account_id.as_ref().unwrap() } pub fn old_state(&self) -> Option<&str> { @@ -222,7 +229,7 @@ impl SetResponse { } pub fn new_state(&self) -> &str { - &self.new_state + self.new_state.as_ref().unwrap() } pub fn created(&mut self, id: &str) -> crate::Result { diff --git a/src/email/mod.rs b/src/email/mod.rs index 9593fb1..abe6f03 100644 --- a/src/email/mod.rs +++ b/src/email/mod.rs @@ -13,7 +13,10 @@ use std::{ fmt::{self, Display, Formatter}, }; -use crate::{core::request::ResultReference, Get}; +use crate::{ + core::{request::ResultReference, Type}, + Get, Set, +}; #[derive(Debug, Default, Clone, Serialize, Deserialize)] pub struct Email { @@ -813,6 +816,18 @@ impl SubmissionCapabilities { } } +impl Type for Email { + fn requires_account_id() -> bool { + true + } +} + +impl Type for Property { + fn requires_account_id() -> bool { + true + } +} + #[cfg(feature = "debug")] use std::collections::BTreeMap; diff --git a/src/email_submission/mod.rs b/src/email_submission/mod.rs index 7fa90a5..62d94f9 100644 --- a/src/email_submission/mod.rs +++ b/src/email_submission/mod.rs @@ -8,7 +8,7 @@ use std::{collections::HashMap, fmt::Display}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; -use crate::{email::Email, Get}; +use crate::{core::Type, email::Email, Get, Set}; #[derive(Debug, Clone, Serialize, Default)] pub struct SetArguments { @@ -167,3 +167,15 @@ impl Display for Property { } } } + +impl Type for EmailSubmission { + fn requires_account_id() -> bool { + true + } +} + +impl Type for Property { + fn requires_account_id() -> bool { + true + } +} diff --git a/src/event_source/mod.rs b/src/event_source/mod.rs index 1860794..67e2108 100644 --- a/src/event_source/mod.rs +++ b/src/event_source/mod.rs @@ -26,10 +26,15 @@ impl URLParser for URLParameter { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Changes { + id: Option, changes: HashMap>, } impl Changes { + pub fn id(&self) -> Option<&str> { + self.id.as_deref() + } + pub fn account_changes(&mut self, account_id: &str) -> Option> { self.changes.remove(account_id) } @@ -38,7 +43,11 @@ impl Changes { self.changes.keys() } - pub fn into_innter(self) -> HashMap> { + pub fn changes(&self, account_id: &str) -> Option> { + self.changes.get(account_id).map(|changes| changes.iter()) + } + + pub fn into_inner(self) -> HashMap> { self.changes } } diff --git a/src/event_source/parser.rs b/src/event_source/parser.rs index ffcd204..ba5cbcf 100644 --- a/src/event_source/parser.rs +++ b/src/event_source/parser.rs @@ -63,10 +63,16 @@ impl EventParser { Ok(Event { event: EventType::State, data, + id, .. }) => { return match serde_json::from_slice::(&data) { Ok(state_change) => Some(Ok(Changes { + id: if !id.is_empty() { + Some(String::from_utf8(id).unwrap_or_default()) + } else { + None + }, changes: state_change.changed, })), Err(err) => Some(Err(err.into())), @@ -74,12 +80,19 @@ impl EventParser { } Ok(Event { event: EventType::Ping, + #[cfg(feature = "debug")] + id, .. }) => { #[cfg(feature = "debug")] use std::iter::FromIterator; #[cfg(feature = "debug")] return Some(Ok(Changes { + id: if !id.is_empty() { + Some(String::from_utf8(id).unwrap_or_default()) + } else { + None + }, changes: std::collections::HashMap::from_iter([( "ping".to_string(), std::collections::HashMap::new(), diff --git a/src/identity/mod.rs b/src/identity/mod.rs index fa5c4cc..4b65d89 100644 --- a/src/identity/mod.rs +++ b/src/identity/mod.rs @@ -5,6 +5,8 @@ pub mod set; use std::fmt::Display; use crate::core::set::list_not_set; +use crate::core::Type; +use crate::Set; use crate::{email::EmailAddress, Get}; use serde::{Deserialize, Serialize}; @@ -83,3 +85,15 @@ impl Display for Property { } } } + +impl Type for Identity { + fn requires_account_id() -> bool { + true + } +} + +impl Type for Property { + fn requires_account_id() -> bool { + true + } +} diff --git a/src/mailbox/mod.rs b/src/mailbox/mod.rs index f72b593..4f15d25 100644 --- a/src/mailbox/mod.rs +++ b/src/mailbox/mod.rs @@ -5,9 +5,9 @@ pub mod set; use std::fmt::Display; -use crate::core::set::string_not_set; +use crate::core::{set::string_not_set, Type}; use crate::mailbox::set::role_not_set; -use crate::Get; +use crate::{Get, Set}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Default)] @@ -183,3 +183,15 @@ impl ChangesResponse { self.updated_properties.as_deref() } } + +impl Type for Mailbox { + fn requires_account_id() -> bool { + true + } +} + +impl Type for Property { + fn requires_account_id() -> bool { + true + } +} diff --git a/src/push_subscription/get.rs b/src/push_subscription/get.rs index 8ff90c3..e31d759 100644 --- a/src/push_subscription/get.rs +++ b/src/push_subscription/get.rs @@ -7,6 +7,10 @@ impl PushSubscription { self.id.as_ref().unwrap() } + pub fn unwrap_id(self) -> String { + self.id.unwrap() + } + pub fn device_client_id(&self) -> &str { self.device_client_id.as_ref().unwrap() } diff --git a/src/push_subscription/helpers.rs b/src/push_subscription/helpers.rs index 190d57e..2bedbdf 100644 --- a/src/push_subscription/helpers.rs +++ b/src/push_subscription/helpers.rs @@ -1,14 +1,66 @@ use crate::{ + client::Client, core::{ get::GetRequest, request::{Arguments, Request}, response::{PushSubscriptionGetResponse, PushSubscriptionSetResponse}, - set::SetRequest, + set::{Create, SetRequest}, }, Method, Set, }; -use super::PushSubscription; +use super::{Keys, PushSubscription}; + +impl Client { + pub async fn push_subscription_create( + &mut self, + device_client_id: impl Into, + url: impl Into, + keys: Option, + ) -> crate::Result { + let mut request = self.build(); + let create_req = request + .set_push_subscription() + .create() + .device_client_id(device_client_id) + .url(url); + + if let Some(keys) = keys { + create_req.keys(keys); + } + + let id = create_req.create_id().unwrap(); + request + .send_single::() + .await? + .created(&id) + } + + pub async fn push_subscription_verify( + &mut self, + id: &str, + verification_code: impl Into, + ) -> crate::Result> { + let mut request = self.build(); + request + .set_push_subscription() + .update(id) + .verification_code(verification_code); + request + .send_single::() + .await? + .updated(id) + } + + pub async fn push_subscription_destroy(&mut self, id: &str) -> crate::Result<()> { + let mut request = self.build(); + request.set_push_subscription().destroy([id]); + request + .send_single::() + .await? + .destroyed(id) + } +} impl Request<'_> { pub fn get_push_subscription(&mut self) -> &mut GetRequest { diff --git a/src/push_subscription/mod.rs b/src/push_subscription/mod.rs index f7a2380..a8ead03 100644 --- a/src/push_subscription/mod.rs +++ b/src/push_subscription/mod.rs @@ -8,7 +8,8 @@ use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::core::set::list_not_set; -use crate::{Get, TypeState}; +use crate::core::Type; +use crate::{Get, Set, TypeState}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PushSubscription { @@ -84,3 +85,15 @@ pub struct Keys { p256dh: String, auth: String, } + +impl Type for PushSubscription { + fn requires_account_id() -> bool { + false + } +} + +impl Type for Property { + fn requires_account_id() -> bool { + false + } +} diff --git a/src/thread/mod.rs b/src/thread/mod.rs index 5a76957..d4620c5 100644 --- a/src/thread/mod.rs +++ b/src/thread/mod.rs @@ -5,6 +5,8 @@ use std::fmt::Display; use serde::{Deserialize, Serialize}; +use crate::core::Type; + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Thread { id: String, @@ -20,6 +22,12 @@ pub enum Property { EmailIds, } +impl Type for Property { + fn requires_account_id() -> bool { + true + } +} + impl Display for Property { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/src/vacation_response/mod.rs b/src/vacation_response/mod.rs index 7e14707..3fe2210 100644 --- a/src/vacation_response/mod.rs +++ b/src/vacation_response/mod.rs @@ -6,7 +6,9 @@ use std::fmt::Display; use crate::core::set::date_not_set; use crate::core::set::string_not_set; +use crate::core::Type; use crate::Get; +use crate::Set; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; @@ -78,3 +80,15 @@ impl Display for Property { } } } + +impl Type for VacationResponse { + fn requires_account_id() -> bool { + true + } +} + +impl Type for Property { + fn requires_account_id() -> bool { + true + } +}