From dd68031b692065469b4fde959e5751df2005f10e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Tue, 2 Mar 2021 14:32:30 +0100 Subject: [PATCH 1/2] improvement: implement /receipt --- src/client_server/read_marker.rs | 52 ++++++++++++++++++++++++++++---- src/main.rs | 2 +- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/client_server/read_marker.rs b/src/client_server/read_marker.rs index 0c4ec1a4..f7d3712d 100644 --- a/src/client_server/read_marker.rs +++ b/src/client_server/read_marker.rs @@ -2,7 +2,8 @@ use super::State; use crate::{ConduitResult, Database, Error, Ruma}; use ruma::{ api::client::{ - error::ErrorKind, r0::capabilities::get_capabilities, r0::read_marker::set_read_marker, + error::ErrorKind, + r0::{read_marker::set_read_marker, receipt::create_receipt}, }, events::{AnyEphemeralRoomEvent, AnyEvent, EventType}, }; @@ -83,13 +84,52 @@ pub async fn set_read_marker_route( feature = "conduit_bin", post("/_matrix/client/r0/rooms/<_>/receipt/<_>/<_>", data = "") )] -pub async fn set_receipt_route( +pub async fn create_receipt_route( db: State<'_, Database>, - body: Ruma, -) -> ConduitResult { - let _sender_user = body.sender_user.as_ref().expect("user is authenticated"); + body: Ruma>, +) -> ConduitResult { + let sender_user = body.sender_user.as_ref().expect("user is authenticated"); + + db.rooms.edus.private_read_set( + &body.room_id, + &sender_user, + db.rooms + .get_pdu_count(&body.event_id)? + .ok_or(Error::BadRequest( + ErrorKind::InvalidParam, + "Event does not exist.", + ))?, + &db.globals, + )?; + + let mut user_receipts = BTreeMap::new(); + user_receipts.insert( + sender_user.clone(), + ruma::events::receipt::Receipt { + ts: Some(SystemTime::now()), + }, + ); + let mut receipt_content = BTreeMap::new(); + receipt_content.insert( + body.event_id.to_owned(), + ruma::events::receipt::Receipts { + read: Some(user_receipts), + }, + ); + + db.rooms.edus.readreceipt_update( + &sender_user, + &body.room_id, + AnyEvent::Ephemeral(AnyEphemeralRoomEvent::Receipt( + ruma::events::receipt::ReceiptEvent { + content: ruma::events::receipt::ReceiptEventContent(receipt_content), + room_id: body.room_id.clone(), + }, + )), + &db.globals, + )?; db.flush().await?; - Ok(set_read_marker::Response.into()) + Ok(create_receipt::Response.into()) } diff --git a/src/main.rs b/src/main.rs index 65434a5d..d5f1f4e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,7 +90,7 @@ fn setup_rocket() -> rocket::Rocket { client_server::get_backup_key_sessions_route, client_server::get_backup_keys_route, client_server::set_read_marker_route, - client_server::set_receipt_route, + client_server::create_receipt_route, client_server::create_typing_event_route, client_server::create_room_route, client_server::redact_event_route, From 278751eb23cd524fb489634905612e4939c1501c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Tue, 2 Mar 2021 14:36:48 +0100 Subject: [PATCH 2/2] improvement: use transaction ids for federation requests --- src/database/sending.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/database/sending.rs b/src/database/sending.rs index fd327935..8c487e17 100644 --- a/src/database/sending.rs +++ b/src/database/sending.rs @@ -9,6 +9,7 @@ use std::{ use crate::{appservice_server, server_server, utils, Error, PduEvent, Result}; use federation::transactions::send_transaction_message; use log::info; +use ring::digest; use rocket::futures::stream::{FuturesUnordered, StreamExt}; use ruma::{ api::{appservice, federation, OutgoingRequest}, @@ -229,6 +230,13 @@ impl Sending { Ok(()) } + fn calculate_hash(keys: &[IVec]) -> Vec { + // We only hash the pdu's event ids, not the whole pdu + let bytes = keys.join(&0xff); + let hash = digest::digest(&digest::SHA256, &bytes); + hash.as_ref().to_owned() + } + async fn handle_event( server: Box, is_appservice: bool, @@ -266,7 +274,10 @@ impl Sending { .unwrap(), // TODO: handle error appservice::event::push_events::v1::Request { events: &pdu_jsons, - txn_id: &utils::random_string(16), + txn_id: &base64::encode_config( + Self::calculate_hash(&pdu_ids), + base64::URL_SAFE_NO_PAD, + ), }, ) .await @@ -309,7 +320,10 @@ impl Sending { pdus: &pdu_jsons, edus: &[], origin_server_ts: SystemTime::now(), - transaction_id: &utils::random_string(16), + transaction_id: &base64::encode_config( + Self::calculate_hash(&pdu_ids), + base64::URL_SAFE_NO_PAD, + ), }, ) .await