mirror of
https://github.com/chatmail/core.git
synced 2026-08-18 06:36:29 +03:00
Compare commits
2 Commits
subkey
...
fix_export
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15bf53c092 | ||
|
|
f6afd5f7f1 |
@@ -501,9 +501,15 @@ char* dc_get_oauth2_url (dc_context_t* context, const char*
|
||||
* To interrupt a configuration prematurely, use dc_stop_ongoing_process();
|
||||
* this is not needed if #DC_EVENT_CONFIGURE_PROGRESS reports success.
|
||||
*
|
||||
* If #DC_EVENT_CONFIGURE_PROGRESS reports failure,
|
||||
* the core continues to use the last working configuration
|
||||
* and parameters as `addr`, `mail_pw` etc. are set to that.
|
||||
* On a successfull configuration,
|
||||
* the core makes a copy of the parameters mentioned above:
|
||||
* the original parameters as are never modified by the core.
|
||||
*
|
||||
* UI-implementors should keep this in mind -
|
||||
* eg. if the UI wants to prefill a configure-edit-dialog with these parameters,
|
||||
* the UI should reset them if the user cancels the dialog
|
||||
* after a configure-attempts has failed.
|
||||
* Otherwise the parameters may not reflect the current configuation.
|
||||
*
|
||||
* @memberof dc_context_t
|
||||
* @param context The context object as created by dc_context_new().
|
||||
|
||||
@@ -192,7 +192,7 @@ unsafe fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: &Message) {
|
||||
let msgtext = msg.get_text();
|
||||
info!(
|
||||
context,
|
||||
"{}{}{}{}: {} (Contact#{}): {} {}{}{}{}{} [{}]",
|
||||
"{}#{}{}{}: {} (Contact#{}): {} {}{}{}{}{} [{}]",
|
||||
prefix.as_ref(),
|
||||
msg.get_id(),
|
||||
if msg.get_showpadlock() { "🔒" } else { "" },
|
||||
@@ -240,7 +240,7 @@ unsafe fn log_msglist(context: &Context, msglist: &Vec<MsgId>) -> Result<(), Err
|
||||
lines_out += 1
|
||||
}
|
||||
let msg = Message::load_from_db(context, msg_id)?;
|
||||
log_msg(context, "", &msg);
|
||||
log_msg(context, "Msg", &msg);
|
||||
}
|
||||
}
|
||||
if lines_out > 0 {
|
||||
@@ -426,12 +426,12 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
if msg.is_setupmessage() {
|
||||
let setupcodebegin = msg.get_setupcodebegin(context);
|
||||
println!(
|
||||
"The setup code for setup message {} starts with: {}",
|
||||
"The setup code for setup message Msg#{} starts with: {}",
|
||||
msg_id,
|
||||
setupcodebegin.unwrap_or_default(),
|
||||
);
|
||||
} else {
|
||||
bail!("{} is no setup message.", msg_id,);
|
||||
bail!("Msg#{} is no setup message.", msg_id,);
|
||||
}
|
||||
}
|
||||
"continue-key-transfer" => {
|
||||
@@ -726,7 +726,7 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
let marker = location.marker.as_ref().unwrap_or(&default_marker);
|
||||
info!(
|
||||
context,
|
||||
"Loc#{}: {}: lat={} lng={} acc={} Chat#{} Contact#{} {} {}",
|
||||
"Loc#{}: {}: lat={} lng={} acc={} Chat#{} Contact#{} Msg#{} {}",
|
||||
location.location_id,
|
||||
dc_timestamp_to_str(location.timestamp),
|
||||
location.latitude,
|
||||
@@ -852,9 +852,9 @@ pub unsafe fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::E
|
||||
println!("{} images or videos: ", images.len());
|
||||
for (i, data) in images.iter().enumerate() {
|
||||
if 0 == i {
|
||||
print!("{}", data);
|
||||
print!("Msg#{}", data);
|
||||
} else {
|
||||
print!(", {}", data);
|
||||
print!(", Msg#{}", data);
|
||||
}
|
||||
}
|
||||
print!("\n");
|
||||
|
||||
@@ -642,7 +642,7 @@ class TestOnlineAccount:
|
||||
assert os.path.exists(msg_in.filename)
|
||||
assert os.stat(msg_in.filename).st_size == os.stat(path).st_size
|
||||
|
||||
def test_import_export_online_all(self, acfactory, tmpdir, lp):
|
||||
def test_import_export_online_all_twice(self, acfactory, tmpdir, lp):
|
||||
ac1 = acfactory.get_online_configuring_account()
|
||||
wait_configuration_progress(ac1, 1000)
|
||||
|
||||
@@ -675,7 +675,6 @@ class TestOnlineAccount:
|
||||
assert len(messages) == 1
|
||||
assert messages[0].text == "msg1"
|
||||
|
||||
pytest.xfail("cannot export twice yet, probably due to interrupt_idle failing")
|
||||
# wait until a second passed since last backup
|
||||
# because get_latest_backupfile() shall return the latest backup
|
||||
# from a UI it's unlikely anyone manages to export two
|
||||
|
||||
@@ -126,7 +126,7 @@ impl Chatlist {
|
||||
" SELECT MAX(timestamp)",
|
||||
" FROM msgs",
|
||||
" WHERE chat_id=c.id",
|
||||
" AND hidden=0)",
|
||||
" AND (hidden=0 OR (hidden=1 AND state=19)))",
|
||||
" WHERE c.id>9",
|
||||
" AND c.blocked=0",
|
||||
" AND c.id IN(SELECT chat_id FROM chats_contacts WHERE contact_id=?)",
|
||||
@@ -149,7 +149,7 @@ impl Chatlist {
|
||||
" SELECT MAX(timestamp)",
|
||||
" FROM msgs",
|
||||
" WHERE chat_id=c.id",
|
||||
" AND hidden=0)",
|
||||
" AND (hidden=0 OR (hidden=1 AND state=19)))",
|
||||
" WHERE c.id>9",
|
||||
" AND c.blocked=0",
|
||||
" AND c.archived=1",
|
||||
@@ -175,7 +175,7 @@ impl Chatlist {
|
||||
" SELECT MAX(timestamp)",
|
||||
" FROM msgs",
|
||||
" WHERE chat_id=c.id",
|
||||
" AND hidden=0)",
|
||||
" AND (hidden=0 OR (hidden=1 AND state=19)))",
|
||||
" WHERE c.id>9",
|
||||
" AND c.blocked=0",
|
||||
" AND c.name LIKE ?",
|
||||
@@ -198,7 +198,7 @@ impl Chatlist {
|
||||
" SELECT MAX(timestamp)",
|
||||
" FROM msgs",
|
||||
" WHERE chat_id=c.id",
|
||||
" AND hidden=0)",
|
||||
" AND (hidden=0 OR (hidden=1 AND state=19)))",
|
||||
" WHERE c.id>9",
|
||||
" AND c.blocked=0",
|
||||
" AND c.archived=0",
|
||||
@@ -294,7 +294,7 @@ impl Chatlist {
|
||||
let lastmsg_id = self.ids[index].1;
|
||||
let mut lastcontact = None;
|
||||
|
||||
let mut lastmsg = if let Ok(lastmsg) = Message::load_from_db(context, lastmsg_id) {
|
||||
let lastmsg = if let Ok(lastmsg) = Message::load_from_db(context, lastmsg_id) {
|
||||
if lastmsg.from_id != DC_CONTACT_ID_SELF
|
||||
&& (chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup)
|
||||
{
|
||||
@@ -306,16 +306,6 @@ impl Chatlist {
|
||||
None
|
||||
};
|
||||
|
||||
if let Ok(draft) = get_draft(context, chat.id) {
|
||||
if draft.is_some()
|
||||
&& (lastmsg.is_none()
|
||||
|| draft.as_ref().unwrap().timestamp_sort
|
||||
> lastmsg.as_ref().unwrap().timestamp_sort)
|
||||
{
|
||||
lastmsg = draft;
|
||||
}
|
||||
}
|
||||
|
||||
if chat.id == DC_CHAT_ID_ARCHIVED_LINK {
|
||||
ret.text2 = None;
|
||||
} else if lastmsg.is_none() || lastmsg.as_ref().unwrap().from_id == DC_CONTACT_ID_UNDEFINED
|
||||
|
||||
@@ -421,16 +421,6 @@ pub fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context) {
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
// remember the entered parameters on success
|
||||
// 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 {
|
||||
LoginParam::from_database(context, "").save_to_database(context, "configured_raw_");
|
||||
} else {
|
||||
LoginParam::from_database(context, "configured_raw_").save_to_database(context, "");
|
||||
}
|
||||
|
||||
context.free_ongoing();
|
||||
progress!(context, if success { 1000 } else { 0 });
|
||||
}
|
||||
|
||||
@@ -154,15 +154,13 @@ pub(crate) fn dc_timestamp_from_date(date_time: *mut mailimf_date_time) -> i64 {
|
||||
******************************************************************************/
|
||||
|
||||
pub fn dc_timestamp_to_str(wanted: i64) -> String {
|
||||
let ts = Local.timestamp(wanted, 0);
|
||||
let ts = chrono::Utc.timestamp(wanted, 0);
|
||||
ts.format("%Y.%m.%d %H:%M:%S").to_string()
|
||||
}
|
||||
|
||||
pub(crate) fn dc_gm2local_offset() -> i64 {
|
||||
/* returns the offset that must be _added_ to an UTC/GMT-time to create the localtime.
|
||||
the function may return negative values. */
|
||||
let lt = Local::now();
|
||||
lt.offset().local_minus_utc() as i64
|
||||
((lt.offset().local_minus_utc() / (60 * 60)) * 100) as i64
|
||||
}
|
||||
|
||||
/* timesmearing */
|
||||
|
||||
@@ -502,8 +502,8 @@ impl Imap {
|
||||
}
|
||||
|
||||
info!(context, "IMAP unsetup_handle step 3 (clearing config).");
|
||||
self.config.write().unwrap().selected_folder = None;
|
||||
self.config.write().unwrap().selected_mailbox = None;
|
||||
// self.config.write().unwrap().selected_folder = None;
|
||||
// self.config.write().unwrap().selected_mailbox = None;
|
||||
info!(context, "IMAP unsetup_handle step 4 (disconnected).",);
|
||||
}
|
||||
|
||||
|
||||
19
src/pgp.rs
19
src/pgp.rs
@@ -5,7 +5,7 @@ use std::io::Cursor;
|
||||
use pgp::armor::BlockType;
|
||||
use pgp::composed::{
|
||||
Deserializable, KeyType as PgpKeyType, Message, SecretKeyParamsBuilder, SignedPublicKey,
|
||||
SignedPublicSubKey, SignedSecretKey, SubkeyParamsBuilder,
|
||||
SignedSecretKey, SubkeyParamsBuilder,
|
||||
};
|
||||
use pgp::crypto::{HashAlgorithm, SymmetricKeyAlgorithm};
|
||||
use pgp::types::{CompressionAlgorithm, KeyTrait, SecretKeyTrait, StringToKey};
|
||||
@@ -97,29 +97,18 @@ pub fn create_keypair(addr: impl AsRef<str>) -> Option<(Key, Key)> {
|
||||
Some((Key::Public(public_key), Key::Secret(private_key)))
|
||||
}
|
||||
|
||||
/// Select subkey of the public key to use for encryption.
|
||||
///
|
||||
/// Currently the first subkey is selected.
|
||||
fn select_pk_for_encryption(key: &SignedPublicKey) -> Option<&SignedPublicSubKey> {
|
||||
key.public_subkeys.iter().find(|_k|
|
||||
// TODO: check if it is an encryption subkey
|
||||
true)
|
||||
}
|
||||
|
||||
pub fn pk_encrypt(
|
||||
plain: &[u8],
|
||||
public_keys_for_encryption: &Keyring,
|
||||
private_key_for_signing: Option<&Key>,
|
||||
) -> Result<String, Error> {
|
||||
let lit_msg = Message::new_literal_bytes("", plain);
|
||||
let pkeys: Vec<&SignedPublicSubKey> = public_keys_for_encryption
|
||||
let pkeys: Vec<&SignedPublicKey> = public_keys_for_encryption
|
||||
.keys()
|
||||
.iter()
|
||||
.filter_map(|key| {
|
||||
key.as_ref()
|
||||
.try_into()
|
||||
.ok()
|
||||
.and_then(select_pk_for_encryption)
|
||||
let k: &Key = &key;
|
||||
k.try_into().ok()
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user