Skip to content

Commit a72c546

Browse files
committed
Move self-reporting logic into new file self_reporting.rs
1 parent 1473ea0 commit a72c546

File tree

5 files changed

+293
-223
lines changed

5 files changed

+293
-223
lines changed

src/context.rs

Lines changed: 1 addition & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::debug_logging::DebugLogging;
2626
use crate::download::DownloadState;
2727
use crate::events::{Event, EventEmitter, EventType, Events};
2828
use crate::imap::{FolderMeaning, Imap, ServerMetadata};
29-
use crate::key::{load_self_public_key, load_self_secret_key, DcKey as _};
29+
use crate::key::{load_self_public_key, load_self_secret_key, self_fingerprint, DcKey as _};
3030
use crate::log::LogExt;
3131
use crate::log::{info, warn};
3232
use crate::login_param::{ConfiguredLoginParam, EnteredLoginParam};
@@ -1062,197 +1062,6 @@ impl Context {
10621062
Ok(res)
10631063
}
10641064

1065-
async fn get_self_report(&self) -> Result<String> {
1066-
#[derive(Serialize)]
1067-
struct Statistics {
1068-
core_version: String,
1069-
num_msgs: u32,
1070-
num_chats: u32,
1071-
db_size: u64,
1072-
key_created: i64,
1073-
chat_numbers: ChatNumbers,
1074-
self_reporting_id: String,
1075-
}
1076-
#[derive(Default, Serialize)]
1077-
struct ChatNumbers {
1078-
protected: u32,
1079-
protection_broken: u32,
1080-
opportunistic_dc: u32,
1081-
opportunistic_mua: u32,
1082-
unencrypted_dc: u32,
1083-
unencrypted_mua: u32,
1084-
}
1085-
1086-
let num_msgs: u32 = self
1087-
.sql
1088-
.query_get_value(
1089-
"SELECT COUNT(*) FROM msgs WHERE hidden=0 AND chat_id!=?",
1090-
(DC_CHAT_ID_TRASH,),
1091-
)
1092-
.await?
1093-
.unwrap_or_default();
1094-
1095-
let num_chats: u32 = self
1096-
.sql
1097-
.query_get_value("SELECT COUNT(*) FROM chats WHERE id>9 AND blocked!=1", ())
1098-
.await?
1099-
.unwrap_or_default();
1100-
1101-
let db_size = tokio::fs::metadata(&self.sql.dbfile).await?.len();
1102-
1103-
let key_created = load_self_secret_key(self)
1104-
.await?
1105-
.primary_key
1106-
.created_at()
1107-
.timestamp();
1108-
1109-
// how many of the chats active in the last months are:
1110-
// - protected
1111-
// - protection-broken
1112-
// - opportunistic-encrypted and the contact uses Delta Chat
1113-
// - opportunistic-encrypted and the contact uses a classical MUA
1114-
// - unencrypted and the contact uses Delta Chat
1115-
// - unencrypted and the contact uses a classical MUA
1116-
let three_months_ago = time().saturating_sub(3600 * 24 * 30 * 3);
1117-
let chat_numbers = self
1118-
.sql
1119-
.query_map(
1120-
"SELECT c.protected, m.param, m.msgrmsg
1121-
FROM chats c
1122-
JOIN msgs m
1123-
ON c.id=m.chat_id
1124-
AND m.id=(
1125-
SELECT id
1126-
FROM msgs
1127-
WHERE chat_id=c.id
1128-
AND hidden=0
1129-
AND download_state=?
1130-
AND to_id!=?
1131-
ORDER BY timestamp DESC, id DESC LIMIT 1)
1132-
WHERE c.id>9
1133-
AND (c.blocked=0 OR c.blocked=2)
1134-
AND IFNULL(m.timestamp,c.created_timestamp) > ?
1135-
GROUP BY c.id",
1136-
(DownloadState::Done, ContactId::INFO, three_months_ago),
1137-
|row| {
1138-
let protected: ProtectionStatus = row.get(0)?;
1139-
let message_param: Params =
1140-
row.get::<_, String>(1)?.parse().unwrap_or_default();
1141-
let is_dc_message: bool = row.get(2)?;
1142-
Ok((protected, message_param, is_dc_message))
1143-
},
1144-
|rows| {
1145-
let mut chats = ChatNumbers::default();
1146-
for row in rows {
1147-
let (protected, message_param, is_dc_message) = row?;
1148-
let encrypted = message_param
1149-
.get_bool(Param::GuaranteeE2ee)
1150-
.unwrap_or(false);
1151-
1152-
if protected == ProtectionStatus::Protected {
1153-
chats.protected += 1;
1154-
} else if protected == ProtectionStatus::ProtectionBroken {
1155-
chats.protection_broken += 1;
1156-
} else if encrypted {
1157-
if is_dc_message {
1158-
chats.opportunistic_dc += 1;
1159-
} else {
1160-
chats.opportunistic_mua += 1;
1161-
}
1162-
} else if is_dc_message {
1163-
chats.unencrypted_dc += 1;
1164-
} else {
1165-
chats.unencrypted_mua += 1;
1166-
}
1167-
}
1168-
Ok(chats)
1169-
},
1170-
)
1171-
.await?;
1172-
1173-
let self_reporting_id = match self.get_config(Config::SelfReportingId).await? {
1174-
Some(id) => id,
1175-
None => {
1176-
let id = create_id();
1177-
self.set_config_internal(Config::SelfReportingId, Some(&id))
1178-
.await?;
1179-
id
1180-
}
1181-
};
1182-
let statistics = Statistics {
1183-
core_version: get_version_str().to_string(),
1184-
num_msgs,
1185-
num_chats,
1186-
db_size,
1187-
key_created,
1188-
chat_numbers,
1189-
self_reporting_id,
1190-
};
1191-
1192-
Ok(serde_json::to_string_pretty(&statistics)?)
1193-
}
1194-
1195-
/// Drafts a message with statistics about the usage of Delta Chat.
1196-
/// The user can inspect the message if they want, and then hit "Send".
1197-
///
1198-
/// On the other end, a bot will receive the message and make it available
1199-
/// to Delta Chat's developers.
1200-
pub async fn send_self_report(&self) -> Result<ChatId> {
1201-
info!(self, "Sending self report.");
1202-
// Setting `Config::LastHousekeeping` at the beginning avoids endless loops when things do not
1203-
// work out for whatever reason or are interrupted by the OS.
1204-
self.set_config_internal(Config::LastSelfReportSent, Some(&time().to_string()))
1205-
.await
1206-
.log_err(self)
1207-
.ok();
1208-
1209-
const SELF_REPORTING_BOT_VCARD: &str = include_str!("../assets/self-reporting-bot.vcf");
1210-
let contact_id: ContactId = *import_vcard(self, SELF_REPORTING_BOT_VCARD)
1211-
.await?
1212-
.first()
1213-
.context("Self reporting bot vCard does not contain a contact")?;
1214-
mark_contact_id_as_verified(self, contact_id, ContactId::SELF).await?;
1215-
1216-
let chat_id = if let Some(res) = ChatId::lookup_by_contact(self, contact_id).await? {
1217-
// Already exists, no need to create.
1218-
res
1219-
} else {
1220-
let chat_id = ChatId::get_for_contact(self, contact_id).await?;
1221-
chat_id
1222-
.set_visibility(self, ChatVisibility::Archived)
1223-
.await?;
1224-
chat::set_muted(self, chat_id, MuteDuration::Forever).await?;
1225-
chat_id
1226-
};
1227-
1228-
chat_id
1229-
.set_protection(self, ProtectionStatus::Protected, time(), Some(contact_id))
1230-
.await?;
1231-
1232-
let mut msg = Message::new(Viewtype::File);
1233-
msg.set_text(
1234-
"The attachment contains anonymous usage statistics, \
1235-
because you enabled this in the settings. \
1236-
This helps us improve the security of Delta Chat. \
1237-
See TODO[blog post] for more information."
1238-
.to_string(),
1239-
);
1240-
msg.set_file_from_bytes(
1241-
self,
1242-
"statistics.txt",
1243-
self.get_self_report().await?.as_bytes(),
1244-
Some("text/plain"),
1245-
)?;
1246-
1247-
crate::chat::send_msg(self, chat_id, &mut msg)
1248-
.await
1249-
.context("Failed to send self_reporting message")
1250-
.log_err(self)
1251-
.ok();
1252-
1253-
Ok(chat_id)
1254-
}
1255-
12561065
/// Get a list of fresh, unmuted messages in unblocked chats.
12571066
///
12581067
/// The list starts with the most recent message

src/context/context_tests.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -598,23 +598,6 @@ async fn test_get_next_msgs() -> Result<()> {
598598
Ok(())
599599
}
600600

601-
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
602-
async fn test_draft_self_report() -> Result<()> {
603-
let alice = TestContext::new_alice().await;
604-
605-
let chat_id = alice.send_self_report().await?;
606-
let msg = get_chat_msg(&alice, chat_id, 0, 2).await;
607-
assert_eq!(msg.get_info_type(), SystemMessage::ChatProtectionEnabled);
608-
609-
let chat = Chat::load_from_db(&alice, chat_id).await?;
610-
assert!(chat.is_protected());
611-
612-
let statistics_msg = get_chat_msg(&alice, chat_id, 1, 2).await;
613-
assert_eq!(statistics_msg.get_filename().unwrap(), "statistics.txt");
614-
615-
Ok(())
616-
}
617-
618601
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
619602
async fn test_cache_is_cleared_when_io_is_started() -> Result<()> {
620603
let alice = TestContext::new_alice().await;

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ pub mod html;
9898
pub mod net;
9999
pub mod plaintext;
100100
mod push;
101+
mod self_reporting;
101102
pub mod summary;
102103

103104
mod debug_logging;

src/scheduler.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::imap::{FolderMeaning, Imap, session::Session};
2424
use crate::location;
2525
use crate::log::{LogExt, error, info, warn};
2626
use crate::message::MsgId;
27+
use crate::self_reporting::maybe_send_self_report;
2728
use crate::smtp::{Smtp, send_smtp_messages};
2829
use crate::sql;
2930
use crate::tools::{self, duration_to_str, maybe_add_time_based_warnings, time, time_elapsed};
@@ -507,20 +508,7 @@ async fn inbox_fetch_idle(ctx: &Context, imap: &mut Imap, mut session: Session)
507508
}
508509
};
509510

510-
//#[cfg(target_os = "android")] TODO
511-
if ctx.get_config_bool(Config::SelfReporting).await? {
512-
match ctx.get_config_i64(Config::LastSelfReportSent).await {
513-
Ok(last_selfreport_time) => {
514-
let next_selfreport_time = last_selfreport_time.saturating_add(30); // TODO increase to 1 day or 1 week
515-
if next_selfreport_time <= time() {
516-
ctx.send_self_report().await?;
517-
}
518-
}
519-
Err(err) => {
520-
warn!(ctx, "Failed to get last self_reporting time: {}", err);
521-
}
522-
}
523-
}
511+
maybe_send_self_report(ctx).await?;
524512
match ctx.get_config_bool(Config::FetchedExistingMsgs).await {
525513
Ok(fetched_existing_msgs) => {
526514
if !fetched_existing_msgs {

0 commit comments

Comments
 (0)