Skip to content

Commit 28a4c19

Browse files
committed
Move self-reporting logic into new file self_reporting.rs
1 parent 0fd053a commit 28a4c19

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::login_param::{ConfiguredLoginParam, EnteredLoginParam};
3232
use crate::message::{self, Message, MessageState, MsgId, Viewtype};
@@ -1064,197 +1064,6 @@ impl Context {
10641064
Ok(res)
10651065
}
10661066

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

594-
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
595-
async fn test_draft_self_report() -> Result<()> {
596-
let alice = TestContext::new_alice().await;
597-
598-
let chat_id = alice.send_self_report().await?;
599-
let msg = get_chat_msg(&alice, chat_id, 0, 2).await;
600-
assert_eq!(msg.get_info_type(), SystemMessage::ChatProtectionEnabled);
601-
602-
let chat = Chat::load_from_db(&alice, chat_id).await?;
603-
assert!(chat.is_protected());
604-
605-
let statistics_msg = get_chat_msg(&alice, chat_id, 1, 2).await;
606-
assert_eq!(statistics_msg.get_filename().unwrap(), "statistics.txt");
607-
608-
Ok(())
609-
}
610-
611594
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
612595
async fn test_cache_is_cleared_when_io_is_started() -> Result<()> {
613596
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
@@ -22,6 +22,7 @@ use crate::imap::{session::Session, FolderMeaning, Imap};
2222
use crate::location;
2323
use crate::log::LogExt;
2424
use crate::message::MsgId;
25+
use crate::self_reporting::maybe_send_self_report;
2526
use crate::smtp::{send_smtp_messages, Smtp};
2627
use crate::sql;
2728
use crate::tools::{self, duration_to_str, maybe_add_time_based_warnings, time, time_elapsed};
@@ -505,20 +506,7 @@ async fn inbox_fetch_idle(ctx: &Context, imap: &mut Imap, mut session: Session)
505506
}
506507
};
507508

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

0 commit comments

Comments
 (0)