first pass at resolving CR

This commit is contained in:
dignifiedquire
2020-05-19 17:26:22 +02:00
parent ba4df23bff
commit 133ff4914d
7 changed files with 18 additions and 104 deletions

View File

@@ -635,44 +635,6 @@ impl Chat {
&self.name
}
fn parent_query(fields: &str) -> String {
// Check for server_uid guarantees that we don't
// select a draft or undelivered message.
format!(
"SELECT {} \
FROM msgs WHERE chat_id=?1 AND server_uid!=0 \
ORDER BY timestamp DESC, id DESC \
LIMIT 1;",
fields
)
}
async fn get_parent_mime_headers(&self, context: &Context) -> Option<(String, String, String)> {
let collect = |row: &rusqlite::Row| Ok((row.get(0)?, row.get(1)?, row.get(2)?));
let params = paramsv![self.id];
let sql = &context.sql;
let query = Self::parent_query("rfc724_mid, mime_in_reply_to, mime_references");
sql.query_row(&query, params, collect).await.ok()
}
async fn parent_is_encrypted(&self, context: &Context) -> Result<bool, Error> {
let sql = &context.sql;
let params = paramsv![self.id];
let query = Self::parent_query("param");
let packed: Option<String> = sql.query_get_value_result(&query, params).await?;
if let Some(ref packed) = packed {
let param = packed.parse::<Params>()?;
Ok(param.exists(Param::GuaranteeE2ee))
} else {
// No messages
Ok(false)
}
}
pub async fn get_profile_image(&self, context: &Context) -> Option<PathBuf> {
if let Some(image_rel) = self.param.get(Param::ProfileImage) {
if !image_rel.is_empty() {

View File

@@ -44,11 +44,11 @@ impl Context {
ensure!(
!self.scheduler.read().await.is_running(),
"Can not configure, already running"
"cannot configure, already running"
);
ensure!(
self.sql.is_open().await,
"Cannot configure, database not opened."
"cannot configure, database not opened."
);
let cancel_channel = self.alloc_ongoing().await?;

View File

@@ -52,6 +52,8 @@ pub struct InnerContext {
pub(crate) running_state: RwLock<RunningState>,
/// Mutex to avoid generating the key for the user more than once.
pub(crate) generating_key_mutex: Mutex<()>,
/// Mutex to enforce only a single running oauth2 is running.
pub(crate) oauth2_mutex: Mutex<()>,
pub(crate) translated_stockstrings: RwLock<HashMap<usize, String>>,
pub(crate) logs: (SyncSender<Event>, SyncReceiver<Event>),
@@ -117,6 +119,7 @@ impl Context {
bob: RwLock::new(Default::default()),
last_smeared_timestamp: RwLock::new(0),
generating_key_mutex: Mutex::new(()),
oauth2_mutex: Mutex::new(()),
translated_stockstrings: RwLock::new(HashMap::new()),
logs: unbounded(),
scheduler: RwLock::new(Scheduler::Stopped),

View File

@@ -1227,6 +1227,14 @@ impl Imap {
return;
}
if !self
.add_flag_finalized_with_set(context, SELECT_ALL, "\\Deleted")
.await
{
error!(context, "Cannot mark messages for deletion {}", folder);
return;
}
// we now trigger expunge to actually delete messages
self.config.selected_folder_needs_expunge = true;
match self.select_folder::<String>(context, None).await {

View File

@@ -47,6 +47,7 @@ impl Imap {
}
self.config.selected_folder = None;
self.config.selected_folder_needs_expunge = false;
Ok(())
}
@@ -77,26 +78,7 @@ impl Imap {
// deselect existing folder, if needed (it's also done implicitly by SELECT, however, without EXPUNGE then)
let needs_expunge = { self.config.selected_folder_needs_expunge };
if needs_expunge {
if let Some(ref folder) = self.config.selected_folder {
info!(context, "Expunge messages in \"{}\".", folder);
// A CLOSE-SELECT is considerably faster than an EXPUNGE-SELECT, see
// https://tools.ietf.org/html/rfc3501#section-6.4.2
if let Some(ref mut session) = &mut self.session {
match session.close().await {
Ok(_) => {
info!(context, "close/expunge succeeded");
}
Err(err) => {
self.trigger_reconnect();
return Err(Error::CloseExpungeFailed(err));
}
}
} else {
return Err(Error::NoSession);
}
}
self.config.selected_folder_needs_expunge = false;
self.close_folder(context).await?;
}
// select new folder

View File

@@ -810,45 +810,6 @@ pub enum Connection<'a> {
Smtp(&'a mut Smtp),
}
async fn add_imap_deletion_jobs(context: &Context) -> sql::Result<()> {
if let Some(delete_server_after) = context.get_config_delete_server_after().await {
let threshold_timestamp = time() - delete_server_after;
// Select all expired messages which don't have a
// corresponding message deletion job yet.
let msg_ids = context
.sql
.query_map(
"SELECT id FROM msgs \
WHERE timestamp < ? \
AND server_uid != 0 \
AND NOT EXISTS (SELECT 1 FROM jobs WHERE foreign_id = msgs.id \
AND action = ?)",
paramsv![threshold_timestamp, Action::DeleteMsgOnImap],
|row| row.get::<_, MsgId>(0),
|ids| {
ids.collect::<std::result::Result<Vec<_>, _>>()
.map_err(Into::into)
},
)
.await?;
// Schedule IMAP deletion for expired messages.
for msg_id in msg_ids {
add(
context,
Action::DeleteMsgOnImap,
msg_id.to_u32() as i32,
Params::new(),
0,
)
.await;
}
}
Ok(())
}
async fn load_imap_deletion_msgid(context: &Context) -> sql::Result<Option<MsgId>> {
if let Some(delete_server_after) = context.get_config_delete_server_after().await {
let threshold_timestamp = time() - delete_server_after;

View File

@@ -75,8 +75,6 @@ pub async fn dc_get_oauth2_url(
}
}
// The following function may block due http-requests;
// must not be called from the main thread or by the ui!
pub async fn dc_get_oauth2_access_token(
context: &Context,
addr: impl AsRef<str>,
@@ -84,9 +82,7 @@ pub async fn dc_get_oauth2_access_token(
regenerate: bool,
) -> Option<String> {
if let Some(oauth2) = Oauth2::from_address(addr) {
// TODO: FIXME
// let lock = context.oauth2_critical.clone();
// let _l = lock.lock().await;
let lock = context.oauth2_mutex.lock().await;
// read generated token
if !regenerate && !is_expired(context).await {
@@ -243,6 +239,8 @@ pub async fn dc_get_oauth2_access_token(
warn!(context, "Failed to find OAuth2 access token");
}
drop(lock);
response.access_token
} else {
warn!(context, "Internal OAuth2 error: 2");