fix more tests

This commit is contained in:
dignifiedquire
2020-03-22 21:57:26 +01:00
parent 20ef115eb2
commit b616a2b3e7
7 changed files with 126 additions and 73 deletions

View File

@@ -4,6 +4,7 @@ mod auto_mozilla;
mod auto_outlook;
mod read_url;
use async_std::prelude::*;
use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
use crate::config::Config;
@@ -13,11 +14,11 @@ use crate::dc_tools::*;
use crate::error::{Error, Result};
use crate::imap::Imap;
use crate::login_param::{CertificateChecks, LoginParam};
use crate::message::Message;
use crate::oauth2::*;
use crate::smtp::Smtp;
use crate::{chat, e2ee, provider};
use crate::message::Message;
use auto_mozilla::moz_autoconfigure;
use auto_outlook::outlk_autodiscover;
@@ -39,10 +40,8 @@ impl Context {
/// Configures this account with the currently set parameters.
pub async fn configure(&self) -> Result<()> {
ensure!(
!self.has_ongoing().await,
"There is already another ongoing process running."
);
use futures::future::FutureExt;
ensure!(
!self.scheduler.read().await.is_running(),
"Can not configure, already running"
@@ -51,11 +50,22 @@ impl Context {
self.sql.is_open().await,
"Cannot configure, database not opened."
);
ensure!(
self.alloc_ongoing().await,
"Cannot allocate ongoing process"
);
let cancel_channel = self.alloc_ongoing().await?;
let res = self
.inner_configure()
.race(cancel_channel.recv().map(|_| {
progress!(self, 0);
Ok(())
}))
.await;
self.free_ongoing().await;
res
}
async fn inner_configure(&self) -> Result<()> {
let mut success = false;
let mut param_autoconfig: Option<LoginParam> = None;
@@ -127,15 +137,12 @@ impl Context {
// and restore to last-entered on failure.
// this way, the parameters visible to the ui are always in-sync with the current configuration.
if success {
assert!(self.is_configured().await, "epic fail");
LoginParam::from_database(self, "")
.await
.save_to_database(self, "configured_raw_")
.await
.ok();
self.free_ongoing().await;
progress!(self, 1000);
Ok(())
} else {
@@ -145,8 +152,6 @@ impl Context {
.await
.ok();
self.free_ongoing().await;
progress!(self, 0);
Err(Error::Message("Configure failed".to_string()))
}
@@ -398,8 +403,8 @@ async fn exec_step(
progress!(ctx, 600);
/* try to connect to IMAP - if we did not got an autoconfig,
do some further tries with different settings and username variations */
try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?;
*is_imap_connected = true;
*is_imap_connected =
try_imap_connections(ctx, param, param_autoconfig.is_some(), imap).await?;
}
15 => {
progress!(ctx, 800);
@@ -512,13 +517,10 @@ async fn try_imap_connections(
mut param: &mut LoginParam,
was_autoconfig: bool,
imap: &mut Imap,
) -> Result<()> {
) -> Result<bool> {
// progress 650 and 660
if try_imap_connection(context, &mut param, was_autoconfig, 0, imap)
.await
.is_ok()
{
return Ok(());
if let Ok(val) = try_imap_connection(context, &mut param, was_autoconfig, 0, imap).await {
return Ok(val);
}
progress!(context, 670);
param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS);
@@ -532,9 +534,7 @@ async fn try_imap_connections(
param.send_user = param.send_user.split_at(at).0.to_string();
}
// progress 680 and 690
try_imap_connection(context, &mut param, was_autoconfig, 1, imap).await?;
Ok(())
try_imap_connection(context, &mut param, was_autoconfig, 1, imap).await
}
async fn try_imap_connection(
@@ -543,24 +543,26 @@ async fn try_imap_connection(
was_autoconfig: bool,
variation: usize,
imap: &mut Imap,
) -> Result<()> {
) -> Result<bool> {
if try_imap_one_param(context, &param, imap).await.is_ok() {
return Ok(());
return Ok(true);
}
if was_autoconfig {
bail!("autoconfig");
return Ok(false);
}
progress!(context, 650 + variation * 30);
param.server_flags &= !(DC_LP_IMAP_SOCKET_FLAGS);
param.server_flags |= DC_LP_IMAP_SOCKET_STARTTLS;
if try_imap_one_param(context, &param, imap).await.is_ok() {
return Ok(());
return Ok(true);
}
progress!(context, 660 + variation * 30);
param.mail_port = 143;
try_imap_one_param(context, &param, imap).await
try_imap_one_param(context, &param, imap).await?;
Ok(true)
}
async fn try_imap_one_param(context: &Context, param: &LoginParam, imap: &mut Imap) -> Result<()> {
@@ -579,6 +581,10 @@ async fn try_imap_one_param(context: &Context, param: &LoginParam, imap: &mut Im
return Ok(());
}
if context.shall_stop_ongoing().await {
bail!("Interrupted");
}
bail!("Could not connect: {}", inf);
}
@@ -593,7 +599,7 @@ async fn try_smtp_connections(
return Ok(());
}
if was_autoconfig {
bail!("autoconfig");
return Ok(());
}
progress!(context, 850);
param.server_flags &= !(DC_LP_SMTP_SOCKET_FLAGS as i32);

View File

@@ -5,7 +5,7 @@ use std::ffi::OsString;
use std::ops::Deref;
use async_std::path::{Path, PathBuf};
use async_std::sync::{Arc, Mutex, RwLock};
use async_std::sync::{channel, Arc, Mutex, Receiver, RwLock, Sender};
use crossbeam_queue::SegQueue;
use crate::chat::*;
@@ -55,10 +55,11 @@ pub struct InnerContext {
pub(crate) scheduler: RwLock<Scheduler>,
}
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug)]
pub struct RunningState {
pub ongoing_running: bool,
shall_stop_ongoing: bool,
cancel_sender: Option<Sender<()>>,
}
/// Return some info about deltachat-core
@@ -180,20 +181,20 @@ impl Context {
* Ongoing process allocation/free/check
******************************************************************************/
pub async fn alloc_ongoing(&self) -> bool {
pub async fn alloc_ongoing(&self) -> Result<Receiver<()>> {
if self.has_ongoing().await {
warn!(self, "There is already another ongoing process running.",);
false
} else {
let s_a = &self.running_state;
let mut s = s_a.write().await;
s.ongoing_running = true;
s.shall_stop_ongoing = false;
true
bail!("There is already another ongoing process running.");
}
let s_a = &self.running_state;
let mut s = s_a.write().await;
s.ongoing_running = true;
s.shall_stop_ongoing = false;
let (sender, receiver) = channel(1);
s.cancel_sender = Some(sender);
Ok(receiver)
}
pub async fn free_ongoing(&self) {
@@ -202,6 +203,7 @@ impl Context {
s.ongoing_running = false;
s.shall_stop_ongoing = true;
s.cancel_sender.take();
}
pub async fn has_ongoing(&self) -> bool {
@@ -215,6 +217,9 @@ impl Context {
pub async fn stop_ongoing(&self) {
let s_a = &self.running_state;
let mut s = s_a.write().await;
if let Some(cancel) = s.cancel_sender.take() {
cancel.send(()).await;
}
if s.ongoing_running && !s.shall_stop_ongoing {
info!(self, "Signaling the ongoing process to stop ASAP.",);
@@ -503,6 +508,7 @@ impl Default for RunningState {
RunningState {
ongoing_running: false,
shall_stop_ongoing: true,
cancel_sender: None,
}
}
}

View File

@@ -70,9 +70,16 @@ pub async fn imex(
what: ImexMode,
param1: Option<impl AsRef<Path>>,
) -> Result<()> {
job_imex_imap(context, what, param1).await?;
use futures::future::FutureExt;
Ok(())
let cancel = context.alloc_ongoing().await?;
let res = imex_inner(context, what, param1)
.race(cancel.recv().map(|_| Err(format_err!("canceled"))))
.await;
context.free_ongoing().await;
res
}
/// Returns the filename of the backup found (otherwise an error)
@@ -110,8 +117,13 @@ pub async fn has_backup(context: &Context, dir_name: impl AsRef<Path>) -> Result
}
pub async fn initiate_key_transfer(context: &Context) -> Result<String> {
ensure!(context.alloc_ongoing().await, "could not allocate ongoing");
let res = do_initiate_key_transfer(context).await;
use futures::future::FutureExt;
let cancel = context.alloc_ongoing().await?;
let res = do_initiate_key_transfer(context)
.race(cancel.recv().map(|_| Err(format_err!("canceled"))))
.await;
context.free_ongoing().await;
res
}
@@ -120,10 +132,8 @@ async fn do_initiate_key_transfer(context: &Context) -> Result<String> {
let mut msg: Message;
let setup_code = create_setup_code(context);
/* this may require a keypair to be created. this may take a second ... */
ensure!(!context.shall_stop_ongoing().await, "canceled");
let setup_file_content = render_setup_file(context, &setup_code).await?;
/* encrypting may also take a while ... */
ensure!(!context.shall_stop_ongoing().await, "canceled");
let setup_file_blob = BlobObject::create(
context,
"autocrypt-setup-message.html",
@@ -144,7 +154,6 @@ async fn do_initiate_key_transfer(context: &Context) -> Result<String> {
ForcePlaintext::NoAutocryptHeader as i32,
);
ensure!(!context.shall_stop_ongoing().await, "canceled");
let msg_id = chat::send_msg(context, chat_id, &mut msg).await?;
info!(context, "Wait for setup message being sent ...",);
while !context.shall_stop_ongoing().await {
@@ -363,13 +372,12 @@ pub fn normalize_setup_code(s: &str) -> String {
out
}
pub async fn job_imex_imap(
async fn imex_inner(
context: &Context,
what: ImexMode,
param: Option<impl AsRef<Path>>,
) -> Result<()> {
ensure!(context.alloc_ongoing().await, "could not allocate ongoing");
ensure!(!param.is_some(), "No Import/export dir/file given.");
ensure!(param.is_some(), "No Import/export dir/file given.");
info!(context, "Import/export process started.");
context.call_cb(Event::ImexProgress(10));
@@ -380,7 +388,6 @@ pub async fn job_imex_imap(
if what == ImexMode::ExportBackup || what == ImexMode::ExportSelfKeys {
// before we export anything, make sure the private key exists
if e2ee::ensure_secret_key_exists(context).await.is_err() {
context.free_ongoing().await;
bail!("Cannot create private key or private key not available.");
} else {
dc_create_folder(context, &path).await?;
@@ -393,7 +400,7 @@ pub async fn job_imex_imap(
ImexMode::ExportBackup => export_backup(context, path).await,
ImexMode::ImportBackup => import_backup(context, path).await,
};
context.free_ongoing().await;
match success {
Ok(()) => {
info!(context, "IMEX successfully completed");

View File

@@ -1,5 +1,6 @@
//! Verified contact protocol implementation as [specified by countermitm project](https://countermitm.readthedocs.io/en/stable/new.html#setup-contact-protocol)
use async_std::prelude::*;
use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC};
use crate::aheader::EncryptPreference;
@@ -181,6 +182,21 @@ async fn cleanup(
/// Take a scanned QR-code and do the setup-contact/join-group handshake.
/// See the ffi-documentation for more details.
pub async fn dc_join_securejoin(context: &Context, qr: &str) -> ChatId {
use futures::future::FutureExt;
let cancel = match context.alloc_ongoing().await {
Ok(cancel) => cancel,
Err(_) => {
return cleanup(&context, ChatId::new(0), false, false).await;
}
};
securejoin(context, qr)
.race(cancel.recv().map(|_| ChatId::new(0)))
.await
}
async fn securejoin(context: &Context, qr: &str) -> ChatId {
/*========================================================
==== Bob - the joiner's side =====
==== Step 2 in "Setup verified contact" protocol =====
@@ -191,9 +207,6 @@ pub async fn dc_join_securejoin(context: &Context, qr: &str) -> ChatId {
info!(context, "Requesting secure-join ...",);
ensure_secret_key_exists(context).await.ok();
if !context.alloc_ongoing().await {
return cleanup(&context, contact_chat_id, false, join_vg).await;
}
let qr_scan = check_qr(context, &qr).await;
if qr_scan.state != LotState::QrAskVerifyContact && qr_scan.state != LotState::QrAskVerifyGroup
{