mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
cargo fmt
Also formatted SQL query, because rustfmt can't format statements with too long strings.
This commit is contained in:
committed by
link2xt
parent
093839c2b0
commit
25274f13c3
396
src/chat.rs
396
src/chat.rs
@@ -795,218 +795,236 @@ impl Chat {
|
|||||||
None => bail!("Cannot prepare message for sending, address is not configured."),
|
None => bail!("Cannot prepare message for sending, address is not configured."),
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_rfc724_mid = {
|
let new_rfc724_mid = {
|
||||||
let grpid = match self.typ {
|
let grpid = match self.typ {
|
||||||
Chattype::Group | Chattype::VerifiedGroup => Some(self.grpid.as_str()),
|
Chattype::Group | Chattype::VerifiedGroup => Some(self.grpid.as_str()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
|
||||||
dc_create_outgoing_rfc724_mid(grpid, &from)
|
|
||||||
};
|
};
|
||||||
|
dc_create_outgoing_rfc724_mid(grpid, &from)
|
||||||
|
};
|
||||||
|
|
||||||
if self.typ == Chattype::Single {
|
if self.typ == Chattype::Single {
|
||||||
if let Some(id) = context
|
if let Some(id) = context
|
||||||
.sql
|
.sql
|
||||||
.query_get_value(
|
.query_get_value(
|
||||||
context,
|
context,
|
||||||
"SELECT contact_id FROM chats_contacts WHERE chat_id=?;",
|
"SELECT contact_id FROM chats_contacts WHERE chat_id=?;",
|
||||||
paramsv![self.id],
|
paramsv![self.id],
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
|
||||||
to_id = id;
|
|
||||||
} else {
|
|
||||||
error!(
|
|
||||||
context,
|
|
||||||
"Cannot send message, contact for {} not found.", self.id,
|
|
||||||
);
|
|
||||||
bail!("Cannot set message, contact for {} not found.", self.id);
|
|
||||||
}
|
|
||||||
} else if (self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup)
|
|
||||||
&& self.param.get_int(Param::Unpromoted).unwrap_or_default() == 1
|
|
||||||
{
|
{
|
||||||
msg.param.set_int(Param::AttachGroupImage, 1);
|
to_id = id;
|
||||||
self.param.remove(Param::Unpromoted);
|
} else {
|
||||||
self.update_param(context).await?;
|
error!(
|
||||||
|
context,
|
||||||
|
"Cannot send message, contact for {} not found.", self.id,
|
||||||
|
);
|
||||||
|
bail!("Cannot set message, contact for {} not found.", self.id);
|
||||||
}
|
}
|
||||||
|
} else if (self.typ == Chattype::Group || self.typ == Chattype::VerifiedGroup)
|
||||||
|
&& self.param.get_int(Param::Unpromoted).unwrap_or_default() == 1
|
||||||
|
{
|
||||||
|
msg.param.set_int(Param::AttachGroupImage, 1);
|
||||||
|
self.param.remove(Param::Unpromoted);
|
||||||
|
self.update_param(context).await?;
|
||||||
|
}
|
||||||
|
|
||||||
/* check if we want to encrypt this message. If yes and circumstances change
|
/* check if we want to encrypt this message. If yes and circumstances change
|
||||||
so that E2EE is no longer available at a later point (reset, changed settings),
|
so that E2EE is no longer available at a later point (reset, changed settings),
|
||||||
we might not send the message out at all */
|
we might not send the message out at all */
|
||||||
if !msg
|
if !msg
|
||||||
.param
|
.param
|
||||||
.get_bool(Param::ForcePlaintext)
|
.get_bool(Param::ForcePlaintext)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
{
|
{
|
||||||
let mut can_encrypt = true;
|
let mut can_encrypt = true;
|
||||||
let mut all_mutual = context.get_config_bool(Config::E2eeEnabled).await;
|
let mut all_mutual = context.get_config_bool(Config::E2eeEnabled).await;
|
||||||
|
|
||||||
// take care that this statement returns NULL rows
|
// take care that this statement returns NULL rows
|
||||||
// if there is no peerstates for a chat member!
|
// if there is no peerstates for a chat member!
|
||||||
// for DC_PARAM_SELFTALK this statement does not return any row
|
// for DC_PARAM_SELFTALK this statement does not return any row
|
||||||
let res = context
|
let res = context
|
||||||
.sql
|
.sql
|
||||||
.query_map(
|
.query_map(
|
||||||
"SELECT ps.prefer_encrypted, c.addr \
|
"SELECT ps.prefer_encrypted, c.addr \
|
||||||
FROM chats_contacts cc \
|
FROM chats_contacts cc \
|
||||||
LEFT JOIN contacts c ON cc.contact_id=c.id \
|
LEFT JOIN contacts c ON cc.contact_id=c.id \
|
||||||
LEFT JOIN acpeerstates ps ON c.addr=ps.addr \
|
LEFT JOIN acpeerstates ps ON c.addr=ps.addr \
|
||||||
WHERE cc.chat_id=? AND cc.contact_id>9;",
|
WHERE cc.chat_id=? AND cc.contact_id>9;",
|
||||||
paramsv![self.id],
|
paramsv![self.id],
|
||||||
|row| {
|
|row| {
|
||||||
let addr: String = row.get(1)?;
|
let addr: String = row.get(1)?;
|
||||||
|
|
||||||
if let Some(prefer_encrypted) = row.get::<_, Option<i32>>(0)? {
|
if let Some(prefer_encrypted) = row.get::<_, Option<i32>>(0)? {
|
||||||
// the peerstate exist, so we have either public_key or gossip_key
|
// the peerstate exist, so we have either public_key or gossip_key
|
||||||
// and can encrypt potentially
|
// and can encrypt potentially
|
||||||
if prefer_encrypted != 1 {
|
if prefer_encrypted != 1 {
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
"[autocrypt] peerstate for {} is {}",
|
"[autocrypt] peerstate for {} is {}",
|
||||||
addr,
|
addr,
|
||||||
if prefer_encrypted == 0 {
|
if prefer_encrypted == 0 {
|
||||||
"NOPREFERENCE"
|
"NOPREFERENCE"
|
||||||
} else {
|
} else {
|
||||||
"RESET"
|
"RESET"
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
all_mutual = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
info!(context, "[autocrypt] no peerstate for {}", addr,);
|
|
||||||
can_encrypt = false;
|
|
||||||
all_mutual = false;
|
all_mutual = false;
|
||||||
}
|
}
|
||||||
Ok(())
|
} else {
|
||||||
},
|
info!(context, "[autocrypt] no peerstate for {}", addr,);
|
||||||
|rows| rows.collect::<Result<Vec<_>, _>>().map_err(Into::into),
|
can_encrypt = false;
|
||||||
)
|
all_mutual = false;
|
||||||
.await;
|
}
|
||||||
match res {
|
Ok(())
|
||||||
Ok(_) => {}
|
},
|
||||||
Err(err) => {
|
|rows| rows.collect::<Result<Vec<_>, _>>().map_err(Into::into),
|
||||||
warn!(context, "chat: failed to load peerstates: {:?}", err);
|
)
|
||||||
}
|
.await;
|
||||||
}
|
match res {
|
||||||
|
Ok(_) => {}
|
||||||
if can_encrypt && (all_mutual || self.id.parent_is_encrypted(context).await?) {
|
Err(err) => {
|
||||||
msg.param.set_int(Param::GuaranteeE2ee, 1);
|
warn!(context, "chat: failed to load peerstates: {:?}", err);
|
||||||
}
|
|
||||||
}
|
|
||||||
// reset encrypt error state eg. for forwarding
|
|
||||||
msg.param.remove(Param::ErroneousE2ee);
|
|
||||||
|
|
||||||
// set "In-Reply-To:" to identify the message to which the composed message is a reply;
|
|
||||||
// set "References:" to identify the "thread" of the conversation;
|
|
||||||
// both according to RFC 5322 3.6.4, page 25
|
|
||||||
//
|
|
||||||
// as self-talks are mainly used to transfer data between devices,
|
|
||||||
// we do not set In-Reply-To/References in this case.
|
|
||||||
if !self.is_self_talk() {
|
|
||||||
if let Some((parent_rfc724_mid, parent_in_reply_to, parent_references)) =
|
|
||||||
self.id.get_parent_mime_headers(context).await
|
|
||||||
{
|
|
||||||
if !parent_rfc724_mid.is_empty() {
|
|
||||||
new_in_reply_to = parent_rfc724_mid.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
// the whole list of messages referenced may be huge;
|
|
||||||
// only use the oldest and and the parent message
|
|
||||||
let parent_references = parent_references
|
|
||||||
.find(' ')
|
|
||||||
.and_then(|n| parent_references.get(..n))
|
|
||||||
.unwrap_or(&parent_references);
|
|
||||||
|
|
||||||
if !parent_references.is_empty() && !parent_rfc724_mid.is_empty() {
|
|
||||||
// angle brackets are added by the mimefactory later
|
|
||||||
new_references = format!("{} {}", parent_references, parent_rfc724_mid);
|
|
||||||
} else if !parent_references.is_empty() {
|
|
||||||
new_references = parent_references.to_string();
|
|
||||||
} else if !parent_in_reply_to.is_empty() && !parent_rfc724_mid.is_empty() {
|
|
||||||
new_references = format!("{} {}", parent_in_reply_to, parent_rfc724_mid);
|
|
||||||
} else if !parent_in_reply_to.is_empty() {
|
|
||||||
new_references = parent_in_reply_to;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add independent location to database
|
if can_encrypt && (all_mutual || self.id.parent_is_encrypted(context).await?) {
|
||||||
|
msg.param.set_int(Param::GuaranteeE2ee, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// reset encrypt error state eg. for forwarding
|
||||||
|
msg.param.remove(Param::ErroneousE2ee);
|
||||||
|
|
||||||
if msg.param.exists(Param::SetLatitude)
|
// set "In-Reply-To:" to identify the message to which the composed message is a reply;
|
||||||
&& context
|
// set "References:" to identify the "thread" of the conversation;
|
||||||
.sql
|
// both according to RFC 5322 3.6.4, page 25
|
||||||
.execute(
|
//
|
||||||
"INSERT INTO locations \
|
// as self-talks are mainly used to transfer data between devices,
|
||||||
|
// we do not set In-Reply-To/References in this case.
|
||||||
|
if !self.is_self_talk() {
|
||||||
|
if let Some((parent_rfc724_mid, parent_in_reply_to, parent_references)) =
|
||||||
|
self.id.get_parent_mime_headers(context).await
|
||||||
|
{
|
||||||
|
if !parent_rfc724_mid.is_empty() {
|
||||||
|
new_in_reply_to = parent_rfc724_mid.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
// the whole list of messages referenced may be huge;
|
||||||
|
// only use the oldest and and the parent message
|
||||||
|
let parent_references = parent_references
|
||||||
|
.find(' ')
|
||||||
|
.and_then(|n| parent_references.get(..n))
|
||||||
|
.unwrap_or(&parent_references);
|
||||||
|
|
||||||
|
if !parent_references.is_empty() && !parent_rfc724_mid.is_empty() {
|
||||||
|
// angle brackets are added by the mimefactory later
|
||||||
|
new_references = format!("{} {}", parent_references, parent_rfc724_mid);
|
||||||
|
} else if !parent_references.is_empty() {
|
||||||
|
new_references = parent_references.to_string();
|
||||||
|
} else if !parent_in_reply_to.is_empty() && !parent_rfc724_mid.is_empty() {
|
||||||
|
new_references = format!("{} {}", parent_in_reply_to, parent_rfc724_mid);
|
||||||
|
} else if !parent_in_reply_to.is_empty() {
|
||||||
|
new_references = parent_in_reply_to;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add independent location to database
|
||||||
|
|
||||||
|
if msg.param.exists(Param::SetLatitude)
|
||||||
|
&& context
|
||||||
|
.sql
|
||||||
|
.execute(
|
||||||
|
"INSERT INTO locations \
|
||||||
(timestamp,from_id,chat_id, latitude,longitude,independent)\
|
(timestamp,from_id,chat_id, latitude,longitude,independent)\
|
||||||
VALUES (?,?,?, ?,?,1);", // 1=DC_CONTACT_ID_SELF
|
VALUES (?,?,?, ?,?,1);", // 1=DC_CONTACT_ID_SELF
|
||||||
paramsv![
|
paramsv![
|
||||||
timestamp,
|
|
||||||
DC_CONTACT_ID_SELF,
|
|
||||||
self.id,
|
|
||||||
msg.param.get_float(Param::SetLatitude).unwrap_or_default(),
|
|
||||||
msg.param.get_float(Param::SetLongitude).unwrap_or_default(),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
location_id = context
|
|
||||||
.sql
|
|
||||||
.get_rowid2(
|
|
||||||
context,
|
|
||||||
"locations",
|
|
||||||
"timestamp",
|
|
||||||
timestamp,
|
timestamp,
|
||||||
"from_id",
|
DC_CONTACT_ID_SELF,
|
||||||
DC_CONTACT_ID_SELF as i32,
|
self.id,
|
||||||
)
|
msg.param.get_float(Param::SetLatitude).unwrap_or_default(),
|
||||||
.await?;
|
msg.param.get_float(Param::SetLongitude).unwrap_or_default(),
|
||||||
}
|
],
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
location_id = context
|
||||||
|
.sql
|
||||||
|
.get_rowid2(
|
||||||
|
context,
|
||||||
|
"locations",
|
||||||
|
"timestamp",
|
||||||
|
timestamp,
|
||||||
|
"from_id",
|
||||||
|
DC_CONTACT_ID_SELF as i32,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
let ephemeral_timer = if msg.param.get_cmd() == SystemMessage::EphemeralTimerChanged {
|
let ephemeral_timer = if msg.param.get_cmd() == SystemMessage::EphemeralTimerChanged {
|
||||||
EphemeralTimer::Disabled
|
EphemeralTimer::Disabled
|
||||||
} else {
|
} else {
|
||||||
self.id.get_ephemeral_timer(context).await?
|
self.id.get_ephemeral_timer(context).await?
|
||||||
};
|
};
|
||||||
let ephemeral_timestamp = match ephemeral_timer {
|
let ephemeral_timestamp = match ephemeral_timer {
|
||||||
EphemeralTimer::Disabled => 0,
|
EphemeralTimer::Disabled => 0,
|
||||||
EphemeralTimer::Enabled { duration } => timestamp + i64::from(duration),
|
EphemeralTimer::Enabled { duration } => timestamp + i64::from(duration),
|
||||||
};
|
};
|
||||||
|
|
||||||
// add message to the database
|
// add message to the database
|
||||||
|
|
||||||
if context.sql.execute(
|
if context
|
||||||
"INSERT INTO msgs (rfc724_mid, chat_id, from_id, to_id, timestamp, type, state, txt, param, hidden, mime_in_reply_to, mime_references, location_id, ephemeral_timer, ephemeral_timestamp) VALUES (?,?,?,?,?, ?,?,?,?,?, ?,?,?,?,?);",
|
.sql
|
||||||
paramsv![
|
.execute(
|
||||||
new_rfc724_mid,
|
"INSERT INTO msgs (
|
||||||
self.id,
|
rfc724_mid,
|
||||||
DC_CONTACT_ID_SELF,
|
chat_id,
|
||||||
to_id as i32,
|
from_id,
|
||||||
timestamp,
|
to_id,
|
||||||
msg.viewtype,
|
timestamp,
|
||||||
msg.state,
|
type,
|
||||||
msg.text.as_ref().cloned().unwrap_or_default(),
|
state,
|
||||||
msg.param.to_string(),
|
txt,
|
||||||
msg.hidden,
|
param,
|
||||||
new_in_reply_to,
|
hidden,
|
||||||
new_references,
|
mime_in_reply_to,
|
||||||
location_id as i32,
|
mime_references,
|
||||||
ephemeral_timer,
|
location_id,
|
||||||
ephemeral_timestamp
|
ephemeral_timer,
|
||||||
]
|
ephemeral_timestamp)
|
||||||
).await.is_ok() {
|
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);",
|
||||||
msg_id = context.sql.get_rowid(
|
paramsv![
|
||||||
context,
|
new_rfc724_mid,
|
||||||
"msgs",
|
self.id,
|
||||||
"rfc724_mid",
|
DC_CONTACT_ID_SELF,
|
||||||
new_rfc724_mid,
|
to_id as i32,
|
||||||
).await?;
|
timestamp,
|
||||||
} else {
|
msg.viewtype,
|
||||||
error!(
|
msg.state,
|
||||||
context,
|
msg.text.as_ref().cloned().unwrap_or_default(),
|
||||||
"Cannot send message, cannot insert to database ({}).",
|
msg.param.to_string(),
|
||||||
self.id,
|
msg.hidden,
|
||||||
);
|
new_in_reply_to,
|
||||||
}
|
new_references,
|
||||||
|
location_id as i32,
|
||||||
|
ephemeral_timer,
|
||||||
|
ephemeral_timestamp
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
msg_id = context
|
||||||
|
.sql
|
||||||
|
.get_rowid(context, "msgs", "rfc724_mid", new_rfc724_mid)
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
error!(
|
||||||
|
context,
|
||||||
|
"Cannot send message, cannot insert to database ({}).", self.id,
|
||||||
|
);
|
||||||
|
}
|
||||||
schedule_ephemeral_task(context).await;
|
schedule_ephemeral_task(context).await;
|
||||||
|
|
||||||
Ok(MsgId::new(msg_id))
|
Ok(MsgId::new(msg_id))
|
||||||
|
|||||||
Reference in New Issue
Block a user