Remove &Context from Peerstate and MimeParser

Passing Context around explicitly removes the need for explicit lifetimes.
This commit is contained in:
link2xt
2021-02-14 01:54:59 +03:00
committed by link2xt
parent 7404e8c85f
commit 57841cdcc0
7 changed files with 91 additions and 109 deletions

View File

@@ -971,7 +971,7 @@ impl Contact {
pub async fn is_verified_ex( pub async fn is_verified_ex(
&self, &self,
context: &Context, context: &Context,
peerstate: Option<&Peerstate<'_>>, peerstate: Option<&Peerstate>,
) -> VerifiedStatus { ) -> VerifiedStatus {
// We're always sort of secured-verified as we could verify the key on this device any time with the key // We're always sort of secured-verified as we could verify the key on this device any time with the key
// on this device // on this device

View File

@@ -113,7 +113,7 @@ impl EncryptHelper {
context: &Context, context: &Context,
min_verified: PeerstateVerifiedStatus, min_verified: PeerstateVerifiedStatus,
mail_to_encrypt: lettre_email::PartBuilder, mail_to_encrypt: lettre_email::PartBuilder,
peerstates: Vec<(Option<Peerstate<'_>>, &str)>, peerstates: Vec<(Option<Peerstate>, &str)>,
) -> Result<String> { ) -> Result<String> {
let mut keyring: Keyring<SignedPublicKey> = Keyring::new(); let mut keyring: Keyring<SignedPublicKey> = Keyring::new();
@@ -166,7 +166,7 @@ pub async fn try_decrypt(
peerstate.apply_header(header, message_time); peerstate.apply_header(header, message_time);
peerstate.save_to_db(&context.sql, false).await?; peerstate.save_to_db(&context.sql, false).await?;
} else { } else {
let p = Peerstate::from_header(context, header, message_time); let p = Peerstate::from_header(header, message_time);
p.save_to_db(&context.sql, true).await?; p.save_to_db(&context.sql, true).await?;
peerstate = Some(p); peerstate = Some(p);
} }
@@ -497,14 +497,10 @@ Sent with my Delta Chat Messenger: https://delta.chat";
Ok(()) Ok(())
} }
fn new_peerstates( fn new_peerstates(prefer_encrypt: EncryptPreference) -> Vec<(Option<Peerstate>, &'static str)> {
ctx: &Context,
prefer_encrypt: EncryptPreference,
) -> Vec<(Option<Peerstate<'_>>, &str)> {
let addr = "bob@foo.bar"; let addr = "bob@foo.bar";
let pub_key = bob_keypair().public; let pub_key = bob_keypair().public;
let peerstate = Peerstate { let peerstate = Peerstate {
context: ctx,
addr: addr.into(), addr: addr.into(),
last_seen: 13, last_seen: 13,
last_seen_autocrypt: 14, last_seen_autocrypt: 14,
@@ -531,17 +527,17 @@ Sent with my Delta Chat Messenger: https://delta.chat";
// test with EncryptPreference::NoPreference: // test with EncryptPreference::NoPreference:
// if e2ee_eguaranteed is unset, there is no encryption as not more than half of peers want encryption // if e2ee_eguaranteed is unset, there is no encryption as not more than half of peers want encryption
let ps = new_peerstates(&t, EncryptPreference::NoPreference); let ps = new_peerstates(EncryptPreference::NoPreference);
assert!(encrypt_helper.should_encrypt(&t, true, &ps).unwrap()); assert!(encrypt_helper.should_encrypt(&t, true, &ps).unwrap());
assert!(!encrypt_helper.should_encrypt(&t, false, &ps).unwrap()); assert!(!encrypt_helper.should_encrypt(&t, false, &ps).unwrap());
// test with EncryptPreference::Reset // test with EncryptPreference::Reset
let ps = new_peerstates(&t, EncryptPreference::Reset); let ps = new_peerstates(EncryptPreference::Reset);
assert!(encrypt_helper.should_encrypt(&t, true, &ps).unwrap()); assert!(encrypt_helper.should_encrypt(&t, true, &ps).unwrap());
assert!(!encrypt_helper.should_encrypt(&t, false, &ps).unwrap()); assert!(!encrypt_helper.should_encrypt(&t, false, &ps).unwrap());
// test with EncryptPreference::Mutual (self is also Mutual) // test with EncryptPreference::Mutual (self is also Mutual)
let ps = new_peerstates(&t, EncryptPreference::Mutual); let ps = new_peerstates(EncryptPreference::Mutual);
assert!(encrypt_helper.should_encrypt(&t, true, &ps).unwrap()); assert!(encrypt_helper.should_encrypt(&t, true, &ps).unwrap());
assert!(encrypt_helper.should_encrypt(&t, false, &ps).unwrap()); assert!(encrypt_helper.should_encrypt(&t, false, &ps).unwrap());

View File

@@ -488,7 +488,7 @@ impl Job {
let msg = job_try!(Message::load_from_db(context, msg_id).await); let msg = job_try!(Message::load_from_db(context, msg_id).await);
let mimefactory = let mimefactory =
job_try!(MimeFactory::from_mdn(context, &msg, additional_rfc724_mids).await); job_try!(MimeFactory::from_mdn(context, &msg, additional_rfc724_mids).await);
let rendered_msg = job_try!(mimefactory.render().await); let rendered_msg = job_try!(mimefactory.render(context).await);
let body = rendered_msg.message; let body = rendered_msg.message;
let addr = contact.get_addr(); let addr = contact.get_addr();
@@ -961,7 +961,7 @@ pub async fn send_msg_job(context: &Context, msg_id: MsgId) -> Result<Option<Job
return Ok(None); return Ok(None);
} }
let rendered_msg = match mimefactory.render().await { let rendered_msg = match mimefactory.render(context).await {
Ok(res) => Ok(res), Ok(res) => Ok(res),
Err(err) => { Err(err) => {
message::set_msg_failed(context, msg_id, Some(err.to_string())).await; message::set_msg_failed(context, msg_id, Some(err.to_string())).await;

View File

@@ -39,7 +39,7 @@ pub enum Loaded {
/// Helper to construct mime messages. /// Helper to construct mime messages.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MimeFactory<'a, 'b> { pub struct MimeFactory<'a> {
from_addr: String, from_addr: String,
from_displayname: String, from_displayname: String,
selfstatus: String, selfstatus: String,
@@ -49,11 +49,10 @@ pub struct MimeFactory<'a, 'b> {
timestamp: i64, timestamp: i64,
loaded: Loaded, loaded: Loaded,
msg: &'b Message, msg: &'a Message,
in_reply_to: String, in_reply_to: String,
references: String, references: String,
req_mdn: bool, req_mdn: bool,
context: &'a Context,
last_added_location_id: u32, last_added_location_id: u32,
attach_selfavatar: bool, attach_selfavatar: bool,
} }
@@ -71,12 +70,12 @@ pub struct RenderedEmail {
pub rfc724_mid: String, pub rfc724_mid: String,
} }
impl<'a, 'b> MimeFactory<'a, 'b> { impl<'a> MimeFactory<'a> {
pub async fn from_msg( pub async fn from_msg(
context: &'a Context, context: &Context,
msg: &'b Message, msg: &'a Message,
attach_selfavatar: bool, attach_selfavatar: bool,
) -> Result<MimeFactory<'a, 'b>, Error> { ) -> Result<MimeFactory<'a>, Error> {
let chat = Chat::load_from_db(context, msg.chat_id).await?; let chat = Chat::load_from_db(context, msg.chat_id).await?;
let from_addr = context let from_addr = context
@@ -156,16 +155,15 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
req_mdn, req_mdn,
last_added_location_id: 0, last_added_location_id: 0,
attach_selfavatar, attach_selfavatar,
context,
}; };
Ok(factory) Ok(factory)
} }
pub async fn from_mdn( pub async fn from_mdn(
context: &'a Context, context: &Context,
msg: &'b Message, msg: &'a Message,
additional_msg_ids: Vec<String>, additional_msg_ids: Vec<String>,
) -> Result<MimeFactory<'a, 'b>, Error> { ) -> Result<MimeFactory<'a>, Error> {
ensure!(!msg.chat_id.is_special(), "Invalid chat id"); ensure!(!msg.chat_id.is_special(), "Invalid chat id");
let contact = Contact::load_from_db(context, msg.from_id).await?; let contact = Contact::load_from_db(context, msg.from_id).await?;
@@ -184,8 +182,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
.unwrap_or(default_str); .unwrap_or(default_str);
let timestamp = dc_create_smeared_timestamp(context).await; let timestamp = dc_create_smeared_timestamp(context).await;
let res = MimeFactory::<'a, 'b> { let res = MimeFactory::<'a> {
context,
from_addr, from_addr,
from_displayname, from_displayname,
selfstatus, selfstatus,
@@ -206,9 +203,11 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
Ok(res) Ok(res)
} }
async fn peerstates_for_recipients(&self) -> Result<Vec<(Option<Peerstate<'_>>, &str)>, Error> { async fn peerstates_for_recipients(
let self_addr = self &self,
.context context: &Context,
) -> Result<Vec<(Option<Peerstate>, &str)>, Error> {
let self_addr = context
.get_config(Config::ConfiguredAddr) .get_config(Config::ConfiguredAddr)
.await .await
.ok_or_else(|| format_err!("Not configured"))?; .ok_or_else(|| format_err!("Not configured"))?;
@@ -219,10 +218,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
.iter() .iter()
.filter(|(_, addr)| addr != &self_addr) .filter(|(_, addr)| addr != &self_addr)
{ {
res.push(( res.push((Peerstate::from_addr(context, addr).await?, addr.as_str()));
Peerstate::from_addr(self.context, addr).await?,
addr.as_str(),
));
} }
Ok(res) Ok(res)
@@ -290,11 +286,11 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
} }
} }
async fn should_do_gossip(&self) -> bool { async fn should_do_gossip(&self, context: &Context) -> bool {
match &self.loaded { match &self.loaded {
Loaded::Message { chat } => { Loaded::Message { chat } => {
// beside key- and member-changes, force re-gossip every 48 hours // beside key- and member-changes, force re-gossip every 48 hours
let gossiped_timestamp = chat.get_gossiped_timestamp(self.context).await; let gossiped_timestamp = chat.get_gossiped_timestamp(context).await;
if time() > gossiped_timestamp + (2 * 24 * 60 * 60) { if time() > gossiped_timestamp + (2 * 24 * 60 * 60) {
return true; return true;
} }
@@ -335,11 +331,11 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
} }
} }
async fn subject_str(&self) -> String { async fn subject_str(&self, context: &Context) -> String {
match self.loaded { match self.loaded {
Loaded::Message { ref chat } => { Loaded::Message { ref chat } => {
if self.msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage { if self.msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage {
stock_str::ac_setup_msg_subject(self.context).await stock_str::ac_setup_msg_subject(context).await
} else if chat.typ == Chattype::Group { } else if chat.typ == Chattype::Group {
let re = if self.in_reply_to.is_empty() { let re = if self.in_reply_to.is_empty() {
"" ""
@@ -371,22 +367,17 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
) )
} }
None => { None => {
let self_name = match self.context.get_config(Config::Displayname).await let self_name = match context.get_config(Config::Displayname).await {
{
Some(name) => name, Some(name) => name,
None => self None => context.get_config(Config::Addr).await.unwrap_or_default(),
.context
.get_config(Config::Addr)
.await
.unwrap_or_default(),
}; };
stock_str::subject_for_new_contact(self.context, self_name).await stock_str::subject_for_new_contact(context, self_name).await
} }
} }
} }
} }
Loaded::MDN { .. } => stock_str::read_rcpt(self.context).await, Loaded::MDN { .. } => stock_str::read_rcpt(context).await,
} }
} }
@@ -397,7 +388,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
.collect() .collect()
} }
pub async fn render(mut self) -> Result<RenderedEmail, Error> { pub async fn render(mut self, context: &Context) -> Result<RenderedEmail, Error> {
// Headers that are encrypted // Headers that are encrypted
// - Chat-*, except Chat-Version // - Chat-*, except Chat-Version
// - Secure-Join* // - Secure-Join*
@@ -468,9 +459,9 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
let grpimage = self.grpimage(); let grpimage = self.grpimage();
let force_plaintext = self.should_force_plaintext(); let force_plaintext = self.should_force_plaintext();
let skip_autocrypt = self.should_skip_autocrypt(); let skip_autocrypt = self.should_skip_autocrypt();
let subject_str = self.subject_str().await; let subject_str = self.subject_str(context).await;
let e2ee_guaranteed = self.is_e2ee_guaranteed(); let e2ee_guaranteed = self.is_e2ee_guaranteed();
let encrypt_helper = EncryptHelper::new(self.context).await?; let encrypt_helper = EncryptHelper::new(context).await?;
let subject = if subject_str let subject = if subject_str
.chars() .chars()
@@ -496,7 +487,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
Loaded::MDN { .. } => dc_create_outgoing_rfc724_mid(None, &self.from_addr), Loaded::MDN { .. } => dc_create_outgoing_rfc724_mid(None, &self.from_addr),
}; };
let ephemeral_timer = self.msg.chat_id.get_ephemeral_timer(self.context).await?; let ephemeral_timer = self.msg.chat_id.get_ephemeral_timer(context).await?;
if let EphemeralTimer::Enabled { duration } = ephemeral_timer { if let EphemeralTimer::Enabled { duration } = ephemeral_timer {
protected_headers.push(Header::new( protected_headers.push(Header::new(
"Ephemeral-Timer".to_string(), "Ephemeral-Timer".to_string(),
@@ -522,15 +513,20 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
let (main_part, parts) = match self.loaded { let (main_part, parts) = match self.loaded {
Loaded::Message { .. } => { Loaded::Message { .. } => {
self.render_message(&mut protected_headers, &mut unprotected_headers, &grpimage) self.render_message(
.await? context,
&mut protected_headers,
&mut unprotected_headers,
&grpimage,
)
.await?
} }
Loaded::MDN { .. } => (self.render_mdn().await?, Vec::new()), Loaded::MDN { .. } => (self.render_mdn(context).await?, Vec::new()),
}; };
let peerstates = self.peerstates_for_recipients().await?; let peerstates = self.peerstates_for_recipients(context).await?;
let should_encrypt = let should_encrypt =
encrypt_helper.should_encrypt(self.context, e2ee_guaranteed, &peerstates)?; encrypt_helper.should_encrypt(context, e2ee_guaranteed, &peerstates)?;
let is_encrypted = should_encrypt && !force_plaintext; let is_encrypted = should_encrypt && !force_plaintext;
let message = if parts.is_empty() { let message = if parts.is_empty() {
@@ -553,7 +549,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
let outer_message = if is_encrypted { let outer_message = if is_encrypted {
// Add gossip headers in chats with multiple recipients // Add gossip headers in chats with multiple recipients
if peerstates.len() > 1 && self.should_do_gossip().await { if peerstates.len() > 1 && self.should_do_gossip(context).await {
for peerstate in peerstates.iter().filter_map(|(state, _)| state.as_ref()) { for peerstate in peerstates.iter().filter_map(|(state, _)| state.as_ref()) {
if peerstate.peek_key(min_verified).is_some() { if peerstate.peek_key(min_verified).is_some() {
if let Some(header) = peerstate.render_gossip_header(min_verified) { if let Some(header) = peerstate.render_gossip_header(min_verified) {
@@ -591,13 +587,13 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
.fold(outer_message, |message, header| message.header(header)); .fold(outer_message, |message, header| message.header(header));
if std::env::var(crate::DCC_MIME_DEBUG).is_ok() { if std::env::var(crate::DCC_MIME_DEBUG).is_ok() {
info!(self.context, "mimefactory: outgoing message mime:"); info!(context, "mimefactory: outgoing message mime:");
let raw_message = message.clone().build().as_string(); let raw_message = message.clone().build().as_string();
println!("{}", raw_message); println!("{}", raw_message);
} }
let encrypted = encrypt_helper let encrypted = encrypt_helper
.encrypt(self.context, min_verified, message, peerstates) .encrypt(context, min_verified, message, peerstates)
.await?; .await?;
outer_message outer_message
@@ -663,9 +659,9 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
Some(part) Some(part)
} }
async fn get_location_kml_part(&mut self) -> Result<PartBuilder, Error> { async fn get_location_kml_part(&mut self, context: &Context) -> Result<PartBuilder, Error> {
let (kml_content, last_added_location_id) = let (kml_content, last_added_location_id) =
location::get_kml(self.context, self.msg.chat_id).await?; location::get_kml(context, self.msg.chat_id).await?;
let part = PartBuilder::new() let part = PartBuilder::new()
.content_type( .content_type(
&"application/vnd.google-earth.kml+xml" &"application/vnd.google-earth.kml+xml"
@@ -687,11 +683,11 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
async fn render_message( async fn render_message(
&mut self, &mut self,
context: &Context,
protected_headers: &mut Vec<Header>, protected_headers: &mut Vec<Header>,
unprotected_headers: &mut Vec<Header>, unprotected_headers: &mut Vec<Header>,
grpimage: &Option<String>, grpimage: &Option<String>,
) -> Result<(PartBuilder, Vec<PartBuilder>), Error> { ) -> Result<(PartBuilder, Vec<PartBuilder>), Error> {
let context = self.context;
let chat = match &self.loaded { let chat = match &self.loaded {
Loaded::Message { chat } => chat, Loaded::Message { chat } => chat,
Loaded::MDN { .. } => bail!("Attempt to render MDN as a message"), Loaded::MDN { .. } => bail!("Attempt to render MDN as a message"),
@@ -796,7 +792,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
unprotected_headers unprotected_headers
.push(Header::new("Autocrypt-Setup-Message".into(), "v1".into())); .push(Header::new("Autocrypt-Setup-Message".into(), "v1".into()));
placeholdertext = Some(stock_str::ac_setup_msg_body(self.context).await); placeholdertext = Some(stock_str::ac_setup_msg_body(context).await);
} }
SystemMessage::SecurejoinMessage => { SystemMessage::SecurejoinMessage => {
let msg = &self.msg; let msg = &self.msg;
@@ -848,7 +844,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
} }
if let Some(grpimage) = grpimage { if let Some(grpimage) = grpimage {
info!(self.context, "setting group image '{}'", grpimage); info!(context, "setting group image '{}'", grpimage);
let mut meta = Message { let mut meta = Message {
viewtype: Viewtype::Image, viewtype: Viewtype::Image,
..Default::default() ..Default::default()
@@ -985,7 +981,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
} }
if location::is_sending_locations_to_chat(context, Some(self.msg.chat_id)).await { if location::is_sending_locations_to_chat(context, Some(self.msg.chat_id)).await {
match self.get_location_kml_part().await { match self.get_location_kml_part(context).await {
Ok(part) => parts.push(part), Ok(part) => parts.push(part),
Err(err) => { Err(err) => {
warn!(context, "mimefactory: could not send location: {}", err); warn!(context, "mimefactory: could not send location: {}", err);
@@ -1010,7 +1006,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
} }
/// Render an MDN /// Render an MDN
async fn render_mdn(&mut self) -> Result<PartBuilder, Error> { async fn render_mdn(&mut self, context: &Context) -> Result<PartBuilder, Error> {
// RFC 6522, this also requires the `report-type` parameter which is equal // RFC 6522, this also requires the `report-type` parameter which is equal
// to the MIME subtype of the second body part of the multipart/report // to the MIME subtype of the second body part of the multipart/report
// //
@@ -1043,11 +1039,11 @@ impl<'a, 'b> MimeFactory<'a, 'b> {
.get_int(Param::GuaranteeE2ee) .get_int(Param::GuaranteeE2ee)
.unwrap_or_default() .unwrap_or_default()
{ {
stock_str::encrypted_msg(self.context).await stock_str::encrypted_msg(context).await
} else { } else {
self.msg.get_summarytext(self.context, 32).await self.msg.get_summarytext(context, 32).await
}; };
let p2 = stock_str::read_rcpt_mail_body(self.context, p1).await; let p2 = stock_str::read_rcpt_mail_body(context, p1).await;
let message_text = format!("{}\r\n", p2); let message_text = format!("{}\r\n", p2);
message = message.child( message = message.child(
PartBuilder::new() PartBuilder::new()
@@ -1500,7 +1496,7 @@ mod tests {
\n", &t).await; \n", &t).await;
let mf = MimeFactory::from_msg(&t, &new_msg, false).await.unwrap(); let mf = MimeFactory::from_msg(&t, &new_msg, false).await.unwrap();
// The subject string should not be "Re: message opened" // The subject string should not be "Re: message opened"
assert_eq!("Re: Hello, Charlie", mf.subject_str().await); assert_eq!("Re: Hello, Charlie", mf.subject_str(&t).await);
} }
async fn first_subject_str(t: TestContext) -> String { async fn first_subject_str(t: TestContext) -> String {
@@ -1519,14 +1515,14 @@ mod tests {
let mf = MimeFactory::from_msg(&t, &new_msg, false).await.unwrap(); let mf = MimeFactory::from_msg(&t, &new_msg, false).await.unwrap();
mf.subject_str().await mf.subject_str(&t).await
} }
async fn msg_to_subject_str(imf_raw: &[u8]) -> String { async fn msg_to_subject_str(imf_raw: &[u8]) -> String {
let t = TestContext::new_alice().await; let t = TestContext::new_alice().await;
let new_msg = incoming_msg_to_reply_msg(imf_raw, &t).await; let new_msg = incoming_msg_to_reply_msg(imf_raw, &t).await;
let mf = MimeFactory::from_msg(&t, &new_msg, false).await.unwrap(); let mf = MimeFactory::from_msg(&t, &new_msg, false).await.unwrap();
mf.subject_str().await mf.subject_str(&t).await
} }
// Creates a `Message` that replies "Hi" to the incoming email in `imf_raw`. // Creates a `Message` that replies "Hi" to the incoming email in `imf_raw`.
@@ -1581,7 +1577,7 @@ mod tests {
let recipients = mimefactory.recipients(); let recipients = mimefactory.recipients();
assert_eq!(recipients, vec!["charlie@example.com"]); assert_eq!(recipients, vec!["charlie@example.com"]);
let rendered_msg = mimefactory.render().await.unwrap(); let rendered_msg = mimefactory.render(context).await.unwrap();
let mail = mailparse::parse_mail(&rendered_msg.message).unwrap(); let mail = mailparse::parse_mail(&rendered_msg.message).unwrap();
assert_eq!( assert_eq!(

View File

@@ -1172,7 +1172,7 @@ async fn update_gossip_peerstates(
peerstate.apply_gossip(header, message_time); peerstate.apply_gossip(header, message_time);
peerstate.save_to_db(&context.sql, false).await?; peerstate.save_to_db(&context.sql, false).await?;
} else { } else {
let p = Peerstate::from_gossip(context, header, message_time); let p = Peerstate::from_gossip(header, message_time);
p.save_to_db(&context.sql, true).await?; p.save_to_db(&context.sql, true).await?;
peerstate = Some(p); peerstate = Some(p);
} }

View File

@@ -30,8 +30,7 @@ pub enum PeerstateVerifiedStatus {
} }
/// Peerstate represents the state of an Autocrypt peer. /// Peerstate represents the state of an Autocrypt peer.
pub struct Peerstate<'a> { pub struct Peerstate {
pub context: &'a Context,
pub addr: String, pub addr: String,
pub last_seen: i64, pub last_seen: i64,
pub last_seen_autocrypt: i64, pub last_seen_autocrypt: i64,
@@ -47,7 +46,7 @@ pub struct Peerstate<'a> {
pub fingerprint_changed: bool, pub fingerprint_changed: bool,
} }
impl<'a> PartialEq for Peerstate<'a> { impl PartialEq for Peerstate {
fn eq(&self, other: &Peerstate) -> bool { fn eq(&self, other: &Peerstate) -> bool {
self.addr == other.addr self.addr == other.addr
&& self.last_seen == other.last_seen && self.last_seen == other.last_seen
@@ -65,9 +64,9 @@ impl<'a> PartialEq for Peerstate<'a> {
} }
} }
impl<'a> Eq for Peerstate<'a> {} impl Eq for Peerstate {}
impl<'a> fmt::Debug for Peerstate<'a> { impl fmt::Debug for Peerstate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Peerstate") f.debug_struct("Peerstate")
.field("addr", &self.addr) .field("addr", &self.addr)
@@ -94,10 +93,9 @@ pub enum ToSave {
All = 0x02, All = 0x02,
} }
impl<'a> Peerstate<'a> { impl Peerstate {
pub fn from_header(context: &'a Context, header: &Aheader, message_time: i64) -> Self { pub fn from_header(header: &Aheader, message_time: i64) -> Self {
Peerstate { Peerstate {
context,
addr: header.addr.clone(), addr: header.addr.clone(),
last_seen: message_time, last_seen: message_time,
last_seen_autocrypt: message_time, last_seen_autocrypt: message_time,
@@ -114,9 +112,8 @@ impl<'a> Peerstate<'a> {
} }
} }
pub fn from_gossip(context: &'a Context, gossip_header: &Aheader, message_time: i64) -> Self { pub fn from_gossip(gossip_header: &Aheader, message_time: i64) -> Self {
Peerstate { Peerstate {
context,
addr: gossip_header.addr.clone(), addr: gossip_header.addr.clone(),
last_seen: 0, last_seen: 0,
last_seen_autocrypt: 0, last_seen_autocrypt: 0,
@@ -141,7 +138,7 @@ impl<'a> Peerstate<'a> {
} }
} }
pub async fn from_addr(context: &'a Context, addr: &str) -> Result<Option<Peerstate<'a>>> { pub async fn from_addr(context: &Context, addr: &str) -> Result<Option<Peerstate>> {
let query = "SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key, \ let query = "SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key, \
gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, \ gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, \
verified_key, verified_key_fingerprint \ verified_key, verified_key_fingerprint \
@@ -151,10 +148,10 @@ impl<'a> Peerstate<'a> {
} }
pub async fn from_fingerprint( pub async fn from_fingerprint(
context: &'a Context, context: &Context,
_sql: &Sql, _sql: &Sql,
fingerprint: &Fingerprint, fingerprint: &Fingerprint,
) -> Result<Option<Peerstate<'a>>> { ) -> Result<Option<Peerstate>> {
let query = "SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key, \ let query = "SELECT addr, last_seen, last_seen_autocrypt, prefer_encrypted, public_key, \
gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, \ gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, \
verified_key, verified_key_fingerprint \ verified_key, verified_key_fingerprint \
@@ -167,10 +164,10 @@ impl<'a> Peerstate<'a> {
} }
async fn from_stmt( async fn from_stmt(
context: &'a Context, context: &Context,
query: &str, query: &str,
params: Vec<&dyn crate::ToSql>, params: Vec<&dyn crate::ToSql>,
) -> Result<Option<Peerstate<'a>>> { ) -> Result<Option<Peerstate>> {
let peerstate = context let peerstate = context
.sql .sql
.query_row_optional(query, params, |row| { .query_row_optional(query, params, |row| {
@@ -181,7 +178,6 @@ impl<'a> Peerstate<'a> {
*/ */
let res = Peerstate { let res = Peerstate {
context,
addr: row.get(0)?, addr: row.get(0)?,
last_seen: row.get(1)?, last_seen: row.get(1)?,
last_seen_autocrypt: row.get(2)?, last_seen_autocrypt: row.get(2)?,
@@ -434,31 +430,31 @@ impl<'a> Peerstate<'a> {
if self.to_save == Some(ToSave::All) || create { if self.to_save == Some(ToSave::All) || create {
sql.execute( sql.execute(
if create { if create {
"INSERT INTO acpeerstates (last_seen, last_seen_autocrypt, prefer_encrypted, \ "INSERT INTO acpeerstates (last_seen, last_seen_autocrypt, prefer_encrypted, \
public_key, gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, \ public_key, gossip_timestamp, gossip_key, public_key_fingerprint, gossip_key_fingerprint, \
verified_key, verified_key_fingerprint, addr \ verified_key, verified_key_fingerprint, addr \
) VALUES(?,?,?,?,?,?,?,?,?,?,?)" ) VALUES(?,?,?,?,?,?,?,?,?,?,?)"
} else { } else {
"UPDATE acpeerstates \ "UPDATE acpeerstates \
SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, \ SET last_seen=?, last_seen_autocrypt=?, prefer_encrypted=?, \
public_key=?, gossip_timestamp=?, gossip_key=?, public_key_fingerprint=?, gossip_key_fingerprint=?, \ public_key=?, gossip_timestamp=?, gossip_key=?, public_key_fingerprint=?, gossip_key_fingerprint=?, \
verified_key=?, verified_key_fingerprint=? \ verified_key=?, verified_key_fingerprint=? \
WHERE addr=?" WHERE addr=?"
}, },
paramsv![ paramsv![
self.last_seen, self.last_seen,
self.last_seen_autocrypt, self.last_seen_autocrypt,
self.prefer_encrypt as i64, self.prefer_encrypt as i64,
self.public_key.as_ref().map(|k| k.to_bytes()), self.public_key.as_ref().map(|k| k.to_bytes()),
self.gossip_timestamp, self.gossip_timestamp,
self.gossip_key.as_ref().map(|k| k.to_bytes()), self.gossip_key.as_ref().map(|k| k.to_bytes()),
self.public_key_fingerprint.as_ref().map(|fp| fp.hex()), self.public_key_fingerprint.as_ref().map(|fp| fp.hex()),
self.gossip_key_fingerprint.as_ref().map(|fp| fp.hex()), self.gossip_key_fingerprint.as_ref().map(|fp| fp.hex()),
self.verified_key.as_ref().map(|k| k.to_bytes()), self.verified_key.as_ref().map(|k| k.to_bytes()),
self.verified_key_fingerprint.as_ref().map(|fp| fp.hex()), self.verified_key_fingerprint.as_ref().map(|fp| fp.hex()),
self.addr, self.addr,
], ],
).await?; ).await?;
} else if self.to_save == Some(ToSave::Timestamps) { } else if self.to_save == Some(ToSave::Timestamps) {
sql.execute( sql.execute(
"UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, gossip_timestamp=? \ "UPDATE acpeerstates SET last_seen=?, last_seen_autocrypt=?, gossip_timestamp=? \
@@ -505,7 +501,6 @@ mod tests {
let pub_key = alice_keypair().public; let pub_key = alice_keypair().public;
let mut peerstate = Peerstate { let mut peerstate = Peerstate {
context: &ctx.ctx,
addr: addr.into(), addr: addr.into(),
last_seen: 10, last_seen: 10,
last_seen_autocrypt: 11, last_seen_autocrypt: 11,
@@ -549,7 +544,6 @@ mod tests {
let pub_key = alice_keypair().public; let pub_key = alice_keypair().public;
let peerstate = Peerstate { let peerstate = Peerstate {
context: &ctx.ctx,
addr: addr.into(), addr: addr.into(),
last_seen: 10, last_seen: 10,
last_seen_autocrypt: 11, last_seen_autocrypt: 11,
@@ -583,7 +577,6 @@ mod tests {
let pub_key = alice_keypair().public; let pub_key = alice_keypair().public;
let mut peerstate = Peerstate { let mut peerstate = Peerstate {
context: &ctx.ctx,
addr: addr.into(), addr: addr.into(),
last_seen: 10, last_seen: 10,
last_seen_autocrypt: 11, last_seen_autocrypt: 11,
@@ -644,13 +637,11 @@ mod tests {
#[async_std::test] #[async_std::test]
async fn test_peerstate_degrade_reordering() { async fn test_peerstate_degrade_reordering() {
let context = crate::test_utils::TestContext::new().await.ctx;
let addr = "example@example.org"; let addr = "example@example.org";
let pub_key = alice_keypair().public; let pub_key = alice_keypair().public;
let header = Aheader::new(addr.to_string(), pub_key, EncryptPreference::Mutual); let header = Aheader::new(addr.to_string(), pub_key, EncryptPreference::Mutual);
let mut peerstate = Peerstate { let mut peerstate = Peerstate {
context: &context,
addr: addr.to_string(), addr: addr.to_string(),
last_seen: 0, last_seen: 0,
last_seen_autocrypt: 0, last_seen_autocrypt: 0,

View File

@@ -1124,7 +1124,6 @@ mod tests {
// Ensure Bob knows Alice_FP // Ensure Bob knows Alice_FP
let alice_pubkey = SignedPublicKey::load_self(&alice.ctx).await.unwrap(); let alice_pubkey = SignedPublicKey::load_self(&alice.ctx).await.unwrap();
let peerstate = Peerstate { let peerstate = Peerstate {
context: &bob.ctx,
addr: "alice@example.com".into(), addr: "alice@example.com".into(),
last_seen: 10, last_seen: 10,
last_seen_autocrypt: 10, last_seen_autocrypt: 10,