From 40eebbd9d86f3ac8c0f36924c1c38248cbbfb3af Mon Sep 17 00:00:00 2001 From: Jonas Zohren Date: Wed, 22 Jun 2022 22:14:53 +0000 Subject: [PATCH 01/56] feat(ci): Split clippy into own fallible job For some reason, the clippy build does not work. This change allows the cargo:test job to still succeed and the pipeline to pass --- .gitlab-ci.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 380332b..eb7a96f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -250,17 +250,30 @@ docker:tags:dockerhub: test:cargo: extends: .test-shared-settings before_script: - - rustup component add clippy # If provided, bring in caching through sccache, which uses an external S3 endpoint to store compilation results: - if [ -n "${SCCACHE_ENDPOINT}" ]; then export RUSTC_WRAPPER=/usr/local/cargo/bin/sccache; fi script: - rustc --version && cargo --version # Print version info for debugging - "cargo test --color always --workspace --verbose --locked --no-fail-fast -- -Z unstable-options --format json | gitlab-report -p test > $CI_PROJECT_DIR/report.xml" - - "cargo clippy --color always --verbose --message-format=json | gitlab-report -p clippy > $CI_PROJECT_DIR/gl-code-quality-report.json" artifacts: when: always reports: junit: report.xml + + +test:clippy: + extends: .test-shared-settings + allow_failure: true + before_script: + - rustup component add clippy + # If provided, bring in caching through sccache, which uses an external S3 endpoint to store compilation results: + - if [ -n "${SCCACHE_ENDPOINT}" ]; then export RUSTC_WRAPPER=/usr/local/cargo/bin/sccache; fi + script: + - rustc --version && cargo --version # Print version info for debugging + - "cargo clippy --color always --verbose --message-format=json | gitlab-report -p clippy > $CI_PROJECT_DIR/gl-code-quality-report.json" + artifacts: + when: always + reports: codequality: gl-code-quality-report.json test:format: From 49bd75b8563db181517eb97679ca8349177eb102 Mon Sep 17 00:00:00 2001 From: Jim Date: Thu, 23 Jun 2022 06:58:34 +0000 Subject: [PATCH 02/56] Lightning bolt optional --- conduit-example.toml | 3 +++ src/client_server/account.rs | 22 +++++++++------------- src/config.rs | 6 ++++++ src/database/admin.rs | 8 +++++++- src/database/globals.rs | 4 ++++ 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/conduit-example.toml b/conduit-example.toml index 362f7e7..5eed070 100644 --- a/conduit-example.toml +++ b/conduit-example.toml @@ -40,6 +40,9 @@ allow_registration = true allow_federation = true +# Enable the display name lightning bolt on registration. +enable_lightning_bolt = true + trusted_servers = ["matrix.org"] #max_concurrent_requests = 100 # How many requests Conduit sends to other servers at the same time diff --git a/src/client_server/account.rs b/src/client_server/account.rs index dc0782d..1484bf6 100644 --- a/src/client_server/account.rs +++ b/src/client_server/account.rs @@ -1,10 +1,7 @@ -use std::sync::Arc; - use super::{DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH}; use crate::{ database::{admin::make_user_admin, DatabaseGuard}, - pdu::PduBuilder, - utils, Database, Error, Result, Ruma, + utils, Error, Result, Ruma, }; use ruma::{ api::client::{ @@ -15,16 +12,9 @@ use ruma::{ error::ErrorKind, uiaa::{AuthFlow, AuthType, UiaaInfo}, }, - events::{ - room::{ - member::{MembershipState, RoomMemberEventContent}, - message::RoomMessageEventContent, - }, - GlobalAccountDataEventType, RoomEventType, - }, + events::{room::message::RoomMessageEventContent, GlobalAccountDataEventType}, push, UserId, }; -use serde_json::value::to_raw_value; use tracing::{info, warn}; use register::RegistrationKind; @@ -181,7 +171,13 @@ pub async fn register_route( db.users.create(&user_id, password)?; // Default to pretty displayname - let displayname = format!("{} ⚡️", user_id.localpart()); + let mut displayname = user_id.localpart().to_owned(); + + // If enabled append lightning bolt to display name (default true) + if db.globals.enable_lightning_bolt() { + displayname.push_str(" ⚡️"); + } + db.users .set_displayname(&user_id, Some(displayname.clone()))?; diff --git a/src/config.rs b/src/config.rs index 29af883..7d81d0f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -26,6 +26,8 @@ pub struct Config { pub database_path: String, #[serde(default = "default_db_cache_capacity_mb")] pub db_cache_capacity_mb: f64, + #[serde(default = "true_fn")] + pub enable_lightning_bolt: bool, #[serde(default = "default_conduit_cache_capacity_modifier")] pub conduit_cache_capacity_modifier: f64, #[serde(default = "default_rocksdb_max_open_files")] @@ -135,6 +137,10 @@ impl fmt::Display for Config { &self.max_concurrent_requests.to_string(), ), ("Allow registration", &self.allow_registration.to_string()), + ( + "Enabled lightning bolt", + &self.enable_lightning_bolt.to_string(), + ), ("Allow encryption", &self.allow_encryption.to_string()), ("Allow federation", &self.allow_federation.to_string()), ("Allow room creation", &self.allow_room_creation.to_string()), diff --git a/src/database/admin.rs b/src/database/admin.rs index 6f418ea..edc7691 100644 --- a/src/database/admin.rs +++ b/src/database/admin.rs @@ -598,7 +598,13 @@ async fn process_admin_command( db.users.create(&user_id, Some(password.as_str()))?; // Default to pretty displayname - let displayname = format!("{} ⚡️", user_id.localpart()); + let mut displayname = user_id.localpart().to_owned(); + + // If enabled append lightning bolt to display name (default true) + if db.globals.enable_lightning_bolt() { + displayname.push_str(" ⚡️"); + } + db.users .set_displayname(&user_id, Some(displayname.clone()))?; diff --git a/src/database/globals.rs b/src/database/globals.rs index 7e09128..7d7b7fd 100644 --- a/src/database/globals.rs +++ b/src/database/globals.rs @@ -267,6 +267,10 @@ impl Globals { self.config.default_room_version.clone() } + pub fn enable_lightning_bolt(&self) -> bool { + self.config.enable_lightning_bolt + } + pub fn trusted_servers(&self) -> &[Box] { &self.config.trusted_servers } From 35fd732b047f6c7a848e2065c7e8310ca23041db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Thu, 23 Jun 2022 09:04:19 +0200 Subject: [PATCH 03/56] Bump version to 0.4 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8d791f..c4700ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -406,7 +406,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "conduit" -version = "0.3.0-next" +version = "0.4.0" dependencies = [ "axum", "axum-server", diff --git a/Cargo.toml b/Cargo.toml index f150c4e..a8556a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ authors = ["timokoesters "] homepage = "https://conduit.rs" repository = "https://gitlab.com/famedly/conduit" readme = "README.md" -version = "0.3.0-next" +version = "0.4.0" rust-version = "1.56" edition = "2021" From 3a8321f9adcb575370fa2c606c2a212c1f6f03f3 Mon Sep 17 00:00:00 2001 From: AndSDev Date: Mon, 29 Aug 2022 14:09:08 +0000 Subject: [PATCH 04/56] feat(db/rooms): encryption is not allowed in the admins room --- src/service/rooms/timeline/mod.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 619dca2..32781f2 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -22,6 +22,7 @@ use ruma::{ }, push::{Action, Ruleset, Tweak}, state_res, + state_res::Event, state_res::RoomVersion, uint, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, OwnedServerName, RoomAliasId, RoomId, UserId, @@ -683,6 +684,22 @@ impl Service { let (pdu, pdu_json) = self.create_hash_and_sign_event(pdu_builder, sender, room_id, state_lock)?; + let admin_room = services().rooms.alias.resolve_local_alias( + <&RoomAliasId>::try_from( + format!("#admins:{}", services().globals.server_name()).as_str(), + ) + .expect("#admins:server_name is a valid room alias"), + )?; + if admin_room.filter(|v| v == room_id).is_some() { + if pdu.event_type() == &RoomEventType::RoomEncryption { + warn!("Encryption is not allowed in the admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Encryption is not allowed in the admins room.", + )); + } + } + // We append to state before appending the pdu, so we don't have a moment in time with the // pdu without it's state. This is okay because append_pdu can't fail. let statehashid = services().rooms.state.append_to_state(&pdu)?; From c67f95ebffd60a9efe222816c742b1522e06578e Mon Sep 17 00:00:00 2001 From: AndSDev Date: Wed, 31 Aug 2022 07:10:54 +0000 Subject: [PATCH 05/56] feat(db/rooms): disable leaving from admin room for conduit user --- src/service/rooms/timeline/mod.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 32781f2..2f56fea 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -698,6 +698,26 @@ impl Service { "Encryption is not allowed in the admins room.", )); } + if pdu.event_type() == &RoomEventType::RoomMember { + #[derive(Deserialize)] + struct ExtractMembership { + membership: MembershipState, + } + + let content = serde_json::from_str::(pdu.content.get()) + .map_err(|_| Error::bad_database("Invalid content in pdu."))?; + + if content.membership == MembershipState::Leave { + let server_user = format!("@conduit:{}", services().globals.server_name()); + if sender == &server_user { + warn!("Conduit user cannot leave from admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Conduit user cannot leave from admins room.", + )); + } + } + } } // We append to state before appending the pdu, so we don't have a moment in time with the From da2dbd2877d3b7b1edc2a05bb5593759d8072794 Mon Sep 17 00:00:00 2001 From: AndSDev Date: Wed, 31 Aug 2022 07:11:28 +0000 Subject: [PATCH 06/56] feat(db/rooms): disable leaving from admin room for last user --- src/service/rooms/timeline/mod.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 2f56fea..5d28628 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -716,6 +716,21 @@ impl Service { "Conduit user cannot leave from admins room.", )); } + + let count = services() + .rooms + .state_cache + .room_members(room_id) + .filter_map(|m| m.ok()) + .filter(|m| m.server_name() == services().globals.server_name()) + .count(); + if count < 3 { + warn!("Last admin cannot leave from admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Last admin cannot leave from admins room.", + )); + } } } } From 912491cb28f88fb0ed9cdd1aac4a76a307cbec03 Mon Sep 17 00:00:00 2001 From: AndSDev Date: Wed, 31 Aug 2022 08:22:45 +0000 Subject: [PATCH 07/56] style(db/rooms): refactor admin room pdu validating --- src/service/rooms/timeline/mod.rs | 75 ++++++++++++++++--------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 5d28628..9ededd2 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -691,47 +691,50 @@ impl Service { .expect("#admins:server_name is a valid room alias"), )?; if admin_room.filter(|v| v == room_id).is_some() { - if pdu.event_type() == &RoomEventType::RoomEncryption { - warn!("Encryption is not allowed in the admins room"); - return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Encryption is not allowed in the admins room.", - )); - } - if pdu.event_type() == &RoomEventType::RoomMember { - #[derive(Deserialize)] - struct ExtractMembership { - membership: MembershipState, + match pdu.event_type() { + RoomEventType::RoomEncryption => { + warn!("Encryption is not allowed in the admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Encryption is not allowed in the admins room.", + )); } - - let content = serde_json::from_str::(pdu.content.get()) - .map_err(|_| Error::bad_database("Invalid content in pdu."))?; - - if content.membership == MembershipState::Leave { - let server_user = format!("@conduit:{}", services().globals.server_name()); - if sender == &server_user { - warn!("Conduit user cannot leave from admins room"); - return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Conduit user cannot leave from admins room.", - )); + RoomEventType::RoomMember => { + #[derive(Deserialize)] + struct ExtractMembership { + membership: MembershipState, } - let count = services() - .rooms - .state_cache - .room_members(room_id) - .filter_map(|m| m.ok()) - .filter(|m| m.server_name() == services().globals.server_name()) - .count(); - if count < 3 { - warn!("Last admin cannot leave from admins room"); - return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Last admin cannot leave from admins room.", - )); + let content = serde_json::from_str::(pdu.content.get()) + .map_err(|_| Error::bad_database("Invalid content in pdu."))?; + + if content.membership == MembershipState::Leave { + let server_user = format!("@conduit:{}", services().globals.server_name()); + if sender == &server_user { + warn!("Conduit user cannot leave from admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Conduit user cannot leave from admins room.", + )); + } + + let count = services() + .rooms + .state_cache + .room_members(room_id) + .filter_map(|m| m.ok()) + .filter(|m| m.server_name() == services().globals.server_name()) + .count(); + if count < 3 { + warn!("Last admin cannot leave from admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Last admin cannot leave from admins room.", + )); + } } } + _ => {} } } From 76f81ac2010746c5cba1105a37187ce2e59d2ffe Mon Sep 17 00:00:00 2001 From: AndSDev Date: Tue, 6 Sep 2022 11:32:33 +0000 Subject: [PATCH 08/56] feat(db/rooms): disable banning for last user and conduit user in admins room --- src/service/rooms/timeline/mod.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 9ededd2..66a8196 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -733,6 +733,32 @@ impl Service { )); } } + + if content.membership == MembershipState::Ban && pdu.state_key().is_some() { + let server_user = format!("@conduit:{}", services().globals.server_name()); + if pdu.state_key().as_ref().unwrap() == &server_user { + warn!("Conduit user cannot be banned in admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Conduit user cannot be banned in admins room.", + )); + } + + let count = services() + .rooms + .state_cache + .room_members(room_id) + .filter_map(|m| m.ok()) + .filter(|m| m.server_name() == services().globals.server_name()) + .count(); + if count < 3 { + warn!("Last admin cannot be banned in admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Last admin cannot be banned in admins room.", + )); + } + } } _ => {} } From d755a96c2c3422849fdac8792e5d91141f837a18 Mon Sep 17 00:00:00 2001 From: AndSDev Date: Thu, 13 Oct 2022 11:19:51 +0000 Subject: [PATCH 09/56] refactor(service/rooms/timeline): add cache for server_name --- src/service/rooms/timeline/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 66a8196..9494f67 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -705,11 +705,12 @@ impl Service { membership: MembershipState, } + let server_name = services().globals.server_name(); let content = serde_json::from_str::(pdu.content.get()) .map_err(|_| Error::bad_database("Invalid content in pdu."))?; if content.membership == MembershipState::Leave { - let server_user = format!("@conduit:{}", services().globals.server_name()); + let server_user = format!("@conduit:{}", server_name); if sender == &server_user { warn!("Conduit user cannot leave from admins room"); return Err(Error::BadRequest( @@ -723,7 +724,7 @@ impl Service { .state_cache .room_members(room_id) .filter_map(|m| m.ok()) - .filter(|m| m.server_name() == services().globals.server_name()) + .filter(|m| m.server_name() == server_name) .count(); if count < 3 { warn!("Last admin cannot leave from admins room"); @@ -735,7 +736,7 @@ impl Service { } if content.membership == MembershipState::Ban && pdu.state_key().is_some() { - let server_user = format!("@conduit:{}", services().globals.server_name()); + let server_user = format!("@conduit:{}", server_name); if pdu.state_key().as_ref().unwrap() == &server_user { warn!("Conduit user cannot be banned in admins room"); return Err(Error::BadRequest( @@ -749,7 +750,7 @@ impl Service { .state_cache .room_members(room_id) .filter_map(|m| m.ok()) - .filter(|m| m.server_name() == services().globals.server_name()) + .filter(|m| m.server_name() == server_name) .count(); if count < 3 { warn!("Last admin cannot be banned in admins room"); From e923f63c4919a9eb65f074c8099fc7bc115925ee Mon Sep 17 00:00:00 2001 From: AndSDev Date: Fri, 14 Oct 2022 14:45:05 +0300 Subject: [PATCH 10/56] fix(service/rooms/timeline): fix validating for non-joined members --- src/service/rooms/timeline/mod.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 9494f67..403b400 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -705,13 +705,17 @@ impl Service { membership: MembershipState, } + let target = pdu + .state_key() + .filter(|v| v.starts_with("@")) + .unwrap_or(sender.as_str()); let server_name = services().globals.server_name(); + let server_user = format!("@conduit:{}", server_name); let content = serde_json::from_str::(pdu.content.get()) .map_err(|_| Error::bad_database("Invalid content in pdu."))?; if content.membership == MembershipState::Leave { - let server_user = format!("@conduit:{}", server_name); - if sender == &server_user { + if target == &server_user { warn!("Conduit user cannot leave from admins room"); return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -725,8 +729,9 @@ impl Service { .room_members(room_id) .filter_map(|m| m.ok()) .filter(|m| m.server_name() == server_name) + .filter(|m| m != target) .count(); - if count < 3 { + if count < 2 { warn!("Last admin cannot leave from admins room"); return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -736,8 +741,7 @@ impl Service { } if content.membership == MembershipState::Ban && pdu.state_key().is_some() { - let server_user = format!("@conduit:{}", server_name); - if pdu.state_key().as_ref().unwrap() == &server_user { + if target == &server_user { warn!("Conduit user cannot be banned in admins room"); return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -751,8 +755,9 @@ impl Service { .room_members(room_id) .filter_map(|m| m.ok()) .filter(|m| m.server_name() == server_name) + .filter(|m| m != target) .count(); - if count < 3 { + if count < 2 { warn!("Last admin cannot be banned in admins room"); return Err(Error::BadRequest( ErrorKind::Forbidden, From 9c0c74f547f5088de3e74cf1dc01f58538922e16 Mon Sep 17 00:00:00 2001 From: Paul Beziau Date: Tue, 18 Oct 2022 09:15:07 +0000 Subject: [PATCH 11/56] Migrate database to use correct rule id in pushrules. it convert : - ".m.rules.call" to ".m.rule.call" - ".m.rules.room_one_to_one" to ".m.rule.room_one_to_one" - ".m.rules.encrypted_room_one_to_one" to ".m.rule.encrypted_room_one_to_one" - ".m.rules.message" to ".m.rule.message" - ".m.rules.encrypted" to ".m.rule.encrypted" related to issue #264 --- src/database/mod.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index 15ee137..dce4eff 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -7,7 +7,7 @@ use directories::ProjectDirs; use lru_cache::LruCache; use ruma::{ events::{ - push_rules::PushRulesEventContent, room::message::RoomMessageEventContent, + push_rules::{PushRulesEventContent, PushRulesEvent}, room::message::RoomMessageEventContent, GlobalAccountDataEvent, GlobalAccountDataEventType, StateEventType, }, push::Ruleset, @@ -801,6 +801,72 @@ impl KeyValueDatabase { warn!("Migration: 10 -> 11 finished"); } + if services().globals.database_version()? < 12 { + + for username in services().users.list_local_users().unwrap() { + + let user = UserId::parse_with_server_name(username, services().globals.server_name()) + .unwrap(); + + + let raw_rules_list = services().account_data + .get( + None, + &user, + GlobalAccountDataEventType::PushRules.to_string().into()) + .unwrap() + .expect("Username is invalid"); + + let mut account_data = serde_json::from_str::(raw_rules_list.get()).unwrap(); + let rules_list = &mut account_data.content.global; + + //content rule + { + let content_rule_transformation = + [".m.rules.contains_user_name", ".m.rule.contains_user_name"]; + + let rule = rules_list.content.get(content_rule_transformation[0]); + if rule.is_some() { + let mut rule = rule.unwrap().clone(); + rule.rule_id = content_rule_transformation[1].to_string(); + rules_list.content.remove(content_rule_transformation[0]); + rules_list.content.insert(rule); + } + } + + //underride rules + { + let underride_rule_transformation = + [[".m.rules.call", ".m.rule.call"], + [".m.rules.room_one_to_one", ".m.rule.room_one_to_one"], + [".m.rules.encrypted_room_one_to_one", ".m.rule.encrypted_room_one_to_one"], + [".m.rules.message", ".m.rule.message"], + [".m.rules.encrypted", ".m.rule.encrypted"]]; + + for transformation in underride_rule_transformation { + let rule = rules_list.underride.get(transformation[0]); + if rule.is_some() { + let mut rule = rule.unwrap().clone(); + rule.rule_id = transformation[1].to_string(); + rules_list.underride.remove(transformation[0]); + rules_list.underride.insert(rule); + } + } + } + + services().account_data.update( + None, + &user, + GlobalAccountDataEventType::PushRules.to_string().into(), + &serde_json::to_value(account_data).expect("to json value always works"), + )?; + } + + services().globals.bump_database_version(12)?; + + warn!("Migration: 11 -> 12 finished"); + } + assert_eq!(11, latest_database_version); info!( From d47c1a8ba678bf58b1ff8bdb65438aaaddc80188 Mon Sep 17 00:00:00 2001 From: Paul Beziau Date: Fri, 21 Oct 2022 12:27:11 +0000 Subject: [PATCH 12/56] Fix database version check & code formating --- src/database/mod.rs | 127 ++++++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 59 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index dce4eff..ccc8177 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -7,7 +7,8 @@ use directories::ProjectDirs; use lru_cache::LruCache; use ruma::{ events::{ - push_rules::{PushRulesEventContent, PushRulesEvent}, room::message::RoomMessageEventContent, + push_rules::{PushRulesEvent, PushRulesEventContent}, + room::message::RoomMessageEventContent, GlobalAccountDataEvent, GlobalAccountDataEventType, StateEventType, }, push::Ruleset, @@ -405,7 +406,7 @@ impl KeyValueDatabase { } // If the database has any data, perform data migrations before starting - let latest_database_version = 11; + let latest_database_version = 12; if services().users.count()? > 0 { // MIGRATIONS @@ -801,73 +802,81 @@ impl KeyValueDatabase { warn!("Migration: 10 -> 11 finished"); } - if services().globals.database_version()? < 12 { + if services().globals.database_version()? < 12 { + for username in services().users.list_local_users().unwrap() { + let user = + UserId::parse_with_server_name(username, services().globals.server_name()) + .unwrap(); - for username in services().users.list_local_users().unwrap() { + let raw_rules_list = services() + .account_data + .get( + None, + &user, + GlobalAccountDataEventType::PushRules.to_string().into(), + ) + .unwrap() + .expect("Username is invalid"); - let user = UserId::parse_with_server_name(username, services().globals.server_name()) - .unwrap(); + let mut account_data = + serde_json::from_str::(raw_rules_list.get()).unwrap(); + let rules_list = &mut account_data.content.global; + //content rule + { + let content_rule_transformation = + [".m.rules.contains_user_name", ".m.rule.contains_user_name"]; - let raw_rules_list = services().account_data - .get( - None, - &user, - GlobalAccountDataEventType::PushRules.to_string().into()) - .unwrap() - .expect("Username is invalid"); + let rule = rules_list.content.get(content_rule_transformation[0]); + if rule.is_some() { + let mut rule = rule.unwrap().clone(); + rule.rule_id = content_rule_transformation[1].to_string(); + rules_list.content.remove(content_rule_transformation[0]); + rules_list.content.insert(rule); + } + } - let mut account_data = serde_json::from_str::(raw_rules_list.get()).unwrap(); - let rules_list = &mut account_data.content.global; + //underride rules + { + let underride_rule_transformation = [ + [".m.rules.call", ".m.rule.call"], + [".m.rules.room_one_to_one", ".m.rule.room_one_to_one"], + [ + ".m.rules.encrypted_room_one_to_one", + ".m.rule.encrypted_room_one_to_one", + ], + [".m.rules.message", ".m.rule.message"], + [".m.rules.encrypted", ".m.rule.encrypted"], + ]; - //content rule - { - let content_rule_transformation = - [".m.rules.contains_user_name", ".m.rule.contains_user_name"]; + for transformation in underride_rule_transformation { + let rule = rules_list.underride.get(transformation[0]); + if rule.is_some() { + let mut rule = rule.unwrap().clone(); + rule.rule_id = transformation[1].to_string(); + rules_list.underride.remove(transformation[0]); + rules_list.underride.insert(rule); + } + } + } - let rule = rules_list.content.get(content_rule_transformation[0]); - if rule.is_some() { - let mut rule = rule.unwrap().clone(); - rule.rule_id = content_rule_transformation[1].to_string(); - rules_list.content.remove(content_rule_transformation[0]); - rules_list.content.insert(rule); - } - } + services().account_data.update( + None, + &user, + GlobalAccountDataEventType::PushRules.to_string().into(), + &serde_json::to_value(account_data).expect("to json value always works"), + )?; + } - //underride rules - { - let underride_rule_transformation = - [[".m.rules.call", ".m.rule.call"], - [".m.rules.room_one_to_one", ".m.rule.room_one_to_one"], - [".m.rules.encrypted_room_one_to_one", ".m.rule.encrypted_room_one_to_one"], - [".m.rules.message", ".m.rule.message"], - [".m.rules.encrypted", ".m.rule.encrypted"]]; + services().globals.bump_database_version(12)?; - for transformation in underride_rule_transformation { - let rule = rules_list.underride.get(transformation[0]); - if rule.is_some() { - let mut rule = rule.unwrap().clone(); - rule.rule_id = transformation[1].to_string(); - rules_list.underride.remove(transformation[0]); - rules_list.underride.insert(rule); - } - } - } + warn!("Migration: 11 -> 12 finished"); + } - services().account_data.update( - None, - &user, - GlobalAccountDataEventType::PushRules.to_string().into(), - &serde_json::to_value(account_data).expect("to json value always works"), - )?; - } - - services().globals.bump_database_version(12)?; - - warn!("Migration: 11 -> 12 finished"); - } - - assert_eq!(11, latest_database_version); + assert_eq!( + services().globals.database_version().unwrap(), + latest_database_version + ); info!( "Loaded {} database with version {}", From 7c98ba64aa3f64be9aff77f36c33d2d48d9653b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sat, 15 Oct 2022 16:56:08 +0200 Subject: [PATCH 13/56] fix: HEAD requests should produce METHOD_NOT_ALLOWED --- src/api/client_server/directory.rs | 11 ++--------- src/api/client_server/sync.rs | 2 +- src/main.rs | 18 ++++++++++++------ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/api/client_server/directory.rs b/src/api/client_server/directory.rs index a7381d8..f07a225 100644 --- a/src/api/client_server/directory.rs +++ b/src/api/client_server/directory.rs @@ -87,10 +87,7 @@ pub async fn set_room_visibility_route( if !services().rooms.metadata.exists(&body.room_id)? { // Return 404 if the room doesn't exist - return Err(Error::BadRequest( - ErrorKind::NotFound, - "Room not found", - )); + return Err(Error::BadRequest(ErrorKind::NotFound, "Room not found")); } match &body.visibility { @@ -116,13 +113,9 @@ pub async fn set_room_visibility_route( pub async fn get_room_visibility_route( body: Ruma, ) -> Result { - if !services().rooms.metadata.exists(&body.room_id)? { // Return 404 if the room doesn't exist - return Err(Error::BadRequest( - ErrorKind::NotFound, - "Room not found", - )); + return Err(Error::BadRequest(ErrorKind::NotFound, "Room not found")); } Ok(get_room_visibility::v3::Response { diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 828ae19..7de274b 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -905,7 +905,7 @@ async fn sync_helper( let leave_shortstatekey = services() .rooms .short - .get_or_create_shortstatekey(&StateEventType::RoomMember, &sender_user.as_str())?; + .get_or_create_shortstatekey(&StateEventType::RoomMember, sender_user.as_str())?; left_state_ids.insert(leave_shortstatekey, left_event_id); diff --git a/src/main.rs b/src/main.rs index 626de3a..a782de0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,10 +24,13 @@ use figment::{ }; use http::{ header::{self, HeaderName}, - Method, Uri, + Method, StatusCode, Uri, }; use opentelemetry::trace::{FutureExt, Tracer}; -use ruma::api::{client::error::ErrorKind, IncomingRequest}; +use ruma::api::{ + client::{error::Error as RumaError, error::ErrorKind, uiaa::UiaaResponse}, + IncomingRequest, +}; use tokio::signal; use tower::ServiceBuilder; use tower_http::{ @@ -191,15 +194,18 @@ async fn run_server() -> io::Result<()> { async fn unrecognized_method( req: axum::http::Request, next: axum::middleware::Next, -) -> std::result::Result { +) -> std::result::Result { let method = req.method().clone(); let uri = req.uri().clone(); let inner = next.run(req).await; if inner.status() == axum::http::StatusCode::METHOD_NOT_ALLOWED { warn!("Method not allowed: {method} {uri}"); - return Ok( - Error::BadRequest(ErrorKind::Unrecognized, "Unrecognized request").into_response(), - ); + return Ok(RumaResponse(UiaaResponse::MatrixError(RumaError { + kind: ErrorKind::Unrecognized, + message: "M_UNRECOGNIZED: Unrecognized request".to_owned(), + status_code: StatusCode::METHOD_NOT_ALLOWED, + })) + .into_response()); } Ok(inner) } From 02dd3d32f2ea7a40fe76402f321009f16579fd6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sun, 30 Oct 2022 20:36:14 +0100 Subject: [PATCH 14/56] fix: element android did not reset notification counts --- src/api/client_server/account.rs | 4 ++-- src/api/client_server/directory.rs | 11 ++--------- src/api/client_server/sync.rs | 5 ++--- src/database/key_value/rooms/user.rs | 25 +++++++++++++++++++++++++ src/database/mod.rs | 2 ++ src/service/rooms/user/data.rs | 3 +++ src/service/rooms/user/mod.rs | 4 ++++ 7 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/api/client_server/account.rs b/src/api/client_server/account.rs index c9e3c9b..309a361 100644 --- a/src/api/client_server/account.rs +++ b/src/api/client_server/account.rs @@ -4,8 +4,8 @@ use ruma::{ api::client::{ account::{ change_password, deactivate, get_3pids, get_username_availability, register, - request_3pid_management_token_via_email, request_3pid_management_token_via_msisdn, whoami, - ThirdPartyIdRemovalStatus, + request_3pid_management_token_via_email, request_3pid_management_token_via_msisdn, + whoami, ThirdPartyIdRemovalStatus, }, error::ErrorKind, uiaa::{AuthFlow, AuthType, UiaaInfo}, diff --git a/src/api/client_server/directory.rs b/src/api/client_server/directory.rs index a7381d8..f07a225 100644 --- a/src/api/client_server/directory.rs +++ b/src/api/client_server/directory.rs @@ -87,10 +87,7 @@ pub async fn set_room_visibility_route( if !services().rooms.metadata.exists(&body.room_id)? { // Return 404 if the room doesn't exist - return Err(Error::BadRequest( - ErrorKind::NotFound, - "Room not found", - )); + return Err(Error::BadRequest(ErrorKind::NotFound, "Room not found")); } match &body.visibility { @@ -116,13 +113,9 @@ pub async fn set_room_visibility_route( pub async fn get_room_visibility_route( body: Ruma, ) -> Result { - if !services().rooms.metadata.exists(&body.room_id)? { // Return 404 if the room doesn't exist - return Err(Error::BadRequest( - ErrorKind::NotFound, - "Room not found", - )); + return Err(Error::BadRequest(ErrorKind::NotFound, "Room not found")); } Ok(get_room_visibility::v3::Response { diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 828ae19..56f918a 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -282,9 +282,8 @@ async fn sync_helper( let send_notification_counts = !timeline_pdus.is_empty() || services() .rooms - .edus - .read_receipt - .last_privateread_update(&sender_user, &room_id)? + .user + .last_notification_read(&sender_user, &room_id)? > since; let mut timeline_users = HashSet::new(); diff --git a/src/database/key_value/rooms/user.rs b/src/database/key_value/rooms/user.rs index 3d8d1c8..4c43572 100644 --- a/src/database/key_value/rooms/user.rs +++ b/src/database/key_value/rooms/user.rs @@ -7,12 +7,20 @@ impl service::rooms::user::Data for KeyValueDatabase { let mut userroom_id = user_id.as_bytes().to_vec(); userroom_id.push(0xff); userroom_id.extend_from_slice(room_id.as_bytes()); + let mut roomuser_id = room_id.as_bytes().to_vec(); + roomuser_id.push(0xff); + roomuser_id.extend_from_slice(user_id.as_bytes()); self.userroomid_notificationcount .insert(&userroom_id, &0_u64.to_be_bytes())?; self.userroomid_highlightcount .insert(&userroom_id, &0_u64.to_be_bytes())?; + self.roomuserid_lastnotificationread.insert( + &roomuser_id, + &services().globals.next_count()?.to_be_bytes(), + )?; + Ok(()) } @@ -44,6 +52,23 @@ impl service::rooms::user::Data for KeyValueDatabase { .unwrap_or(Ok(0)) } + fn last_notification_read(&self, user_id: &UserId, room_id: &RoomId) -> Result { + let mut key = room_id.as_bytes().to_vec(); + key.push(0xff); + key.extend_from_slice(user_id.as_bytes()); + + Ok(self + .roomuserid_lastnotificationread + .get(&key)? + .map(|bytes| { + utils::u64_from_bytes(&bytes).map_err(|_| { + Error::bad_database("Count in roomuserid_lastprivatereadupdate is invalid.") + }) + }) + .transpose()? + .unwrap_or(0)) + } + fn associate_token_shortstatehash( &self, room_id: &RoomId, diff --git a/src/database/mod.rs b/src/database/mod.rs index 15ee137..3746efe 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -98,6 +98,7 @@ pub struct KeyValueDatabase { pub(super) userroomid_notificationcount: Arc, // NotifyCount = u64 pub(super) userroomid_highlightcount: Arc, // HightlightCount = u64 + pub(super) roomuserid_lastnotificationread: Arc, // LastNotificationRead = u64 /// Remember the current state hash of a room. pub(super) roomid_shortstatehash: Arc, @@ -317,6 +318,7 @@ impl KeyValueDatabase { userroomid_notificationcount: builder.open_tree("userroomid_notificationcount")?, userroomid_highlightcount: builder.open_tree("userroomid_highlightcount")?, + roomuserid_lastnotificationread: builder.open_tree("userroomid_highlightcount")?, statekey_shortstatekey: builder.open_tree("statekey_shortstatekey")?, shortstatekey_statekey: builder.open_tree("shortstatekey_statekey")?, diff --git a/src/service/rooms/user/data.rs b/src/service/rooms/user/data.rs index 43c4c92..4b8a4ec 100644 --- a/src/service/rooms/user/data.rs +++ b/src/service/rooms/user/data.rs @@ -8,6 +8,9 @@ pub trait Data: Send + Sync { fn highlight_count(&self, user_id: &UserId, room_id: &RoomId) -> Result; + // Returns the count at which the last reset_notification_counts was called + fn last_notification_read(&self, user_id: &UserId, room_id: &RoomId) -> Result; + fn associate_token_shortstatehash( &self, room_id: &RoomId, diff --git a/src/service/rooms/user/mod.rs b/src/service/rooms/user/mod.rs index a765cfd..2266d97 100644 --- a/src/service/rooms/user/mod.rs +++ b/src/service/rooms/user/mod.rs @@ -22,6 +22,10 @@ impl Service { self.db.highlight_count(user_id, room_id) } + pub fn last_notification_read(&self, user_id: &UserId, room_id: &RoomId) -> Result { + self.db.last_notification_read(user_id, room_id) + } + pub fn associate_token_shortstatehash( &self, room_id: &RoomId, From 5d691f405eb6cb13f40ec420b5fe99d99fe5feb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sun, 30 Oct 2022 21:22:32 +0100 Subject: [PATCH 15/56] fix: stuck typing indicators --- src/database/key_value/rooms/edus/typing.rs | 43 +++++++++++++++++++++ src/service/rooms/edus/typing/data.rs | 3 ++ src/service/rooms/edus/typing/mod.rs | 42 ++------------------ 3 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/database/key_value/rooms/edus/typing.rs b/src/database/key_value/rooms/edus/typing.rs index 4a2f0f9..d50c000 100644 --- a/src/database/key_value/rooms/edus/typing.rs +++ b/src/database/key_value/rooms/edus/typing.rs @@ -1,4 +1,5 @@ use std::collections::HashSet; +use std::mem; use ruma::{OwnedUserId, RoomId, UserId}; @@ -53,6 +54,48 @@ impl service::rooms::edus::typing::Data for KeyValueDatabase { Ok(()) } + fn typings_maintain( + &self, + room_id: &RoomId, + ) -> Result<()> { + let mut prefix = room_id.as_bytes().to_vec(); + prefix.push(0xff); + + let current_timestamp = utils::millis_since_unix_epoch(); + + let mut found_outdated = false; + + // Find all outdated edus before inserting a new one + for outdated_edu in self + .typingid_userid + .scan_prefix(prefix) + .map(|(key, _)| { + Ok::<_, Error>(( + key.clone(), + utils::u64_from_bytes( + &key.splitn(2, |&b| b == 0xff).nth(1).ok_or_else(|| { + Error::bad_database("RoomTyping has invalid timestamp or delimiters.") + })?[0..mem::size_of::()], + ) + .map_err(|_| Error::bad_database("RoomTyping has invalid timestamp bytes."))?, + )) + }) + .filter_map(|r| r.ok()) + .take_while(|&(_, timestamp)| timestamp < current_timestamp) + { + // This is an outdated edu (time > timestamp) + self.typingid_userid.remove(&outdated_edu.0)?; + found_outdated = true; + } + + if found_outdated { + self.roomid_lasttypingupdate + .insert(room_id.as_bytes(), &services().globals.next_count()?.to_be_bytes())?; + } + + Ok(()) + } + fn last_typing_update(&self, room_id: &RoomId) -> Result { Ok(self .roomid_lasttypingupdate diff --git a/src/service/rooms/edus/typing/data.rs b/src/service/rooms/edus/typing/data.rs index c4ad867..3b1eecf 100644 --- a/src/service/rooms/edus/typing/data.rs +++ b/src/service/rooms/edus/typing/data.rs @@ -10,6 +10,9 @@ pub trait Data: Send + Sync { /// Removes a user from typing before the timeout is reached. fn typing_remove(&self, user_id: &UserId, room_id: &RoomId) -> Result<()>; + /// Makes sure that typing events with old timestamps get removed. + fn typings_maintain(&self, room_id: &RoomId) -> Result<()>; + /// Returns the count of the last typing update in this room. fn last_typing_update(&self, room_id: &RoomId) -> Result; diff --git a/src/service/rooms/edus/typing/mod.rs b/src/service/rooms/edus/typing/mod.rs index d05ec90..6b066f0 100644 --- a/src/service/rooms/edus/typing/mod.rs +++ b/src/service/rooms/edus/typing/mod.rs @@ -21,54 +21,18 @@ impl Service { self.db.typing_remove(user_id, room_id) } - /* TODO: Do this in background thread? /// Makes sure that typing events with old timestamps get removed. fn typings_maintain( &self, room_id: &RoomId, - globals: &super::super::globals::Globals, ) -> Result<()> { - let mut prefix = room_id.as_bytes().to_vec(); - prefix.push(0xff); - - let current_timestamp = utils::millis_since_unix_epoch(); - - let mut found_outdated = false; - - // Find all outdated edus before inserting a new one - for outdated_edu in self - .typingid_userid - .scan_prefix(prefix) - .map(|(key, _)| { - Ok::<_, Error>(( - key.clone(), - utils::u64_from_bytes( - &key.splitn(2, |&b| b == 0xff).nth(1).ok_or_else(|| { - Error::bad_database("RoomTyping has invalid timestamp or delimiters.") - })?[0..mem::size_of::()], - ) - .map_err(|_| Error::bad_database("RoomTyping has invalid timestamp bytes."))?, - )) - }) - .filter_map(|r| r.ok()) - .take_while(|&(_, timestamp)| timestamp < current_timestamp) - { - // This is an outdated edu (time > timestamp) - self.typingid_userid.remove(&outdated_edu.0)?; - found_outdated = true; - } - - if found_outdated { - self.roomid_lasttypingupdate - .insert(room_id.as_bytes(), &globals.next_count()?.to_be_bytes())?; - } - - Ok(()) + self.db.typings_maintain(room_id) } - */ /// Returns the count of the last typing update in this room. pub fn last_typing_update(&self, room_id: &RoomId) -> Result { + self.typings_maintain(room_id)?; + self.db.last_typing_update(room_id) } From 0cf6545116f475db1e42f0c72ae30cdd2663f029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sun, 30 Oct 2022 21:23:10 +0100 Subject: [PATCH 16/56] fix: not sending enough state on join --- src/api/client_server/sync.rs | 41 ++++++++++++--------- src/database/key_value/rooms/edus/typing.rs | 11 +++--- src/service/rooms/edus/typing/mod.rs | 5 +-- 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 5c1c23d..94e4f5b 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -388,13 +388,35 @@ async fn sync_helper( )) }; + let since_sender_member: Option = since_shortstatehash + .and_then(|shortstatehash| { + services() + .rooms + .state_accessor + .state_get( + shortstatehash, + &StateEventType::RoomMember, + sender_user.as_str(), + ) + .transpose() + }) + .transpose()? + .and_then(|pdu| { + serde_json::from_str(pdu.content.get()) + .map_err(|_| Error::bad_database("Invalid PDU in database.")) + .ok() + }); + + let joined_since_last_sync = + since_sender_member.map_or(true, |member| member.membership != MembershipState::Join); + let ( heroes, joined_member_count, invited_member_count, joined_since_last_sync, state_events, - ) = if since_shortstatehash.is_none() { + ) = if since_shortstatehash.is_none() || joined_since_last_sync { // Probably since = 0, we will do an initial sync let (joined_member_count, invited_member_count, heroes) = calculate_counts()?; @@ -487,23 +509,6 @@ async fn sync_helper( // Incremental /sync let since_shortstatehash = since_shortstatehash.unwrap(); - let since_sender_member: Option = services() - .rooms - .state_accessor - .state_get( - since_shortstatehash, - &StateEventType::RoomMember, - sender_user.as_str(), - )? - .and_then(|pdu| { - serde_json::from_str(pdu.content.get()) - .map_err(|_| Error::bad_database("Invalid PDU in database.")) - .ok() - }); - - let joined_since_last_sync = since_sender_member - .map_or(true, |member| member.membership != MembershipState::Join); - let mut state_events = Vec::new(); let mut lazy_loaded = HashSet::new(); diff --git a/src/database/key_value/rooms/edus/typing.rs b/src/database/key_value/rooms/edus/typing.rs index d50c000..d2d4306 100644 --- a/src/database/key_value/rooms/edus/typing.rs +++ b/src/database/key_value/rooms/edus/typing.rs @@ -54,10 +54,7 @@ impl service::rooms::edus::typing::Data for KeyValueDatabase { Ok(()) } - fn typings_maintain( - &self, - room_id: &RoomId, - ) -> Result<()> { + fn typings_maintain(&self, room_id: &RoomId) -> Result<()> { let mut prefix = room_id.as_bytes().to_vec(); prefix.push(0xff); @@ -89,8 +86,10 @@ impl service::rooms::edus::typing::Data for KeyValueDatabase { } if found_outdated { - self.roomid_lasttypingupdate - .insert(room_id.as_bytes(), &services().globals.next_count()?.to_be_bytes())?; + self.roomid_lasttypingupdate.insert( + room_id.as_bytes(), + &services().globals.next_count()?.to_be_bytes(), + )?; } Ok(()) diff --git a/src/service/rooms/edus/typing/mod.rs b/src/service/rooms/edus/typing/mod.rs index 6b066f0..7d44f7d 100644 --- a/src/service/rooms/edus/typing/mod.rs +++ b/src/service/rooms/edus/typing/mod.rs @@ -22,10 +22,7 @@ impl Service { } /// Makes sure that typing events with old timestamps get removed. - fn typings_maintain( - &self, - room_id: &RoomId, - ) -> Result<()> { + fn typings_maintain(&self, room_id: &RoomId) -> Result<()> { self.db.typings_maintain(room_id) } From 00996dd83441abac357e27b4bd325c8ccef62e75 Mon Sep 17 00:00:00 2001 From: Nyaaori <+@nyaaori.cat> Date: Mon, 31 Oct 2022 09:31:17 +0100 Subject: [PATCH 17/56] Cargo Clippy --- src/api/client_server/search.rs | 2 +- src/database/key_value/rooms/edus/typing.rs | 3 +-- src/main.rs | 5 ++++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/api/client_server/search.rs b/src/api/client_server/search.rs index 1ba9cdf..5b634a4 100644 --- a/src/api/client_server/search.rs +++ b/src/api/client_server/search.rs @@ -103,7 +103,7 @@ pub async fn search_events_route( .take(limit) .collect(); - let next_batch = if results.len() < limit as usize { + let next_batch = if results.len() < limit { None } else { Some((skip + limit).to_string()) diff --git a/src/database/key_value/rooms/edus/typing.rs b/src/database/key_value/rooms/edus/typing.rs index d2d4306..5709192 100644 --- a/src/database/key_value/rooms/edus/typing.rs +++ b/src/database/key_value/rooms/edus/typing.rs @@ -1,5 +1,4 @@ -use std::collections::HashSet; -use std::mem; +use std::{collections::HashSet, mem}; use ruma::{OwnedUserId, RoomId, UserId}; diff --git a/src/main.rs b/src/main.rs index 695f0be..72c6d51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,7 +28,10 @@ use http::{ }; use opentelemetry::trace::{FutureExt, Tracer}; use ruma::api::{ - client::{error::Error as RumaError, error::ErrorKind, uiaa::UiaaResponse}, + client::{ + error::{Error as RumaError, ErrorKind}, + uiaa::UiaaResponse, + }, IncomingRequest, }; use tokio::signal; From 23cf39c525790122a97090b041e16b68e94644de Mon Sep 17 00:00:00 2001 From: Nyaaori <+@nyaaori.cat> Date: Mon, 31 Oct 2022 12:08:01 +0100 Subject: [PATCH 18/56] Cleanly handle invalid response from trusted server instead of panicking --- src/service/rooms/event_handler/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 477a971..3b41e86 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -1464,7 +1464,17 @@ impl Service { .write() .map_err(|_| Error::bad_database("RwLock is poisoned."))?; for k in keys.server_keys { - let k = k.deserialize().unwrap(); + let k = match k.deserialize() { + Ok(key) => key, + Err(e) => { + warn!( + "Received error {} while fetching keys from trusted server {}", + e, server + ); + warn!("{}", k.into_json()); + continue; + } + }; // TODO: Check signature from trusted server? servers.remove(&k.server_name); From b37876f3b2280cab122b46f15290979eef355ea3 Mon Sep 17 00:00:00 2001 From: Jonas Zohren Date: Sat, 29 Oct 2022 14:32:22 +0200 Subject: [PATCH 19/56] fix(ci): Only build in (remote host) docker and switch to glibc --- .dockerignore | 2 +- .gitlab-ci.yml | 359 +++++++----------------- .gitlab/setup-buildx-remote-builders.sh | 37 +++ DEPLOY.md | 40 +-- Dockerfile | 56 +++- 5 files changed, 212 insertions(+), 282 deletions(-) create mode 100644 .gitlab/setup-buildx-remote-builders.sh diff --git a/.dockerignore b/.dockerignore index 933b380..c78ddba 100644 --- a/.dockerignore +++ b/.dockerignore @@ -25,4 +25,4 @@ docker-compose* rustfmt.toml # Documentation -*.md +#*.md diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eb7a96f..91258ea 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,140 +5,10 @@ stages: - upload artifacts variables: + # Make GitLab CI go fast: GIT_SUBMODULE_STRATEGY: recursive FF_USE_FASTZIP: 1 CACHE_COMPRESSION_LEVEL: fastest - # Docker in Docker - DOCKER_HOST: tcp://docker:2375/ - DOCKER_TLS_CERTDIR: "" - DOCKER_DRIVER: overlay2 - -# --------------------------------------------------------------------- # -# Cargo: Compiling for different architectures # -# --------------------------------------------------------------------- # - -.build-cargo-shared-settings: - stage: "build" - needs: [] - rules: - - if: '$CI_COMMIT_BRANCH == "master"' - - if: '$CI_COMMIT_BRANCH == "next"' - - if: "$CI_COMMIT_TAG" - - if: '($CI_MERGE_REQUEST_APPROVED == "true") || $BUILD_EVERYTHING' # Once MR is approved, test all builds. Or if BUILD_EVERYTHING is set. - interruptible: true - image: "registry.gitlab.com/jfowl/conduit-containers/rust-with-tools@sha256:69ab327974aef4cc0daf4273579253bf7ae5e379a6c52729b83137e4caa9d093" - tags: ["docker"] - services: ["docker:dind"] - variables: - SHARED_PATH: $CI_PROJECT_DIR/shared - CARGO_PROFILE_RELEASE_LTO: "true" - CARGO_PROFILE_RELEASE_CODEGEN_UNITS: "1" - CARGO_INCREMENTAL: "false" # https://matklad.github.io/2021/09/04/fast-rust-builds.html#ci-workflow - before_script: - - 'echo "Building for target $TARGET"' - - "rustup show && rustc --version && cargo --version" # Print version info for debugging - # fix cargo and rustup mounts from this container (https://gitlab.com/gitlab-org/gitlab-foss/-/issues/41227) - - "mkdir -p $SHARED_PATH/cargo" - - "cp -r $CARGO_HOME/bin $SHARED_PATH/cargo" - - "cp -r $RUSTUP_HOME $SHARED_PATH" - - "export CARGO_HOME=$SHARED_PATH/cargo RUSTUP_HOME=$SHARED_PATH/rustup" - # If provided, bring in caching through sccache, which uses an external S3 endpoint to store compilation results. - - if [ -n "${SCCACHE_ENDPOINT}" ]; then export RUSTC_WRAPPER=/sccache; fi - script: - # cross-compile conduit for target - - 'time cross build --target="$TARGET" --locked --release' - - 'mv "target/$TARGET/release/conduit" "conduit-$TARGET"' - # print information about linking for debugging - - "file conduit-$TARGET" # print file information - - 'readelf --dynamic conduit-$TARGET | sed -e "/NEEDED/q1"' # ensure statically linked - cache: - # https://doc.rust-lang.org/cargo/guide/cargo-home.html#caching-the-cargo-home-in-ci - key: "cargo-cache-$TARGET" - paths: - - $SHARED_PATH/cargo/registry/index - - $SHARED_PATH/cargo/registry/cache - - $SHARED_PATH/cargo/git/db - artifacts: - expire_in: never - -build:release:cargo:x86_64-unknown-linux-musl-with-debug: - extends: .build-cargo-shared-settings - variables: - CARGO_PROFILE_RELEASE_DEBUG: 2 # Enable debug info for flamegraph profiling - TARGET: "x86_64-unknown-linux-musl" - after_script: - - "mv ./conduit-x86_64-unknown-linux-musl ./conduit-x86_64-unknown-linux-musl-with-debug" - artifacts: - name: "conduit-x86_64-unknown-linux-musl-with-debug" - paths: - - "conduit-x86_64-unknown-linux-musl-with-debug" - expose_as: "Conduit for x86_64-unknown-linux-musl-with-debug" - -build:release:cargo:x86_64-unknown-linux-musl: - extends: .build-cargo-shared-settings - variables: - TARGET: "x86_64-unknown-linux-musl" - artifacts: - name: "conduit-x86_64-unknown-linux-musl" - paths: - - "conduit-x86_64-unknown-linux-musl" - expose_as: "Conduit for x86_64-unknown-linux-musl" - -build:release:cargo:arm-unknown-linux-musleabihf: - extends: .build-cargo-shared-settings - variables: - TARGET: "arm-unknown-linux-musleabihf" - artifacts: - name: "conduit-arm-unknown-linux-musleabihf" - paths: - - "conduit-arm-unknown-linux-musleabihf" - expose_as: "Conduit for arm-unknown-linux-musleabihf" - -build:release:cargo:armv7-unknown-linux-musleabihf: - extends: .build-cargo-shared-settings - variables: - TARGET: "armv7-unknown-linux-musleabihf" - artifacts: - name: "conduit-armv7-unknown-linux-musleabihf" - paths: - - "conduit-armv7-unknown-linux-musleabihf" - expose_as: "Conduit for armv7-unknown-linux-musleabihf" - -build:release:cargo:aarch64-unknown-linux-musl: - extends: .build-cargo-shared-settings - variables: - TARGET: "aarch64-unknown-linux-musl" - artifacts: - name: "conduit-aarch64-unknown-linux-musl" - paths: - - "conduit-aarch64-unknown-linux-musl" - expose_as: "Conduit for aarch64-unknown-linux-musl" - -.cargo-debug-shared-settings: - extends: ".build-cargo-shared-settings" - rules: - - when: "always" - cache: - key: "build_cache--$TARGET--$CI_COMMIT_BRANCH--debug" - script: - # cross-compile conduit for target - - 'time time cross build --target="$TARGET" --locked' - - 'mv "target/$TARGET/debug/conduit" "conduit-debug-$TARGET"' - # print information about linking for debugging - - "file conduit-debug-$TARGET" # print file information - - 'readelf --dynamic conduit-debug-$TARGET | sed -e "/NEEDED/q1"' # ensure statically linked - artifacts: - expire_in: 4 weeks - -build:debug:cargo:x86_64-unknown-linux-musl: - extends: ".cargo-debug-shared-settings" - variables: - TARGET: "x86_64-unknown-linux-musl" - artifacts: - name: "conduit-debug-x86_64-unknown-linux-musl" - paths: - - "conduit-debug-x86_64-unknown-linux-musl" - expose_as: "Conduit DEBUG for x86_64-unknown-linux-musl" # --------------------------------------------------------------------- # # Create and publish docker image # @@ -146,98 +16,106 @@ build:debug:cargo:x86_64-unknown-linux-musl: .docker-shared-settings: stage: "build docker image" - image: jdrouet/docker-with-buildx:stable + image: jdrouet/docker-with-buildx:20.10.21-0.9.1 + needs: [] tags: ["docker"] + variables: + # Docker in Docker: + DOCKER_HOST: tcp://docker:2375/ + DOCKER_TLS_CERTDIR: "" + DOCKER_DRIVER: overlay2 services: - docker:dind - needs: - - "build:release:cargo:x86_64-unknown-linux-musl" - - "build:release:cargo:arm-unknown-linux-musleabihf" - - "build:release:cargo:armv7-unknown-linux-musleabihf" - - "build:release:cargo:aarch64-unknown-linux-musl" - variables: - PLATFORMS: "linux/arm/v6,linux/arm/v7,linux/arm64,linux/amd64" - DOCKER_FILE: "docker/ci-binaries-packaging.Dockerfile" - cache: - paths: - - docker_cache - key: "$CI_JOB_NAME" - before_script: - - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY - # Only log in to Dockerhub if the credentials are given: - - if [ -n "${DOCKER_HUB}" ]; then docker login -u "$DOCKER_HUB_USER" -p "$DOCKER_HUB_PASSWORD" "$DOCKER_HUB"; fi script: - # Prepare buildx to build multiarch stuff: - - docker context create 'ci-context' - - docker buildx create --name 'multiarch-builder' --use 'ci-context' - # Copy binaries to their docker arch path - - mkdir -p linux/ && mv ./conduit-x86_64-unknown-linux-musl linux/amd64 - - mkdir -p linux/arm/ && mv ./conduit-arm-unknown-linux-musleabihf linux/arm/v6 - - mkdir -p linux/arm/ && mv ./conduit-armv7-unknown-linux-musleabihf linux/arm/v7 - - mv ./conduit-aarch64-unknown-linux-musl linux/arm64 - - 'export CREATED=$(date -u +''%Y-%m-%dT%H:%M:%SZ'') && echo "Docker image creation date: $CREATED"' - # Build and push image: + - apk add openssh-client + - eval $(ssh-agent -s) + - mkdir -p ~/.ssh && chmod 700 ~/.ssh + - printf "Host *\n\tStrictHostKeyChecking no\n\n" >> ~/.ssh/config + - sh .gitlab/setup-buildx-remote-builders.sh + # Authorize against this project's own image registry: + - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY + # Build multiplatform image and push to temporary tag: - > - docker buildx build + docker buildx build + --platform "linux/arm/v7,linux/arm64,linux/amd64" --pull + --tag "$CI_REGISTRY_IMAGE/temporary-ci-images:$CI_JOB_ID" --push - --cache-from=type=local,src=$CI_PROJECT_DIR/docker_cache - --cache-to=type=local,dest=$CI_PROJECT_DIR/docker_cache - --build-arg CREATED=$CREATED - --build-arg VERSION=$(grep -m1 -o '[0-9].[0-9].[0-9]' Cargo.toml) - --build-arg "GIT_REF=$CI_COMMIT_SHORT_SHA" - --platform "$PLATFORMS" - --tag "$TAG" - --tag "$TAG-alpine" - --tag "$TAG-commit-$CI_COMMIT_SHORT_SHA" - --file "$DOCKER_FILE" . + --file "Dockerfile" . + # Build multiplatform image to deb stage and extract their .deb files: + - > + docker buildx build + --platform "linux/arm/v7,linux/arm64,linux/amd64" + --target "packager-result" + --output="type=local,dest=/tmp/build-output" + --file "Dockerfile" . + # Build multiplatform image to binary stage and extract their binaries: + - > + docker buildx build + --platform "linux/arm/v7,linux/arm64,linux/amd64" + --target "builder-result" + --output="type=local,dest=/tmp/build-output" + --file "Dockerfile" . + # Copy to GitLab container registry: + - > + docker buildx imagetools create + --tag "$CI_REGISTRY_IMAGE/$TAG" + --tag "$CI_REGISTRY_IMAGE/$TAG-bullseye" + --tag "$CI_REGISTRY_IMAGE/$TAG-commit-$CI_COMMIT_SHORT_SHA" + "$CI_REGISTRY_IMAGE/temporary-ci-images:$CI_JOB_ID" + # if DockerHub credentials exist, also copy to dockerhub: + - if [ -n "${DOCKER_HUB}" ]; then docker login -u "$DOCKER_HUB_USER" -p "$DOCKER_HUB_PASSWORD" "$DOCKER_HUB"; fi + - > + if [ -n "${DOCKER_HUB}" ]; then + docker buildx imagetools create + --tag "$DOCKER_HUB_IMAGE/$TAG" + --tag "$DOCKER_HUB_IMAGE/$TAG-bullseye" + --tag "$DOCKER_HUB_IMAGE/$TAG-commit-$CI_COMMIT_SHORT_SHA" + "$CI_REGISTRY_IMAGE/temporary-ci-images:$CI_JOB_ID" + ; fi + - mv /tmp/build-output ./ + artifacts: + paths: + - "./build-output/" -docker:next:gitlab: +docker:next: extends: .docker-shared-settings rules: - - if: '$CI_COMMIT_BRANCH == "next"' + - if: '$BUILD_SERVER_SSH_PRIVATE_KEY && $CI_COMMIT_BRANCH == "next"' variables: - TAG: "$CI_REGISTRY_IMAGE/matrix-conduit:next" + TAG: "matrix-conduit:next" -docker:next:dockerhub: +docker:master: extends: .docker-shared-settings rules: - - if: '$CI_COMMIT_BRANCH == "next" && $DOCKER_HUB' + - if: '$BUILD_SERVER_SSH_PRIVATE_KEY && $CI_COMMIT_BRANCH == "master"' variables: - TAG: "$DOCKER_HUB_IMAGE/matrixconduit/matrix-conduit:next" + TAG: "matrix-conduit:latest" -docker:master:gitlab: +docker:tags: extends: .docker-shared-settings rules: - - if: '$CI_COMMIT_BRANCH == "master"' + - if: "$BUILD_SERVER_SSH_PRIVATE_KEY && $CI_COMMIT_TAG" variables: - TAG: "$CI_REGISTRY_IMAGE/matrix-conduit:latest" + TAG: "matrix-conduit:$CI_COMMIT_TAG" -docker:master:dockerhub: - extends: .docker-shared-settings - rules: - - if: '$CI_COMMIT_BRANCH == "master" && $DOCKER_HUB' - variables: - TAG: "$DOCKER_HUB_IMAGE/matrixconduit/matrix-conduit:latest" - -docker:tags:gitlab: - extends: .docker-shared-settings - rules: - - if: "$CI_COMMIT_TAG" - variables: - TAG: "$CI_REGISTRY_IMAGE/matrix-conduit:$CI_COMMIT_TAG" - -docker:tags:dockerhub: - extends: .docker-shared-settings - rules: - - if: "$CI_COMMIT_TAG && $DOCKER_HUB" - variables: - TAG: "$DOCKER_HUB_IMAGE/matrixconduit/matrix-conduit:$CI_COMMIT_TAG" # --------------------------------------------------------------------- # # Run tests # # --------------------------------------------------------------------- # +cargo check: + stage: test + image: docker.io/rust:1.64.0-bullseye + needs: [] + interruptible: true + before_script: + - "rustup show && rustc --version && cargo --version" # Print version info for debugging + - apt-get update && apt-get -y --no-install-recommends install libclang-dev # dependency for rocksdb + script: + - cargo check + + .test-shared-settings: stage: "test" needs: [] @@ -250,8 +128,7 @@ docker:tags:dockerhub: test:cargo: extends: .test-shared-settings before_script: - # If provided, bring in caching through sccache, which uses an external S3 endpoint to store compilation results: - - if [ -n "${SCCACHE_ENDPOINT}" ]; then export RUSTC_WRAPPER=/usr/local/cargo/bin/sccache; fi + - apt-get update && apt-get -y --no-install-recommends install libclang-dev # dependency for rocksdb script: - rustc --version && cargo --version # Print version info for debugging - "cargo test --color always --workspace --verbose --locked --no-fail-fast -- -Z unstable-options --format json | gitlab-report -p test > $CI_PROJECT_DIR/report.xml" @@ -260,14 +137,12 @@ test:cargo: reports: junit: report.xml - test:clippy: extends: .test-shared-settings allow_failure: true before_script: - rustup component add clippy - # If provided, bring in caching through sccache, which uses an external S3 endpoint to store compilation results: - - if [ -n "${SCCACHE_ENDPOINT}" ]; then export RUSTC_WRAPPER=/usr/local/cargo/bin/sccache; fi + - apt-get update && apt-get -y --no-install-recommends install libclang-dev # dependency for rocksdb script: - rustc --version && cargo --version # Print version info for debugging - "cargo clippy --color always --verbose --message-format=json | gitlab-report -p clippy > $CI_PROJECT_DIR/gl-code-quality-report.json" @@ -294,38 +169,6 @@ test:audit: reports: sast: gl-sast-report.json -test:sytest: - stage: "test" - allow_failure: true - needs: - - "build:debug:cargo:x86_64-unknown-linux-musl" - image: - name: "valkum/sytest-conduit:latest" - entrypoint: [""] - tags: ["docker"] - variables: - PLUGINS: "https://github.com/valkum/sytest_conduit/archive/master.tar.gz" - interruptible: true - before_script: - - "mkdir -p /app" - - "cp ./conduit-debug-x86_64-unknown-linux-musl /app/conduit" - - "chmod +x /app/conduit" - - "rm -rf /src && ln -s $CI_PROJECT_DIR/ /src" - - "mkdir -p /work/server-0/database/ && mkdir -p /work/server-1/database/ && mkdir -p /work/server-2/database/" - - "cd /" - script: - - "SYTEST_EXIT_CODE=0" - - "/bootstrap.sh conduit || SYTEST_EXIT_CODE=1" - - 'perl /sytest/tap-to-junit-xml.pl --puretap --input /logs/results.tap --output $CI_PROJECT_DIR/sytest.xml "Sytest" && cp /logs/results.tap $CI_PROJECT_DIR/results.tap' - - "exit $SYTEST_EXIT_CODE" - artifacts: - when: always - paths: - - "$CI_PROJECT_DIR/sytest.xml" - - "$CI_PROJECT_DIR/results.tap" - reports: - junit: "$CI_PROJECT_DIR/sytest.xml" - test:dockerlint: stage: "test" needs: [] @@ -338,14 +181,12 @@ test:dockerlint: hadolint --no-fail --verbose ./Dockerfile - ./docker/ci-binaries-packaging.Dockerfile # Then output the results into a json for GitLab to pretty-print this in the MR: - > hadolint --format gitlab_codeclimate --failure-threshold error - ./Dockerfile - ./docker/ci-binaries-packaging.Dockerfile > dockerlint.json + ./Dockerfile > dockerlint.json artifacts: when: always reports: @@ -365,28 +206,26 @@ test:dockerlint: # Store binaries as package so they have download urls # # --------------------------------------------------------------------- # -publish:package: - stage: "upload artifacts" - needs: - - "build:release:cargo:x86_64-unknown-linux-musl" - - "build:release:cargo:arm-unknown-linux-musleabihf" - - "build:release:cargo:armv7-unknown-linux-musleabihf" - - "build:release:cargo:aarch64-unknown-linux-musl" - # - "build:cargo-deb:x86_64-unknown-linux-gnu" - rules: - - if: '$CI_COMMIT_BRANCH == "master"' - - if: '$CI_COMMIT_BRANCH == "next"' - - if: "$CI_COMMIT_TAG" - image: curlimages/curl:latest - tags: ["docker"] - variables: - GIT_STRATEGY: "none" # Don't need a clean copy of the code, we just operate on artifacts - script: - - 'BASE_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/conduit-${CI_COMMIT_REF_SLUG}/build-${CI_PIPELINE_ID}"' - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file conduit-x86_64-unknown-linux-musl "${BASE_URL}/conduit-x86_64-unknown-linux-musl"' - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file conduit-arm-unknown-linux-musleabihf "${BASE_URL}/conduit-arm-unknown-linux-musleabihf"' - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file conduit-armv7-unknown-linux-musleabihf "${BASE_URL}/conduit-armv7-unknown-linux-musleabihf"' - - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file conduit-aarch64-unknown-linux-musl "${BASE_URL}/conduit-aarch64-unknown-linux-musl"' +# DISABLED FOR NOW, NEEDS TO BE FIXED AT A LATER TIME: + +#publish:package: +# stage: "upload artifacts" +# needs: +# - "docker:tags" +# rules: +# - if: "$CI_COMMIT_TAG" +# image: curlimages/curl:latest +# tags: ["docker"] +# variables: +# GIT_STRATEGY: "none" # Don't need a clean copy of the code, we just operate on artifacts +# script: +# - 'BASE_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/conduit-${CI_COMMIT_REF_SLUG}/build-${CI_PIPELINE_ID}"' +# - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build-output/linux_amd64/conduit "${BASE_URL}/conduit-x86_64-unknown-linux-gnu"' +# - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build-output/linux_arm_v7/conduit "${BASE_URL}/conduit-armv7-unknown-linux-gnu"' +# - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build-output/linux_arm64/conduit "${BASE_URL}/conduit-aarch64-unknown-linux-gnu"' +# - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build-output/linux_amd64/conduit.deb "${BASE_URL}/conduit-x86_64-unknown-linux-gnu.deb"' +# - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build-output/linux_arm_v7/conduit.deb "${BASE_URL}/conduit-armv7-unknown-linux-gnu.deb"' +# - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build-output/linux_arm64/conduit.deb "${BASE_URL}/conduit-aarch64-unknown-linux-gnu.deb"' # Avoid duplicate pipelines # See: https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines diff --git a/.gitlab/setup-buildx-remote-builders.sh b/.gitlab/setup-buildx-remote-builders.sh new file mode 100644 index 0000000..29d50dd --- /dev/null +++ b/.gitlab/setup-buildx-remote-builders.sh @@ -0,0 +1,37 @@ +#!/bin/sh +set -eux + +# --------------------------------------------------------------------- # +# # +# Configures docker buildx to use a remote server for arm building. # +# Expects $SSH_PRIVATE_KEY to be a valid ssh ed25519 private key with # +# access to the server $ARM_SERVER_USER@$ARM_SERVER_IP # +# # +# This is expected to only be used in the official CI/CD pipeline! # +# # +# Requirements: openssh-client, docker buildx # +# Inspired by: https://depot.dev/blog/building-arm-containers # +# # +# --------------------------------------------------------------------- # + +cat "$BUILD_SERVER_SSH_PRIVATE_KEY" | ssh-add - + +# Test server connections: +ssh "$ARM_SERVER_USER@$ARM_SERVER_IP" "uname -a" +ssh "$AMD_SERVER_USER@$AMD_SERVER_IP" "uname -a" + +# Connect remote arm64 server for all arm builds: +docker buildx create \ + --name "multi" \ + --driver "docker-container" \ + --platform "linux/arm64,linux/arm/v7" \ + "ssh://$ARM_SERVER_USER@$ARM_SERVER_IP" + +# Connect remote amd64 server for adm64 builds: +docker buildx create --append \ + --name "multi" \ + --driver "docker-container" \ + --platform "linux/amd64" \ + "ssh://$AMD_SERVER_USER@$AMD_SERVER_IP" + +docker buildx use multi diff --git a/DEPLOY.md b/DEPLOY.md index 1c7d1af..a2f93b1 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -12,21 +12,27 @@ only offer Linux binaries. You may simply download the binary that fits your machine. Run `uname -m` to see what you need. Now copy the right url: -| CPU Architecture | Download stable version | Download development version | -| ------------------------------------------- | ------------------------------ | ---------------------------- | -| x84_64 / amd64 (Most servers and computers) | [Download][x84_64-musl-master] | [Download][x84_64-musl-next] | -| armv6 | [Download][armv6-musl-master] | [Download][armv6-musl-next] | -| armv7 (e.g. Raspberry Pi by default) | [Download][armv7-musl-master] | [Download][armv7-musl-next] | -| armv8 / aarch64 | [Download][armv8-musl-master] | [Download][armv8-musl-next] | +| CPU Architecture | Download stable version | Download development version | +| ------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------- | +| x84_64 / amd64 (Most servers and computers) | [Binary][x84_64-glibc-master] / [.deb][x84_64-glibc-master-deb] | [Binary][x84_64-glibc-next] / [.deb][x84_64-glibc-next-deb] | +| armv7 (e.g. Raspberry Pi by default) | [Binary][armv7-glibc-master] / [.deb][armv7-glibc-master-deb] | [Binary][armv7-glibc-next] / [.deb][armv7-glibc-next-deb] | +| armv8 / aarch64 | [Binary][armv8-glibc-master] / [.deb][armv8-glibc-master-deb] | [Binary][armv8-glibc-next] / [.deb][armv8-glibc-next-deb] | -[x84_64-musl-master]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/conduit-x86_64-unknown-linux-musl?job=build:release:cargo:x86_64-unknown-linux-musl -[armv6-musl-master]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/conduit-arm-unknown-linux-musleabihf?job=build:release:cargo:arm-unknown-linux-musleabihf -[armv7-musl-master]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/conduit-armv7-unknown-linux-musleabihf?job=build:release:cargo:armv7-unknown-linux-musleabihf -[armv8-musl-master]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/conduit-aarch64-unknown-linux-musl?job=build:release:cargo:aarch64-unknown-linux-musl -[x84_64-musl-next]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/conduit-x86_64-unknown-linux-musl?job=build:release:cargo:x86_64-unknown-linux-musl -[armv6-musl-next]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/conduit-arm-unknown-linux-musleabihf?job=build:release:cargo:arm-unknown-linux-musleabihf -[armv7-musl-next]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/conduit-armv7-unknown-linux-musleabihf?job=build:release:cargo:armv7-unknown-linux-musleabihf -[armv8-musl-next]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/conduit-aarch64-unknown-linux-musl?job=build:release:cargo:aarch64-unknown-linux-musl +These builds were created on and linked against the glibc version shipped with Debian bullseye. +If you use a system with an older glibc version, you might need to compile Conduit yourself. + +[x84_64-glibc-master]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/build-output/linux_amd64/conduit?job=docker:master +[armv7-glibc-master]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/build-output/linux_arm_v7/conduit?job=docker:master +[armv8-glibc-master]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/build-output/linux_arm64/conduit?job=docker:master +[x84_64-glibc-next]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/build-output/linux_amd64/conduit?job=docker:next +[armv7-glibc-next]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/build-output/linux_arm_v7/conduit?job=docker:next +[armv8-glibc-next]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/build-output/linux_arm64/conduit?job=docker:next +[x84_64-glibc-master-deb]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/build-output/linux_amd64/conduit.deb?job=docker:master +[armv7-glibc-master-deb]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/build-output/linux_arm_v7/conduit.deb?job=docker:master +[armv8-glibc-master-deb]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/master/raw/build-output/linux_arm64/conduit.deb?job=docker:master +[x84_64-glibc-next-deb]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/build-output/linux_amd64/conduit.deb?job=docker:next +[armv7-glibc-next-deb]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/build-output/linux_arm_v7/conduit.deb?job=docker:next +[armv8-glibc-next-deb]: https://gitlab.com/famedly/conduit/-/jobs/artifacts/next/raw/build-output/linux_arm64/conduit.deb?job=docker:next ```bash $ sudo wget -O /usr/local/bin/matrix-conduit @@ -43,7 +49,6 @@ $ sudo apt install libclang-dev build-essential $ cargo build --release ``` - If you want to cross compile Conduit to another architecture, read the [Cross-Compile Guide](cross/README.md). ## Adding a Conduit user @@ -189,18 +194,21 @@ $ sudo systemctl reload apache2 ``` ### Caddy + Create `/etc/caddy/conf.d/conduit_caddyfile` and enter this (substitute for your server name). + ```caddy your.server.name, your.server.name:8448 { reverse_proxy /_matrix/* 127.0.0.1:6167 } ``` + That's it! Just start or enable the service and you're set. + ```bash $ sudo systemctl enable caddy ``` - ### Nginx If you use Nginx and not Apache, add the following server section inside the http section of `/etc/nginx/nginx.conf` diff --git a/Dockerfile b/Dockerfile index 3154ebb..2763b12 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM docker.io/rust:1.63-bullseye AS builder +FROM docker.io/rust:1.64-bullseye AS builder WORKDIR /usr/src/conduit # Install required packages to build Conduit and it's dependencies @@ -27,6 +27,49 @@ COPY src src # Builds conduit and places the binary at /usr/src/conduit/target/release/conduit RUN touch src/main.rs && touch src/lib.rs && cargo build --release + +# ONLY USEFUL FOR CI: target stage to extract build artifacts +FROM scratch AS builder-result +COPY --from=builder /usr/src/conduit/target/release/conduit /conduit + + + +# --------------------------------------------------------------------------------------------------------------- +# Build cargo-deb, a tool to package up rust binaries into .deb packages for Debian/Ubuntu based systems: +# --------------------------------------------------------------------------------------------------------------- +FROM docker.io/rust:1.64-bullseye AS build-cargo-deb + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + dpkg \ + dpkg-dev \ + liblzma-dev + +RUN cargo install cargo-deb +# => binary is in /usr/local/cargo/bin/cargo-deb + + +# --------------------------------------------------------------------------------------------------------------- +# Package conduit build-result into a .deb package: +# --------------------------------------------------------------------------------------------------------------- +FROM builder AS packager +WORKDIR /usr/src/conduit + +COPY ./LICENSE ./LICENSE +COPY ./README.md ./README.md +COPY debian/README.Debian ./debian/ +COPY --from=build-cargo-deb /usr/local/cargo/bin/cargo-deb /usr/local/cargo/bin/cargo-deb + +# --no-build makes cargo-deb reuse already compiled project +RUN cargo deb --no-build +# => Package is in /usr/src/conduit/target/debian/__.deb + + +# ONLY USEFUL FOR CI: target stage to extract build artifacts +FROM scratch AS packager-result +COPY --from=packager /usr/src/conduit/target/debian/*.deb /conduit.deb + + # --------------------------------------------------------------------------------------------------------------- # Stuff below this line actually ends up in the resulting docker image # --------------------------------------------------------------------------------------------------------------- @@ -45,9 +88,11 @@ ENV CONDUIT_PORT=6167 \ # └─> Set no config file to do all configuration with env vars # Conduit needs: +# dpkg: to install conduit.deb # ca-certificates: for https # iproute2 & wget: for the healthcheck script RUN apt-get update && apt-get -y --no-install-recommends install \ + dpkg \ ca-certificates \ iproute2 \ wget \ @@ -57,8 +102,9 @@ RUN apt-get update && apt-get -y --no-install-recommends install \ COPY ./docker/healthcheck.sh /srv/conduit/healthcheck.sh HEALTHCHECK --start-period=5s --interval=5s CMD ./healthcheck.sh -# Copy over the actual Conduit binary from the builder stage -COPY --from=builder /usr/src/conduit/target/release/conduit /srv/conduit/conduit +# Install conduit.deb: +COPY --from=packager /usr/src/conduit/target/debian/*.deb /srv/conduit/ +RUN dpkg -i /srv/conduit/*.deb # Improve security: Don't run stuff as root, that does not need to run as root # Most distros also use 1000:1000 for the first real user, so this should resolve volume mounting problems. @@ -73,7 +119,7 @@ RUN chown -cR conduit:conduit /srv/conduit && \ chmod +x /srv/conduit/healthcheck.sh && \ mkdir -p ${DEFAULT_DB_PATH} && \ chown -cR conduit:conduit ${DEFAULT_DB_PATH} - + # Change user to conduit, no root permissions afterwards: USER conduit # Set container home directory @@ -81,4 +127,4 @@ WORKDIR /srv/conduit # Run Conduit and print backtraces on panics ENV RUST_BACKTRACE=1 -ENTRYPOINT [ "/srv/conduit/conduit" ] +ENTRYPOINT [ "/usr/sbin/matrix-conduit" ] From a2d8aec1e3a1578872f1caaee719d3acfa5227bc Mon Sep 17 00:00:00 2001 From: Paul Beziau Date: Thu, 3 Nov 2022 13:12:53 +0000 Subject: [PATCH 20/56] Moving the unwraping of a variable Moving the unwraping of the variable "rule" inside the condition instead of the if body, for the migration of the database from version 11 to 12. --- src/database/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index ccc8177..f6a76c6 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -851,8 +851,8 @@ impl KeyValueDatabase { for transformation in underride_rule_transformation { let rule = rules_list.underride.get(transformation[0]); - if rule.is_some() { - let mut rule = rule.unwrap().clone(); + if let Some(rule) = rule { + let mut rule = rule.clone(); rule.rule_id = transformation[1].to_string(); rules_list.underride.remove(transformation[0]); rules_list.underride.insert(rule); From 09015f113ce19280825e54e98d8c5b92b54a03bb Mon Sep 17 00:00:00 2001 From: Ticho 34782694 Date: Tue, 8 Nov 2022 15:56:24 +0000 Subject: [PATCH 21/56] Describe a better way to enforce Content-Type in nginx add_header will not override the Content-Type header set by the server, but will instead add another header below, which is obviously not ideal. The proposed change will instead tell nginx to set the correct value for this header straight away. --- docker/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/README.md b/docker/README.md index 36717c4..c702832 100644 --- a/docker/README.md +++ b/docker/README.md @@ -121,12 +121,12 @@ So...step by step: location /.well-known/matrix/server { return 200 '{"m.server": ".:443"}'; - add_header Content-Type application/json; + types { } default_type "application/json; charset=utf-8"; } location /.well-known/matrix/client { return 200 '{"m.homeserver": {"base_url": "https://."}}'; - add_header Content-Type application/json; + types { } default_type "application/json; charset=utf-8"; add_header "Access-Control-Allow-Origin" *; } From 75402273882d4641771d5edde7ed8b498eafcb07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 9 Nov 2022 18:46:10 +0100 Subject: [PATCH 22/56] chore: bump dependencies --- Cargo.lock | 357 +++++++++++++++++++------------ Cargo.toml | 2 +- src/api/client_server/push.rs | 5 +- src/api/server_server.rs | 1 + src/database/key_value/pusher.rs | 51 +++-- src/main.rs | 2 +- src/service/pusher/data.rs | 9 +- src/service/pusher/mod.rs | 156 +++++++------- 8 files changed, 333 insertions(+), 250 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bdadf71..71524af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", "once_cell", "version_check", ] @@ -83,9 +83,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" dependencies = [ "proc-macro2", "quote", @@ -157,9 +157,9 @@ dependencies = [ [[package]] name = "axum-server" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba6170b61f7b086609dabcae68d2e07352539c6ef04a7c82980bdfa01a159d" +checksum = "8456dab8f11484979a86651da8e619b355ede5d61a160755155f6c344bd18c47" dependencies = [ "arc-swap", "bytes", @@ -177,15 +177,15 @@ dependencies = [ [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64ct" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2b2456fd614d856680dcd9fcc660a51a820fa09daef2e49772b56a193c8474" +checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" [[package]] name = "bincode" @@ -273,15 +273,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytemuck" -version = "1.12.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f5715e491b5a1598fc2bef5a606847b5dc1d48ea625bd3c02c00de8285591da" +checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" [[package]] name = "byteorder" @@ -297,9 +297,9 @@ checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" [[package]] name = "cc" -version = "1.0.73" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" dependencies = [ "jobserver", ] @@ -332,9 +332,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.0.11" +version = "4.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ed45cc2c62a3eff523e718d8576ba762c83a3146151093283ac62ae11933a73" +checksum = "91b9970d7505127a162fdaa9b96428d28a479ba78c9ec7550a63a5d9863db682" dependencies = [ "bitflags", "clap_derive", @@ -344,9 +344,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.0.10" +version = "4.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db342ce9fda24fb191e2ed4e102055a4d381c1086a06630174cd8da8d5d917ce" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" dependencies = [ "heck", "proc-macro-error", @@ -712,7 +712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.5.4", ] [[package]] @@ -748,9 +748,9 @@ checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" [[package]] name = "futures" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" dependencies = [ "futures-channel", "futures-core", @@ -763,9 +763,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", "futures-sink", @@ -773,15 +773,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" [[package]] name = "futures-executor" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" dependencies = [ "futures-core", "futures-task", @@ -790,15 +790,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68" +checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" [[package]] name = "futures-macro" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" dependencies = [ "proc-macro2", "quote", @@ -807,21 +807,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" [[package]] name = "futures-task" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" [[package]] name = "futures-util" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ "futures-channel", "futures-core", @@ -858,9 +858,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", @@ -885,9 +885,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "h2" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" +checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" dependencies = [ "bytes", "fnv", @@ -1058,9 +1058,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.20" +version = "0.14.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" dependencies = [ "bytes", "futures-channel", @@ -1167,9 +1167,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" [[package]] name = "itertools" @@ -1242,6 +1242,28 @@ dependencies = [ "simple_asn1", ] +[[package]] +name = "konst" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330f0e13e6483b8c34885f7e6c9f19b1a7bd449c673fbb948a51c99d66ef74f4" +dependencies = [ + "konst_macro_rules", + "konst_proc_macros", +] + +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + +[[package]] +name = "konst_proc_macros" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "984e109462d46ad18314f10e392c286c3d47bce203088a09012de1015b45b737" + [[package]] name = "lazy_static" version = "1.4.0" @@ -1256,15 +1278,15 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.134" +version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329c933548736bc49fd575ee68c89e8be4d260064184389a5b77517cddd99ffb" +checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" [[package]] name = "libloading" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if", "winapi", @@ -1284,9 +1306,9 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f0455f2c1bc9a7caa792907026e469c1d91761fb0ea37cbb16427c77280cf35" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" dependencies = [ "cc", "pkg-config", @@ -1408,15 +1430,24 @@ dependencies = [ ] [[package]] -name = "mio" -version = "0.8.4" +name = "miniz_oxide" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1482,28 +1513,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ "hermit-abi", "libc", ] -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] - [[package]] name = "once_cell" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" [[package]] name = "opaque-debug" @@ -1599,9 +1621,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.3.0" +version = "6.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" +checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9" [[package]] name = "overload" @@ -1631,15 +1653,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -1752,27 +1774,27 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "png" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0e7f4c94ec26ff209cee506314212639d6c91b80afb82984819fafce9df01c" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" dependencies = [ "bitflags", "crc32fast", "flate2", - "miniz_oxide", + "miniz_oxide 0.6.2", ] [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" @@ -1811,9 +1833,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" dependencies = [ "unicode-ident", ] @@ -1905,7 +1927,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", ] [[package]] @@ -1932,16 +1954,16 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", "redox_syscall", "thiserror", ] [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -1959,9 +1981,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "reqwest" @@ -2039,7 +2061,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.7.4" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "assign", "js_int", @@ -2057,8 +2079,9 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.7.0" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ + "js_int", "ruma-common", "serde", "serde_json", @@ -2066,13 +2089,14 @@ dependencies = [ [[package]] name = "ruma-client-api" -version = "0.15.1" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +version = "0.15.3" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "assign", "bytes", "http", "js_int", + "js_option", "maplit", "percent-encoding", "ruma-common", @@ -2082,8 +2106,8 @@ dependencies = [ [[package]] name = "ruma-common" -version = "0.10.3" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +version = "0.10.5" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "base64", "bytes", @@ -2093,6 +2117,7 @@ dependencies = [ "itoa", "js_int", "js_option", + "konst", "percent-encoding", "rand 0.8.5", "regex", @@ -2110,7 +2135,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "js_int", "ruma-common", @@ -2121,7 +2146,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "js_int", "thiserror", @@ -2130,7 +2155,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "js_int", "ruma-common", @@ -2139,8 +2164,8 @@ dependencies = [ [[package]] name = "ruma-macros" -version = "0.10.3" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +version = "0.10.5" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "once_cell", "proc-macro-crate", @@ -2155,7 +2180,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "js_int", "ruma-common", @@ -2166,7 +2191,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.12.0" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "base64", "ed25519-dalek", @@ -2182,7 +2207,7 @@ dependencies = [ [[package]] name = "ruma-state-res" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=fba6f70c2df8294f96567f56464a46e3d237a8e9#fba6f70c2df8294f96567f56464a46e3d237a8e9" +source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" dependencies = [ "itertools", "js_int", @@ -2227,9 +2252,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustls" -version = "0.20.6" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" dependencies = [ "log", "ring", @@ -2280,7 +2305,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.36.1", ] [[package]] @@ -2324,18 +2349,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", @@ -2344,9 +2369,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" dependencies = [ "itoa", "ryu", @@ -2367,9 +2392,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.13" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8613d593412a0deb7bbd8de9d908efff5a0cb9ccd8f62c641e7b2ed2f57291d1" +checksum = "6d232d893b10de3eb7258ff01974d6ee20663d8e833263c99409d4b13a0209da" dependencies = [ "indexmap", "itoa", @@ -2513,9 +2538,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" +checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" dependencies = [ "proc-macro2", "quote", @@ -2634,21 +2659,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ "itoa", - "libc", - "num_threads", + "serde", + "time-core", "time-macros", ] [[package]] -name = "time-macros" -version = "0.2.4" +name = "time-core" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] [[package]] name = "tinyvec" @@ -2720,9 +2754,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6edf2d6bc038a43d31353570e27270603f4648d18f5ed10c0e179abe43255af" +checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" dependencies = [ "futures-core", "pin-project-lite", @@ -2793,9 +2827,9 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" [[package]] name = "tower-service" @@ -3005,7 +3039,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.8", ] [[package]] @@ -3180,43 +3214,100 @@ version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" + [[package]] name = "windows_aarch64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" + [[package]] name = "windows_i686_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +[[package]] +name = "windows_i686_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" + [[package]] name = "windows_i686_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +[[package]] +name = "windows_i686_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" + [[package]] name = "windows_x86_64_gnu" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" + [[package]] name = "windows_x86_64_msvc" version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" + [[package]] name = "winreg" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index db51f4a..588b443 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ tower-http = { version = "0.3.4", features = ["add-extension", "cors", "compress # Used for matrix spec type definitions and helpers #ruma = { version = "0.4.0", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } -ruma = { git = "https://github.com/ruma/ruma", rev = "fba6f70c2df8294f96567f56464a46e3d237a8e9", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "2bd5c131f49b2239750c39ed63b623cd5a01c965", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "50c1db7e0a3a21fc794b0cce3b64285a4c750c71", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } diff --git a/src/api/client_server/push.rs b/src/api/client_server/push.rs index 2301ddc..dc936a6 100644 --- a/src/api/client_server/push.rs +++ b/src/api/client_server/push.rs @@ -575,9 +575,10 @@ pub async fn set_pushers_route( body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - let pusher = body.pusher.clone(); - services().pusher.set_pusher(sender_user, pusher)?; + services() + .pusher + .set_pusher(sender_user, body.action.clone())?; Ok(set_pusher::v3::Response::default()) } diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 320e396..f66e96c 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -1478,6 +1478,7 @@ async fn create_join_event( .filter_map(|(_, id)| services().rooms.timeline.get_pdu_json(id).ok().flatten()) .map(PduEvent::convert_to_outgoing_federation_event) .collect(), + event: None, // TODO: handle restricted joins }) } diff --git a/src/database/key_value/pusher.rs b/src/database/key_value/pusher.rs index 3dfceb6..b203107 100644 --- a/src/database/key_value/pusher.rs +++ b/src/database/key_value/pusher.rs @@ -1,38 +1,37 @@ use ruma::{ - api::client::push::{get_pushers, set_pusher}, + api::client::push::{set_pusher, Pusher}, UserId, }; use crate::{database::KeyValueDatabase, service, utils, Error, Result}; impl service::pusher::Data for KeyValueDatabase { - fn set_pusher(&self, sender: &UserId, pusher: set_pusher::v3::Pusher) -> Result<()> { - let mut key = sender.as_bytes().to_vec(); - key.push(0xff); - key.extend_from_slice(pusher.pushkey.as_bytes()); - - // There are 2 kinds of pushers but the spec says: null deletes the pusher. - if pusher.kind.is_none() { - return self - .senderkey_pusher - .remove(&key) - .map(|_| ()) - .map_err(Into::into); + fn set_pusher(&self, sender: &UserId, pusher: set_pusher::v3::PusherAction) -> Result<()> { + match &pusher { + set_pusher::v3::PusherAction::Post(data) => { + let mut key = sender.as_bytes().to_vec(); + key.push(0xff); + key.extend_from_slice(data.pusher.ids.pushkey.as_bytes()); + self.senderkey_pusher.insert( + &key, + &serde_json::to_vec(&pusher).expect("Pusher is valid JSON value"), + )?; + Ok(()) + } + set_pusher::v3::PusherAction::Delete(ids) => { + let mut key = sender.as_bytes().to_vec(); + key.push(0xff); + key.extend_from_slice(ids.pushkey.as_bytes()); + return self + .senderkey_pusher + .remove(&key) + .map(|_| ()) + .map_err(Into::into); + } } - - self.senderkey_pusher.insert( - &key, - &serde_json::to_vec(&pusher).expect("Pusher is valid JSON value"), - )?; - - Ok(()) } - fn get_pusher( - &self, - sender: &UserId, - pushkey: &str, - ) -> Result> { + fn get_pusher(&self, sender: &UserId, pushkey: &str) -> Result> { let mut senderkey = sender.as_bytes().to_vec(); senderkey.push(0xff); senderkey.extend_from_slice(pushkey.as_bytes()); @@ -46,7 +45,7 @@ impl service::pusher::Data for KeyValueDatabase { .transpose() } - fn get_pushers(&self, sender: &UserId) -> Result> { + fn get_pushers(&self, sender: &UserId) -> Result> { let mut prefix = sender.as_bytes().to_vec(); prefix.push(0xff); diff --git a/src/main.rs b/src/main.rs index 72c6d51..d2183a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -473,7 +473,7 @@ macro_rules! impl_ruma_handler { let meta = Req::METADATA; let method_filter = method_to_filter(meta.method); - for path in IntoIterator::into_iter([meta.unstable_path, meta.r0_path, meta.stable_path]).flatten() { + for path in meta.history.all_paths() { let handler = self.clone(); router = router.route(path, on(method_filter, |$( $ty: $ty, )* req| async move { diff --git a/src/service/pusher/data.rs b/src/service/pusher/data.rs index e317121..2062f56 100644 --- a/src/service/pusher/data.rs +++ b/src/service/pusher/data.rs @@ -1,16 +1,15 @@ use crate::Result; use ruma::{ - api::client::push::{get_pushers, set_pusher}, + api::client::push::{set_pusher, Pusher}, UserId, }; pub trait Data: Send + Sync { - fn set_pusher(&self, sender: &UserId, pusher: set_pusher::v3::Pusher) -> Result<()>; + fn set_pusher(&self, sender: &UserId, pusher: set_pusher::v3::PusherAction) -> Result<()>; - fn get_pusher(&self, sender: &UserId, pushkey: &str) - -> Result>; + fn get_pusher(&self, sender: &UserId, pushkey: &str) -> Result>; - fn get_pushers(&self, sender: &UserId) -> Result>; + fn get_pushers(&self, sender: &UserId) -> Result>; fn get_pushkeys<'a>(&'a self, sender: &UserId) -> Box> + 'a>; diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index 7fee276..cd11d71 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -6,7 +6,7 @@ use crate::{services, Error, PduEvent, Result}; use bytes::BytesMut; use ruma::{ api::{ - client::push::{get_pushers, set_pusher, PusherKind}, + client::push::{set_pusher, Pusher, PusherKind}, push_gateway::send_event_notification::{ self, v1::{Device, Notification, NotificationCounts, NotificationPriority}, @@ -23,26 +23,22 @@ use ruma::{ }; use std::{fmt::Debug, mem}; -use tracing::{error, info, warn}; +use tracing::{info, warn}; pub struct Service { pub db: &'static dyn Data, } impl Service { - pub fn set_pusher(&self, sender: &UserId, pusher: set_pusher::v3::Pusher) -> Result<()> { + pub fn set_pusher(&self, sender: &UserId, pusher: set_pusher::v3::PusherAction) -> Result<()> { self.db.set_pusher(sender, pusher) } - pub fn get_pusher( - &self, - sender: &UserId, - pushkey: &str, - ) -> Result> { + pub fn get_pusher(&self, sender: &UserId, pushkey: &str) -> Result> { self.db.get_pusher(sender, pushkey) } - pub fn get_pushers(&self, sender: &UserId) -> Result> { + pub fn get_pushers(&self, sender: &UserId) -> Result> { self.db.get_pushers(sender) } @@ -140,7 +136,7 @@ impl Service { &self, user: &UserId, unread: UInt, - pusher: &get_pushers::v3::Pusher, + pusher: &Pusher, ruleset: Ruleset, pdu: &PduEvent, ) -> Result<()> { @@ -221,91 +217,87 @@ impl Service { async fn send_notice( &self, unread: UInt, - pusher: &get_pushers::v3::Pusher, + pusher: &Pusher, tweaks: Vec, event: &PduEvent, ) -> Result<()> { // TODO: email - if pusher.kind == PusherKind::Email { - return Ok(()); - } + match &pusher.kind { + PusherKind::Http(http) => { + // TODO: + // Two problems with this + // 1. if "event_id_only" is the only format kind it seems we should never add more info + // 2. can pusher/devices have conflicting formats + let event_id_only = http.format == Some(PushFormat::EventIdOnly); - // TODO: - // Two problems with this - // 1. if "event_id_only" is the only format kind it seems we should never add more info - // 2. can pusher/devices have conflicting formats - let event_id_only = pusher.data.format == Some(PushFormat::EventIdOnly); - let url = if let Some(url) = &pusher.data.url { - url - } else { - error!("Http Pusher must have URL specified."); - return Ok(()); - }; + let mut device = Device::new(pusher.ids.app_id.clone(), pusher.ids.pushkey.clone()); + device.data.default_payload = http.default_payload.clone(); + device.data.format = http.format.clone(); - let mut device = Device::new(pusher.app_id.clone(), pusher.pushkey.clone()); - let mut data_minus_url = pusher.data.clone(); - // The url must be stripped off according to spec - data_minus_url.url = None; - device.data = data_minus_url.into(); + // Tweaks are only added if the format is NOT event_id_only + if !event_id_only { + device.tweaks = tweaks.clone(); + } - // Tweaks are only added if the format is NOT event_id_only - if !event_id_only { - device.tweaks = tweaks.clone(); - } + let d = &[device]; + let mut notifi = Notification::new(d); - let d = &[device]; - let mut notifi = Notification::new(d); + notifi.prio = NotificationPriority::Low; + notifi.event_id = Some(&event.event_id); + notifi.room_id = Some(&event.room_id); + // TODO: missed calls + notifi.counts = NotificationCounts::new(unread, uint!(0)); - notifi.prio = NotificationPriority::Low; - notifi.event_id = Some(&event.event_id); - notifi.room_id = Some(&event.room_id); - // TODO: missed calls - notifi.counts = NotificationCounts::new(unread, uint!(0)); + if event.kind == RoomEventType::RoomEncrypted + || tweaks + .iter() + .any(|t| matches!(t, Tweak::Highlight(true) | Tweak::Sound(_))) + { + notifi.prio = NotificationPriority::High + } - if event.kind == RoomEventType::RoomEncrypted - || tweaks - .iter() - .any(|t| matches!(t, Tweak::Highlight(true) | Tweak::Sound(_))) - { - notifi.prio = NotificationPriority::High - } + if event_id_only { + self.send_request(&http.url, send_event_notification::v1::Request::new(notifi)) + .await?; + } else { + notifi.sender = Some(&event.sender); + notifi.event_type = Some(&event.kind); + let content = serde_json::value::to_raw_value(&event.content).ok(); + notifi.content = content.as_deref(); - if event_id_only { - self.send_request(url, send_event_notification::v1::Request::new(notifi)) - .await?; - } else { - notifi.sender = Some(&event.sender); - notifi.event_type = Some(&event.kind); - let content = serde_json::value::to_raw_value(&event.content).ok(); - notifi.content = content.as_deref(); + if event.kind == RoomEventType::RoomMember { + notifi.user_is_target = + event.state_key.as_deref() == Some(event.sender.as_str()); + } - if event.kind == RoomEventType::RoomMember { - notifi.user_is_target = event.state_key.as_deref() == Some(event.sender.as_str()); + let user_name = services().users.displayname(&event.sender)?; + notifi.sender_display_name = user_name.as_deref(); + + let room_name = if let Some(room_name_pdu) = services() + .rooms + .state_accessor + .room_state_get(&event.room_id, &StateEventType::RoomName, "")? + { + serde_json::from_str::(room_name_pdu.content.get()) + .map_err(|_| { + Error::bad_database("Invalid room name event in database.") + })? + .name + } else { + None + }; + + notifi.room_name = room_name.as_deref(); + + self.send_request(&http.url, send_event_notification::v1::Request::new(notifi)) + .await?; + } + + Ok(()) } - - let user_name = services().users.displayname(&event.sender)?; - notifi.sender_display_name = user_name.as_deref(); - - let room_name = if let Some(room_name_pdu) = services() - .rooms - .state_accessor - .room_state_get(&event.room_id, &StateEventType::RoomName, "")? - { - serde_json::from_str::(room_name_pdu.content.get()) - .map_err(|_| Error::bad_database("Invalid room name event in database."))? - .name - } else { - None - }; - - notifi.room_name = room_name.as_deref(); - - self.send_request(url, send_event_notification::v1::Request::new(notifi)) - .await?; + // TODO: Handle email + PusherKind::Email(_) => return Ok(()), + _ => return Ok(()), } - - // TODO: email - - Ok(()) } } From c063700255e0e6bc4637981709ad4835319b75df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 9 Nov 2022 21:14:17 +0100 Subject: [PATCH 23/56] fix: invite dendrite users --- src/api/client_server/membership.rs | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 7142b8e..397e13c 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -826,7 +826,7 @@ pub(crate) async fn invite_helper<'a>( is_direct: bool, ) -> Result<()> { if user_id.server_name() != services().globals.server_name() { - let (pdu_json, invite_room_state) = { + let (pdu, pdu_json, invite_room_state) = { let mutex_state = Arc::clone( services() .globals @@ -867,28 +867,16 @@ pub(crate) async fn invite_helper<'a>( drop(state_lock); - (pdu_json, invite_room_state) + (pdu, pdu_json, invite_room_state) }; - // Generate event id - let expected_event_id = format!( - "${}", - ruma::signatures::reference_hash( - &pdu_json, - &services().rooms.state.get_room_version(room_id)? - ) - .expect("ruma can calculate reference hashes") - ); - let expected_event_id = <&EventId>::try_from(expected_event_id.as_str()) - .expect("ruma's reference hashes are valid event ids"); - let response = services() .sending .send_federation_request( user_id.server_name(), create_invite::v2::Request { room_id, - event_id: expected_event_id, + event_id: &pdu.event_id, room_version: &services().rooms.state.get_room_version(room_id)?, event: &PduEvent::convert_to_outgoing_federation_event(pdu_json.clone()), invite_room_state: &invite_room_state, @@ -910,7 +898,7 @@ pub(crate) async fn invite_helper<'a>( } }; - if expected_event_id != event_id { + if pdu.event_id != event_id { warn!("Server {} changed invite event, that's not allowed in the spec: ours: {:?}, theirs: {:?}", user_id.server_name(), pdu_json, value); } From 3b3c451c83ade05a1259c6666964d96b9eba1f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sat, 19 Nov 2022 12:52:47 +0100 Subject: [PATCH 24/56] fix: unable to leave room --- src/api/client_server/membership.rs | 39 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 397e13c..2267cbf 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -1051,19 +1051,32 @@ pub async fn leave_room(user_id: &UserId, room_id: &RoomId) -> Result<()> { ); let state_lock = mutex_state.lock().await; - let mut event: RoomMemberEventContent = serde_json::from_str( - services() - .rooms - .state_accessor - .room_state_get(room_id, &StateEventType::RoomMember, user_id.as_str())? - .ok_or(Error::BadRequest( - ErrorKind::BadState, - "Cannot leave a room you are not a member of.", - ))? - .content - .get(), - ) - .map_err(|_| Error::bad_database("Invalid member event in database."))?; + let member_event = services().rooms.state_accessor.room_state_get( + room_id, + &StateEventType::RoomMember, + user_id.as_str(), + )?; + + // Fix for broken rooms + let member_event = match member_event { + None => { + error!("Trying to leave a room you are not a member of."); + + services().rooms.state_cache.update_membership( + room_id, + user_id, + MembershipState::Leave, + user_id, + None, + true, + )?; + return Ok(()); + } + Some(e) => e, + }; + + let mut event: RoomMemberEventContent = serde_json::from_str(member_event.content.get()) + .map_err(|_| Error::bad_database("Invalid member event in database."))?; event.membership = MembershipState::Leave; From a3a1db124d2fdf78999b493e51dceb344683b502 Mon Sep 17 00:00:00 2001 From: "Andriy Kushnir (Orhideous)" Date: Mon, 21 Nov 2022 21:48:06 +0200 Subject: [PATCH 25/56] Clean some noisy logs --- src/api/server_server.rs | 4 ++-- src/service/rooms/event_handler/mod.rs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/api/server_server.rs b/src/api/server_server.rs index f66e96c..b7f8807 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -55,7 +55,7 @@ use std::{ time::{Duration, Instant, SystemTime}, }; -use tracing::{error, info, warn}; +use tracing::{debug, error, info, warn}; /// Wraps either an literal IP address plus port, or a hostname plus complement /// (colon-plus-port if it was specified). @@ -724,7 +724,7 @@ pub async fn send_transaction_message_route( drop(mutex_lock); let elapsed = start_time.elapsed(); - warn!( + debug!( "Handling transaction of event {} took {}m{}s", event_id, elapsed.as_secs() / 60, diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 3b41e86..03f1f93 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -133,7 +133,8 @@ impl Service { .await?; let mut errors = 0; - for prev_id in dbg!(sorted_prev_events) { + debug!(events = ?sorted_prev_events, "Got previous events"); + for prev_id in sorted_prev_events { // Check for disabled again because it might have changed if services().rooms.metadata.is_disabled(room_id)? { return Err(Error::BadRequest( @@ -330,7 +331,7 @@ impl Service { // 4. fetch any missing auth events doing all checks listed here starting at 1. These are not timeline events // 5. Reject "due to auth events" if can't get all the auth events or some of the auth events are also rejected "due to auth events" // NOTE: Step 5 is not applied anymore because it failed too often - warn!("Fetching auth events for {}", incoming_pdu.event_id); + debug!(event_id = ?incoming_pdu.event_id, "Fetching auth events"); self.fetch_and_handle_outliers( origin, &incoming_pdu From 6786c44f4df96e7505b68c165b6a275b556f7ab6 Mon Sep 17 00:00:00 2001 From: Nyaaori <+@nyaaori.cat> Date: Mon, 21 Nov 2022 09:39:17 +0100 Subject: [PATCH 26/56] chore: Fix MSRV Ruma requires Rust 1.64 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 588b443..ae51945 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ homepage = "https://conduit.rs" repository = "https://gitlab.com/famedly/conduit" readme = "README.md" version = "0.4.0-next" -rust-version = "1.63" +rust-version = "1.64" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 66bc41125c244b3a1d17a5590882ba1b71212cc7 Mon Sep 17 00:00:00 2001 From: Nyaaori <+@nyaaori.cat> Date: Mon, 21 Nov 2022 09:51:39 +0100 Subject: [PATCH 27/56] refactor: cleanup --- Cargo.lock | 2 +- src/api/client_server/media.rs | 2 +- src/config/mod.rs | 4 ++-- src/database/key_value/pusher.rs | 5 ++--- src/lib.rs | 2 +- src/service/admin/mod.rs | 8 ++++---- src/service/pusher/mod.rs | 6 +++--- src/service/rooms/search/data.rs | 2 +- src/service/rooms/state/data.rs | 2 +- src/service/rooms/state/mod.rs | 2 +- src/service/rooms/user/mod.rs | 6 +++--- 11 files changed, 20 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 71524af..75b1222 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -372,7 +372,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "conduit" -version = "0.4.0-next" +version = "0.5.0-alpha.next" dependencies = [ "async-trait", "axum", diff --git a/src/api/client_server/media.rs b/src/api/client_server/media.rs index ae023c9..fa6def0 100644 --- a/src/api/client_server/media.rs +++ b/src/api/client_server/media.rs @@ -74,7 +74,7 @@ pub async fn get_remote_content( services() .media .create( - mxc.to_string(), + mxc.to_owned(), content_response.content_disposition.as_deref(), content_response.content_type.as_deref(), &content_response.file, diff --git a/src/config/mod.rs b/src/config/mod.rs index 3c3a764..6b862bb 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -183,7 +183,7 @@ impl fmt::Display for Config { ("Turn TTL", &self.turn_ttl.to_string()), ("Turn URIs", { let mut lst = vec![]; - for item in self.turn_uris.to_vec().into_iter().enumerate() { + for item in self.turn_uris.iter().cloned().enumerate() { let (_, uri): (usize, String) = item; lst.push(uri); } @@ -191,7 +191,7 @@ impl fmt::Display for Config { }), ]; - let mut msg: String = "Active config values:\n\n".to_string(); + let mut msg: String = "Active config values:\n\n".to_owned(); for line in lines.into_iter().enumerate() { msg += &format!("{}: {}\n", line.1 .0, line.1 .1); diff --git a/src/database/key_value/pusher.rs b/src/database/key_value/pusher.rs index b203107..50a6fac 100644 --- a/src/database/key_value/pusher.rs +++ b/src/database/key_value/pusher.rs @@ -22,11 +22,10 @@ impl service::pusher::Data for KeyValueDatabase { let mut key = sender.as_bytes().to_vec(); key.push(0xff); key.extend_from_slice(ids.pushkey.as_bytes()); - return self - .senderkey_pusher + self.senderkey_pusher .remove(&key) .map(|_| ()) - .map_err(Into::into); + .map_err(Into::into) } } } diff --git a/src/lib.rs b/src/lib.rs index 3d7f7ae..dc6a9d2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,7 @@ pub use utils::error::{Error, Result}; pub static SERVICES: RwLock> = RwLock::new(None); -pub fn services<'a>() -> &'static Services { +pub fn services() -> &'static Services { SERVICES .read() .unwrap() diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index 5766b2f..e2b2fd8 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -599,7 +599,8 @@ impl Service { } } AdminCommand::CreateUser { username, password } => { - let password = password.unwrap_or(utils::random_string(AUTO_GEN_PASSWORD_LENGTH)); + let password = + password.unwrap_or_else(|| utils::random_string(AUTO_GEN_PASSWORD_LENGTH)); // Validate user id let user_id = match UserId::parse_with_server_name( username.as_str().to_lowercase(), @@ -732,9 +733,8 @@ impl Service { } for &user_id in &user_ids { - match services().users.deactivate_account(user_id) { - Ok(_) => deactivation_count += 1, - Err(_) => {} + if services().users.deactivate_account(user_id).is_ok() { + deactivation_count += 1 } } diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index cd11d71..d3d157c 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -42,7 +42,7 @@ impl Service { self.db.get_pushers(sender) } - pub fn get_pushkeys<'a>(&'a self, sender: &UserId) -> Box>> { + pub fn get_pushkeys(&self, sender: &UserId) -> Box>> { self.db.get_pushkeys(sender) } @@ -296,8 +296,8 @@ impl Service { Ok(()) } // TODO: Handle email - PusherKind::Email(_) => return Ok(()), - _ => return Ok(()), + PusherKind::Email(_) => Ok(()), + _ => Ok(()), } } } diff --git a/src/service/rooms/search/data.rs b/src/service/rooms/search/data.rs index 82c0800..6eef38f 100644 --- a/src/service/rooms/search/data.rs +++ b/src/service/rooms/search/data.rs @@ -2,7 +2,7 @@ use crate::Result; use ruma::RoomId; pub trait Data: Send + Sync { - fn index_pdu<'a>(&self, shortroomid: u64, pdu_id: &[u8], message_body: &str) -> Result<()>; + fn index_pdu(&self, shortroomid: u64, pdu_id: &[u8], message_body: &str) -> Result<()>; fn search_pdus<'a>( &'a self, diff --git a/src/service/rooms/state/data.rs b/src/service/rooms/state/data.rs index f52ea72..96116b0 100644 --- a/src/service/rooms/state/data.rs +++ b/src/service/rooms/state/data.rs @@ -22,7 +22,7 @@ pub trait Data: Send + Sync { fn get_forward_extremities(&self, room_id: &RoomId) -> Result>>; /// Replace the forward extremities of the room. - fn set_forward_extremities<'a>( + fn set_forward_extremities( &self, room_id: &RoomId, event_ids: Vec, diff --git a/src/service/rooms/state/mod.rs b/src/service/rooms/state/mod.rs index 0e45032..3072b80 100644 --- a/src/service/rooms/state/mod.rs +++ b/src/service/rooms/state/mod.rs @@ -343,7 +343,7 @@ impl Service { self.db.get_forward_extremities(room_id) } - pub fn set_forward_extremities<'a>( + pub fn set_forward_extremities( &self, room_id: &RoomId, event_ids: Vec, diff --git a/src/service/rooms/user/mod.rs b/src/service/rooms/user/mod.rs index 2266d97..672e502 100644 --- a/src/service/rooms/user/mod.rs +++ b/src/service/rooms/user/mod.rs @@ -40,10 +40,10 @@ impl Service { self.db.get_token_shortstatehash(room_id, token) } - pub fn get_shared_rooms<'a>( - &'a self, + pub fn get_shared_rooms( + &self, users: Vec, - ) -> Result> + 'a> { + ) -> Result>> { self.db.get_shared_rooms(users) } } From b59304a4df970f1d74b8e15b733f6754125b6fec Mon Sep 17 00:00:00 2001 From: Nyaaori <+@nyaaori.cat> Date: Sun, 25 Sep 2022 11:46:18 +0200 Subject: [PATCH 28/56] Reduce length of generated access tokens and session ids Reduces generated tokens and session ids down to 32 characters (~190 bits of entropy) in length --- src/api/client_server/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/client_server/mod.rs b/src/api/client_server/mod.rs index 65b7a10..6ed17e7 100644 --- a/src/api/client_server/mod.rs +++ b/src/api/client_server/mod.rs @@ -63,6 +63,6 @@ pub use user_directory::*; pub use voip::*; pub const DEVICE_ID_LENGTH: usize = 10; -pub const TOKEN_LENGTH: usize = 256; -pub const SESSION_ID_LENGTH: usize = 256; +pub const TOKEN_LENGTH: usize = 32; +pub const SESSION_ID_LENGTH: usize = 32; pub const AUTO_GEN_PASSWORD_LENGTH: usize = 15; From 583aea187b24e3a8d2a582a2cf6aae34bf04a8ce Mon Sep 17 00:00:00 2001 From: "Andriy Kushnir (Orhideous)" Date: Fri, 25 Nov 2022 23:13:58 +0200 Subject: [PATCH 29/56] Update Cargo.lock --- Cargo.lock | 114 ++++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75b1222..db8ee9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,9 +21,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -291,15 +291,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" [[package]] name = "cc" -version = "1.0.76" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" dependencies = [ "jobserver", ] @@ -332,9 +332,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.0.22" +version = "4.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91b9970d7505127a162fdaa9b96428d28a479ba78c9ec7550a63a5d9863db682" +checksum = "0acbd8d28a0a60d7108d7ae850af6ba34cf2d1257fc646980e5f97ce14275966" dependencies = [ "bitflags", "clap_derive", @@ -372,7 +372,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "conduit" -version = "0.5.0-alpha.next" +version = "0.4.0-next" dependencies = [ "async-trait", "axum", @@ -424,9 +424,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" [[package]] name = "constant_time_eq" @@ -520,9 +520,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.11" +version = "0.9.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" dependencies = [ "autocfg", "cfg-if", @@ -533,9 +533,9 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd42583b04998a5363558e5f9291ee5a5ff6b49944332103f251e7479a82aa7" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" dependencies = [ "cfg-if", "crossbeam-utils", @@ -543,9 +543,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.12" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", ] @@ -600,9 +600,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.3", "crypto-common", @@ -707,12 +707,12 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" dependencies = [ "crc32fast", - "miniz_oxide 0.5.4", + "miniz_oxide", ] [[package]] @@ -1002,7 +1002,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", ] [[package]] @@ -1082,9 +1082,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +checksum = "59df7c4e19c950e6e0e868dcc0a300b09a9b88e9ec55bd879ca819087a77355d" dependencies = [ "http", "hyper", @@ -1116,9 +1116,9 @@ dependencies = [ [[package]] name = "image" -version = "0.24.4" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8e4fb07cf672b1642304e731ef8a6a4c7891d67bb4fd4f5ce58cd6ed86803c" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" dependencies = [ "bytemuck", "byteorder", @@ -1132,9 +1132,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -1155,14 +1155,14 @@ checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" [[package]] name = "ipconfig" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "723519edce41262b05d4143ceb95050e4c614f483e78e9fd9e39a8275a84ad98" +checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be" dependencies = [ "socket2", "widestring", "winapi", - "winreg", + "winreg 0.10.1", ] [[package]] @@ -1197,9 +1197,9 @@ dependencies = [ [[package]] name = "jpeg-decoder" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" [[package]] name = "js-sys" @@ -1401,9 +1401,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] @@ -1420,15 +1420,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.6.2" @@ -1621,9 +1612,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.3.1" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] name = "overload" @@ -1787,7 +1778,7 @@ dependencies = [ "bitflags", "crc32fast", "flate2", - "miniz_oxide 0.6.2", + "miniz_oxide", ] [[package]] @@ -2020,7 +2011,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "winreg 0.7.0", ] [[package]] @@ -2369,9 +2360,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa", "ryu", @@ -2411,7 +2402,7 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.5", + "digest 0.10.6", ] [[package]] @@ -2422,7 +2413,7 @@ checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.5", + "digest 0.10.6", ] [[package]] @@ -2701,9 +2692,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.21.2" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" dependencies = [ "autocfg", "bytes", @@ -3035,9 +3026,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" +checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" dependencies = [ "getrandom 0.2.8", ] @@ -3317,6 +3308,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "yansi" version = "0.5.1" From bcd522e75f29730109320850cb908204cb1857bb Mon Sep 17 00:00:00 2001 From: Orhideous Date: Sun, 27 Nov 2022 20:15:47 +0000 Subject: [PATCH 30/56] Added cross-compilation instructions to DEPLOY.md --- DEPLOY.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/DEPLOY.md b/DEPLOY.md index c484823..89631f5 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -49,7 +49,25 @@ $ sudo apt install libclang-dev build-essential $ cargo build --release ``` -If you want to cross compile Conduit to another architecture, read the [Cross-Compile Guide](cross/README.md). +If you want to cross compile Conduit to another architecture, read the guide below. + +
+Cross compilation + +As easiest way to compile conduit for another platform [cross-rs](https://github.com/cross-rs/cross) is recommended, so install it first. + +In order to use RockDB as storage backend append `-latomic` to linker flags. + +For example, to build a binary for Raspberry Pi Zero W (ARMv6) you need `arm-unknown-linux-gnueabihf` as compilation +target. + +```bash +git clone https://gitlab.com/famedly/conduit.git +cd conduit +export RUSTFLAGS='-C link-arg=-lgcc -Clink-arg=-latomic -Clink-arg=-static-libgcc' +cross build --release --no-default-features --features conduit_bin,backend_rocksdb,jemalloc --target=arm-unknown-linux-gnueabihf +``` +
## Adding a Conduit user From 66ad114e1909ddde5a17005df9c332605a9f9d60 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Fri, 25 Nov 2022 21:20:45 +0100 Subject: [PATCH 31/56] feat: add systemd feature flag --- Cargo.lock | 7 +++++++ Cargo.toml | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index db8ee9d..6ae1836 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -404,6 +404,7 @@ dependencies = [ "ruma", "rusqlite", "rust-argon2", + "sd-notify", "serde", "serde_json", "serde_yaml", @@ -2315,6 +2316,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sd-notify" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "621e3680f3e07db4c9c2c3fb07c6223ab2fab2e54bd3c04c3ae037990f428c32" + [[package]] name = "security-framework" version = "2.7.0" diff --git a/Cargo.toml b/Cargo.toml index ae51945..801d363 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,8 +93,10 @@ tikv-jemallocator = { version = "0.5.0", features = ["unprefixed_malloc_on_suppo lazy_static = "1.4.0" async-trait = "0.1.57" +sd-notify = { version = "0.4.1", optional = true } + [features] -default = ["conduit_bin", "backend_sqlite", "backend_rocksdb", "jemalloc"] +default = ["conduit_bin", "backend_sqlite", "backend_rocksdb", "jemalloc", "systemd"] #backend_sled = ["sled"] backend_persy = ["persy", "parking_lot"] backend_sqlite = ["sqlite"] @@ -103,6 +105,7 @@ backend_rocksdb = ["rocksdb"] jemalloc = ["tikv-jemalloc-ctl", "tikv-jemallocator"] sqlite = ["rusqlite", "parking_lot", "tokio/signal"] conduit_bin = ["axum"] +systemd = ["sd-notify"] [[bin]] name = "conduit" From 06d3efc4d0c98fbb0f5973929cceede77c0f7e44 Mon Sep 17 00:00:00 2001 From: Vladan Popovic Date: Fri, 25 Nov 2022 21:23:21 +0100 Subject: [PATCH 32/56] feat(systemd): call sd-notify after init and before exit --- src/main.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index d2183a3..e754b84 100644 --- a/src/main.rs +++ b/src/main.rs @@ -186,10 +186,20 @@ async fn run_server() -> io::Result<()> { match &config.tls { Some(tls) => { let conf = RustlsConfig::from_pem_file(&tls.certs, &tls.key).await?; - bind_rustls(addr, conf).handle(handle).serve(app).await?; + let server = bind_rustls(addr, conf).handle(handle).serve(app); + + #[cfg(feature = "systemd")] + let _ = sd_notify::notify(true, &[sd_notify::NotifyState::Ready]); + + server.await? } None => { - bind(addr).handle(handle).serve(app).await?; + let server = bind(addr).handle(handle).serve(app); + + #[cfg(feature = "systemd")] + let _ = sd_notify::notify(true, &[sd_notify::NotifyState::Ready]); + + server.await? } } @@ -197,6 +207,9 @@ async fn run_server() -> io::Result<()> { info!(target: "shutdown-sync", "Received shutdown notification, notifying sync helpers..."); services().globals.rotate.fire(); + #[cfg(feature = "systemd")] + let _ = sd_notify::notify(true, &[sd_notify::NotifyState::Stopping]); + Ok(()) } From b9fd6127e22a72d6563446572577a2e110cca95a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sun, 27 Nov 2022 23:25:42 +0100 Subject: [PATCH 33/56] fix: rejoining restricted rooms over federation --- src/api/client_server/membership.rs | 368 ++++++++++++++++++++----- src/api/server_server.rs | 48 ++-- src/service/pdu.rs | 14 +- src/service/rooms/event_handler/mod.rs | 16 +- 4 files changed, 352 insertions(+), 94 deletions(-) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 2267cbf..f6e94e6 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -12,12 +12,15 @@ use ruma::{ }, canonical_json::to_canonical_value, events::{ - room::member::{MembershipState, RoomMemberEventContent}, + room::{ + join_rules::{JoinRule, RoomJoinRulesEventContent}, + member::{MembershipState, RoomMemberEventContent}, + }, RoomEventType, StateEventType, }, serde::Base64, - CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, OwnedServerName, - OwnedUserId, RoomId, RoomVersionId, UserId, + state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, + OwnedServerName, OwnedUserId, RoomId, RoomVersionId, UserId, }; use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; use std::{ @@ -480,33 +483,10 @@ async fn join_room_by_id_helper( .state_cache .server_in_room(services().globals.server_name(), room_id)? { - let mut make_join_response_and_server = Err(Error::BadServerResponse( - "No server available to assist in joining.", - )); + let (make_join_response, remote_server) = + make_join_request(sender_user, room_id, servers).await?; - for remote_server in servers { - let make_join_response = services() - .sending - .send_federation_request( - remote_server, - federation::membership::prepare_join_event::v1::Request { - room_id, - user_id: sender_user, - ver: &services().globals.supported_room_versions(), - }, - ) - .await; - - make_join_response_and_server = make_join_response.map(|r| (r, remote_server)); - - if make_join_response_and_server.is_ok() { - break; - } - } - - let (make_join_response, remote_server) = make_join_response_and_server?; - - let room_version = match make_join_response.room_version { + let room_version_id = match make_join_response.room_version { Some(room_version) if services() .globals @@ -568,14 +548,14 @@ async fn join_room_by_id_helper( services().globals.server_name().as_str(), services().globals.keypair(), &mut join_event_stub, - &room_version, + &room_version_id, ) .expect("event is valid, we just created it"); // Generate event id let event_id = format!( "${}", - ruma::signatures::reference_hash(&join_event_stub, &room_version) + ruma::signatures::reference_hash(&join_event_stub, &room_version_id) .expect("ruma can calculate reference hashes") ); let event_id = <&EventId>::try_from(event_id.as_str()) @@ -588,12 +568,12 @@ async fn join_room_by_id_helper( ); // It has enough fields to be called a proper event now - let join_event = join_event_stub; + let mut join_event = join_event_stub; let send_join_response = services() .sending .send_federation_request( - remote_server, + &remote_server, federation::membership::create_join_event::v2::Request { room_id, event_id, @@ -602,9 +582,53 @@ async fn join_room_by_id_helper( ) .await?; + if let Some(signed_raw) = &send_join_response.room_state.event { + let (signed_event_id, signed_value) = + match gen_event_id_canonical_json(&signed_raw, &room_version_id) { + Ok(t) => t, + Err(_) => { + // Event could not be converted to canonical json + return Err(Error::BadRequest( + ErrorKind::InvalidParam, + "Could not convert event to canonical json.", + )); + } + }; + + if &signed_event_id != event_id { + return Err(Error::BadRequest( + ErrorKind::InvalidParam, + "Server sent event with wrong event id", + )); + } + + if let Ok(signature) = signed_value["signatures"] + .as_object() + .ok_or(Error::BadRequest( + ErrorKind::InvalidParam, + "Server sent invalid signatures type", + )) + .and_then(|e| { + e.get(remote_server.as_str()).ok_or(Error::BadRequest( + ErrorKind::InvalidParam, + "Server did not send its signature", + )) + }) + { + join_event + .get_mut("signatures") + .expect("we created a valid pdu") + .as_object_mut() + .expect("we created a valid pdu") + .insert(remote_server.to_string(), signature.clone()); + } else { + warn!("Server {} sent invalid sendjoin event", remote_server); + } + } + services().rooms.short.get_or_create_shortroomid(room_id)?; - let parsed_pdu = PduEvent::from_id_val(event_id, join_event.clone()) + let parsed_join_pdu = PduEvent::from_id_val(event_id, join_event.clone()) .map_err(|_| Error::BadServerResponse("Invalid join event PDU."))?; let mut state = HashMap::new(); @@ -613,14 +637,14 @@ async fn join_room_by_id_helper( services() .rooms .event_handler - .fetch_join_signing_keys(&send_join_response, &room_version, &pub_key_map) + .fetch_join_signing_keys(&send_join_response, &room_version_id, &pub_key_map) .await?; for result in send_join_response .room_state .state .iter() - .map(|pdu| validate_and_add_event_id(pdu, &room_version, &pub_key_map)) + .map(|pdu| validate_and_add_event_id(pdu, &room_version_id, &pub_key_map)) { let (event_id, value) = match result { Ok(t) => t, @@ -645,31 +669,11 @@ async fn join_room_by_id_helper( } } - let incoming_shortstatekey = services().rooms.short.get_or_create_shortstatekey( - &parsed_pdu.kind.to_string().into(), - parsed_pdu - .state_key - .as_ref() - .expect("Pdu is a membership state event"), - )?; - - state.insert(incoming_shortstatekey, parsed_pdu.event_id.clone()); - - let create_shortstatekey = services() - .rooms - .short - .get_shortstatekey(&StateEventType::RoomCreate, "")? - .expect("Room exists"); - - if state.get(&create_shortstatekey).is_none() { - return Err(Error::BadServerResponse("State contained no create event.")); - } - for result in send_join_response .room_state .auth_chain .iter() - .map(|pdu| validate_and_add_event_id(pdu, &room_version, &pub_key_map)) + .map(|pdu| validate_and_add_event_id(pdu, &room_version_id, &pub_key_map)) { let (event_id, value) = match result { Ok(t) => t, @@ -682,6 +686,34 @@ async fn join_room_by_id_helper( .add_pdu_outlier(&event_id, &value)?; } + if !state_res::event_auth::auth_check( + &state_res::RoomVersion::new(&room_version_id).expect("room version is supported"), + &parsed_join_pdu, + None::, // TODO: third party invite + |k, s| { + services() + .rooms + .timeline + .get_pdu( + state.get( + &services() + .rooms + .short + .get_or_create_shortstatekey(&k.to_string().into(), s) + .ok()?, + )?, + ) + .ok()? + }, + ) + .map_err(|_e| Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed"))? + { + return Err(Error::BadRequest( + ErrorKind::InvalidParam, + "Auth check failed", + )); + } + let (statehash_before_join, new, removed) = services().rooms.state_compressor.save_state( room_id, state @@ -705,12 +737,12 @@ async fn join_room_by_id_helper( // We append to state before appending the pdu, so we don't have a moment in time with the // pdu without it's state. This is okay because append_pdu can't fail. - let statehash_after_join = services().rooms.state.append_to_state(&parsed_pdu)?; + let statehash_after_join = services().rooms.state.append_to_state(&parsed_join_pdu)?; services().rooms.timeline.append_pdu( - &parsed_pdu, + &parsed_join_pdu, join_event, - vec![(*parsed_pdu.event_id).to_owned()], + vec![(*parsed_join_pdu.event_id).to_owned()], &state_lock, )?; @@ -732,7 +764,8 @@ async fn join_room_by_id_helper( join_authorized_via_users_server: None, }; - services().rooms.timeline.build_and_append_pdu( + // Try normal join first + let error = match services().rooms.timeline.build_and_append_pdu( PduBuilder { event_type: RoomEventType::RoomMember, content: to_raw_value(&event).expect("event is valid, we just created it"), @@ -743,14 +776,216 @@ async fn join_room_by_id_helper( sender_user, room_id, &state_lock, + ) { + Ok(_event_id) => return Ok(join_room_by_id::v3::Response::new(room_id.to_owned())), + Err(e) => e, + }; + + // TODO: Conduit does not implement restricted join rules yet, we always ask over + // federation + let join_rules_event = services().rooms.state_accessor.room_state_get( + &room_id, + &StateEventType::RoomJoinRules, + "", )?; + + let join_rules_event_content: Option = join_rules_event + .as_ref() + .map(|join_rules_event| { + serde_json::from_str(join_rules_event.content.get()).map_err(|e| { + warn!("Invalid join rules event: {}", e); + Error::bad_database("Invalid join rules event in db.") + }) + }) + .transpose()?; + + if matches!( + join_rules_event_content, + Some(RoomJoinRulesEventContent { + join_rule: JoinRule::Restricted { .. } + }) | Some(RoomJoinRulesEventContent { + join_rule: JoinRule::KnockRestricted { .. } + }) + ) { + let (make_join_response, remote_server) = + make_join_request(sender_user, room_id, servers).await?; + + let room_version_id = match make_join_response.room_version { + Some(room_version_id) + if services() + .globals + .supported_room_versions() + .contains(&room_version_id) => + { + room_version_id + } + _ => return Err(Error::BadServerResponse("Room version is not supported")), + }; + let mut join_event_stub: CanonicalJsonObject = + serde_json::from_str(make_join_response.event.get()).map_err(|_| { + Error::BadServerResponse("Invalid make_join event json received from server.") + })?; + let join_authorized_via_users_server = join_event_stub + .get("content") + .map(|s| { + s.as_object()? + .get("join_authorised_via_users_server")? + .as_str() + }) + .and_then(|s| OwnedUserId::try_from(s.unwrap_or_default()).ok()); + // TODO: Is origin needed? + join_event_stub.insert( + "origin".to_owned(), + CanonicalJsonValue::String(services().globals.server_name().as_str().to_owned()), + ); + join_event_stub.insert( + "origin_server_ts".to_owned(), + CanonicalJsonValue::Integer( + utils::millis_since_unix_epoch() + .try_into() + .expect("Timestamp is valid js_int value"), + ), + ); + join_event_stub.insert( + "content".to_owned(), + to_canonical_value(RoomMemberEventContent { + membership: MembershipState::Join, + displayname: services().users.displayname(sender_user)?, + avatar_url: services().users.avatar_url(sender_user)?, + is_direct: None, + third_party_invite: None, + blurhash: services().users.blurhash(sender_user)?, + reason: None, + join_authorized_via_users_server, + }) + .expect("event is valid, we just created it"), + ); + + // We don't leave the event id in the pdu because that's only allowed in v1 or v2 rooms + join_event_stub.remove("event_id"); + + // In order to create a compatible ref hash (EventID) the `hashes` field needs to be present + ruma::signatures::hash_and_sign_event( + services().globals.server_name().as_str(), + services().globals.keypair(), + &mut join_event_stub, + &room_version_id, + ) + .expect("event is valid, we just created it"); + + // Generate event id + let event_id = format!( + "${}", + ruma::signatures::reference_hash(&join_event_stub, &room_version_id) + .expect("ruma can calculate reference hashes") + ); + let event_id = <&EventId>::try_from(event_id.as_str()) + .expect("ruma's reference hashes are valid event ids"); + + // Add event_id back + join_event_stub.insert( + "event_id".to_owned(), + CanonicalJsonValue::String(event_id.as_str().to_owned()), + ); + + // It has enough fields to be called a proper event now + let join_event = join_event_stub; + + let send_join_response = services() + .sending + .send_federation_request( + &remote_server, + federation::membership::create_join_event::v2::Request { + room_id, + event_id, + pdu: &PduEvent::convert_to_outgoing_federation_event(join_event.clone()), + }, + ) + .await?; + + if let Some(signed_raw) = send_join_response.room_state.event { + let (signed_event_id, signed_value) = + match gen_event_id_canonical_json(&signed_raw, &room_version_id) { + Ok(t) => t, + Err(_) => { + // Event could not be converted to canonical json + return Err(Error::BadRequest( + ErrorKind::InvalidParam, + "Could not convert event to canonical json.", + )); + } + }; + + if &signed_event_id != event_id { + return Err(Error::BadRequest( + ErrorKind::InvalidParam, + "Server sent event with wrong event id", + )); + } + + drop(state_lock); + let pub_key_map = RwLock::new(BTreeMap::new()); + services() + .rooms + .event_handler + .handle_incoming_pdu( + &remote_server, + &signed_event_id, + room_id, + signed_value, + true, + &pub_key_map, + ) + .await?; + } else { + return Err(error); + } + } else { + return Err(error); + } } - drop(state_lock); - Ok(join_room_by_id::v3::Response::new(room_id.to_owned())) } +async fn make_join_request( + sender_user: &UserId, + room_id: &RoomId, + servers: &[OwnedServerName], +) -> Result<( + federation::membership::prepare_join_event::v1::Response, + OwnedServerName, +)> { + let mut make_join_response_and_server = Err(Error::BadServerResponse( + "No server available to assist in joining.", + )); + + for remote_server in servers { + if remote_server == services().globals.server_name() { + continue; + } + let make_join_response = services() + .sending + .send_federation_request( + remote_server, + federation::membership::prepare_join_event::v1::Request { + room_id, + user_id: sender_user, + ver: &services().globals.supported_room_versions(), + }, + ) + .await; + + make_join_response_and_server = make_join_response.map(|r| (r, remote_server.clone())); + + if make_join_response_and_server.is_ok() { + break; + } + } + + make_join_response_and_server +} + fn validate_and_add_event_id( pdu: &RawJsonValue, room_version: &RoomVersionId, @@ -870,6 +1105,8 @@ pub(crate) async fn invite_helper<'a>( (pdu, pdu_json, invite_room_state) }; + let room_version_id = &services().rooms.state.get_room_version(room_id)?; + let response = services() .sending .send_federation_request( @@ -877,7 +1114,7 @@ pub(crate) async fn invite_helper<'a>( create_invite::v2::Request { room_id, event_id: &pdu.event_id, - room_version: &services().rooms.state.get_room_version(room_id)?, + room_version: &room_version_id, event: &PduEvent::convert_to_outgoing_federation_event(pdu_json.clone()), invite_room_state: &invite_room_state, }, @@ -887,7 +1124,8 @@ pub(crate) async fn invite_helper<'a>( let pub_key_map = RwLock::new(BTreeMap::new()); // We do not add the event_id field to the pdu here because of signature and hashes checks - let (event_id, value) = match gen_event_id_canonical_json(&response.event) { + let (event_id, value) = match gen_event_id_canonical_json(&response.event, room_version_id) + { Ok(t) => t, Err(_) => { // Event could not be converted to canonical json diff --git a/src/api/server_server.rs b/src/api/server_server.rs index f66e96c..44babe5 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -42,8 +42,8 @@ use ruma::{ }, serde::{Base64, JsonObject, Raw}, to_device::DeviceIdOrAllDevices, - CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, - OwnedServerName, OwnedServerSigningKeyId, OwnedUserId, RoomId, ServerName, + CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, + OwnedRoomId, OwnedServerName, OwnedServerSigningKeyId, OwnedUserId, RoomId, ServerName, }; use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; use std::{ @@ -664,16 +664,11 @@ pub async fn send_transaction_message_route( // let mut auth_cache = EventMap::new(); for pdu in &body.pdus { - // We do not add the event_id field to the pdu here because of signature and hashes checks - let (event_id, value) = match gen_event_id_canonical_json(pdu) { - Ok(t) => t, - Err(_) => { - // Event could not be converted to canonical json - continue; - } - }; + let value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| { + warn!("Error parsing incoming event {:?}: {:?}", pdu, e); + Error::BadServerResponse("Invalid PDU in server response") + })?; - // 0. Check the server is in the room let room_id: OwnedRoomId = match value .get("room_id") .and_then(|id| RoomId::parse(id.as_str()?).ok()) @@ -681,14 +676,26 @@ pub async fn send_transaction_message_route( Some(id) => id, None => { // Event is invalid - resolved_map.insert( - event_id, - Err(Error::bad_database("Event needs a valid RoomId.")), - ); continue; } }; + let room_version_id = match services().rooms.state.get_room_version(&room_id) { + Ok(v) => v, + Err(_) => { + continue; + } + }; + + let (event_id, value) = match gen_event_id_canonical_json(pdu, &room_version_id) { + Ok(t) => t, + Err(_) => { + // Event could not be converted to canonical json + continue; + } + }; + // We do not add the event_id field to the pdu here because of signature and hashes checks + services() .rooms .event_handler @@ -1407,7 +1414,8 @@ async fn create_join_event( // let mut auth_cache = EventMap::new(); // We do not add the event_id field to the pdu here because of signature and hashes checks - let (event_id, value) = match gen_event_id_canonical_json(pdu) { + let room_version_id = services().rooms.state.get_room_version(room_id)?; + let (event_id, value) = match gen_event_id_canonical_json(pdu, &room_version_id) { Ok(t) => t, Err(_) => { // Event could not be converted to canonical json @@ -1610,8 +1618,12 @@ pub async fn create_invite_route( invite_state.push(pdu.to_stripped_state_event()); - // If the room already exists, the remote server will notify us about the join via /send - if !services().rooms.metadata.exists(&pdu.room_id)? { + // If we are active in the room, the remote server will notify us about the join via /send + if !services() + .rooms + .state_cache + .server_in_room(services().globals.server_name(), &body.room_id)? + { services().rooms.state_cache.update_membership( &body.room_id, &invited_user, diff --git a/src/service/pdu.rs b/src/service/pdu.rs index 593a687..554f3be 100644 --- a/src/service/pdu.rs +++ b/src/service/pdu.rs @@ -1,4 +1,4 @@ -use crate::{services, Error}; +use crate::Error; use ruma::{ events::{ room::member::RoomMemberEventContent, AnyEphemeralRoomEvent, AnyStateEvent, @@ -7,7 +7,7 @@ use ruma::{ }, serde::Raw, state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, - OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UInt, UserId, + OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, RoomVersionId, UInt, UserId, }; use serde::{Deserialize, Serialize}; use serde_json::{ @@ -334,23 +334,17 @@ impl Ord for PduEvent { /// Returns a tuple of the new `EventId` and the PDU as a `BTreeMap`. pub(crate) fn gen_event_id_canonical_json( pdu: &RawJsonValue, + room_version_id: &RoomVersionId, ) -> crate::Result<(OwnedEventId, CanonicalJsonObject)> { let value: CanonicalJsonObject = serde_json::from_str(pdu.get()).map_err(|e| { warn!("Error parsing incoming event {:?}: {:?}", pdu, e); Error::BadServerResponse("Invalid PDU in server response") })?; - let room_id = value - .get("room_id") - .and_then(|id| RoomId::parse(id.as_str()?).ok()) - .ok_or_else(|| Error::bad_database("PDU in db has invalid room_id."))?; - - let room_version_id = services().rooms.state.get_room_version(&room_id); - let event_id = format!( "${}", // Anything higher than version3 behaves the same - ruma::signatures::reference_hash(&value, &room_version_id?) + ruma::signatures::reference_hash(&value, room_version_id) .expect("ruma can calculate reference hashes") ) .try_into() diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 3b41e86..b941aa1 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -76,6 +76,7 @@ impl Service { is_timeline_event: bool, pub_key_map: &'a RwLock>>, ) -> Result>> { + // 0. Check the server is in the room if !services().rooms.metadata.exists(room_id)? { return Err(Error::BadRequest( ErrorKind::NotFound, @@ -101,6 +102,13 @@ impl Service { .room_state_get(room_id, &StateEventType::RoomCreate, "")? .ok_or_else(|| Error::bad_database("Failed to find create event in db."))?; + let create_event_content: RoomCreateEventContent = + serde_json::from_str(create_event.content.get()).map_err(|e| { + error!("Invalid create event: {}", e); + Error::BadDatabase("Invalid create event in db") + })?; + let room_version_id = &create_event_content.room_version; + let first_pdu_in_room = services() .rooms .timeline @@ -127,6 +135,7 @@ impl Service { origin, &create_event, room_id, + room_version_id, pub_key_map, incoming_pdu.prev_events.clone(), ) @@ -340,6 +349,7 @@ impl Service { .collect::>(), create_event, room_id, + room_version_id, pub_key_map, ) .await; @@ -644,6 +654,7 @@ impl Service { .collect::>(), create_event, room_id, + room_version_id, pub_key_map, ) .await; @@ -1024,6 +1035,7 @@ impl Service { events: &'a [Arc], create_event: &'a PduEvent, room_id: &'a RoomId, + room_version_id: &'a RoomVersionId, pub_key_map: &'a RwLock>>, ) -> AsyncRecursiveType<'a, Vec<(Arc, Option>)>> { @@ -1106,7 +1118,7 @@ impl Service { Ok(res) => { info!("Got {} over federation", next_id); let (calculated_event_id, value) = - match pdu::gen_event_id_canonical_json(&res.pdu) { + match pdu::gen_event_id_canonical_json(&res.pdu, room_version_id) { Ok(t) => t, Err(_) => { back_off((*next_id).to_owned()); @@ -1179,6 +1191,7 @@ impl Service { origin: &ServerName, create_event: &PduEvent, room_id: &RoomId, + room_version_id: &RoomVersionId, pub_key_map: &RwLock>>, initial_set: Vec>, ) -> Result<( @@ -1204,6 +1217,7 @@ impl Service { &[prev_event_id.clone()], create_event, room_id, + room_version_id, pub_key_map, ) .await From 7fd5b22e3b03cd6f10bb40b1dda05a3815ee25b2 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Fri, 16 Dec 2022 10:12:11 +0100 Subject: [PATCH 34/56] The procMacro option has long been on by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … and it's good to let people have their own local configs that won't be tracked by git. --- .gitignore | 1 - .vscode/settings.json | 3 --- 2 files changed, 4 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 19f05ce..203fe05 100644 --- a/.gitignore +++ b/.gitignore @@ -31,7 +31,6 @@ modules.xml ### vscode ### .vscode/* -!.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 95294d4..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "rust-analyzer.procMacro.enable": true, -} \ No newline at end of file From d39ce1401d773a0b68515b8ae1a434f37abfc650 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 14 Dec 2022 13:09:10 +0100 Subject: [PATCH 35/56] WIP: Upgrade Ruma --- Cargo.lock | 22 ++++---- Cargo.toml | 2 +- src/api/client_server/account.rs | 14 ++--- src/api/client_server/alias.rs | 26 +++++---- src/api/client_server/backup.rs | 24 ++++---- src/api/client_server/capabilities.rs | 2 +- src/api/client_server/config.rs | 8 +-- src/api/client_server/context.rs | 2 +- src/api/client_server/device.rs | 8 +-- src/api/client_server/directory.rs | 25 ++++----- src/api/client_server/filter.rs | 4 +- src/api/client_server/keys.rs | 8 +-- src/api/client_server/media.rs | 20 +++---- src/api/client_server/membership.rs | 75 +++++++++++++------------ src/api/client_server/message.rs | 4 +- src/api/client_server/presence.rs | 4 +- src/api/client_server/profile.rs | 20 +++---- src/api/client_server/push.rs | 26 ++++----- src/api/client_server/read_marker.rs | 4 +- src/api/client_server/redact.rs | 2 +- src/api/client_server/report.rs | 2 +- src/api/client_server/room.rs | 8 +-- src/api/client_server/search.rs | 2 +- src/api/client_server/session.rs | 12 ++-- src/api/client_server/state.rs | 10 ++-- src/api/client_server/sync.rs | 18 +++--- src/api/client_server/tag.rs | 8 +-- src/api/client_server/thirdparty.rs | 2 +- src/api/client_server/to_device.rs | 2 +- src/api/client_server/typing.rs | 2 +- src/api/client_server/unversioned.rs | 2 +- src/api/client_server/user_directory.rs | 2 +- src/api/client_server/voip.rs | 2 +- src/api/server_server.rs | 44 +++++++-------- src/database/key_value/users.rs | 10 +--- src/service/rooms/event_handler/mod.rs | 10 ++-- src/service/sending/mod.rs | 8 +-- src/service/uiaa/mod.rs | 12 ++-- src/service/users/data.rs | 10 +--- src/service/users/mod.rs | 10 +--- src/utils/error.rs | 5 +- 41 files changed, 231 insertions(+), 250 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ae1836..a659dec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2053,7 +2053,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.7.4" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "assign", "js_int", @@ -2071,7 +2071,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.7.0" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "js_int", "ruma-common", @@ -2082,7 +2082,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.15.3" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "assign", "bytes", @@ -2099,7 +2099,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.10.5" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "base64", "bytes", @@ -2127,7 +2127,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "js_int", "ruma-common", @@ -2138,7 +2138,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "js_int", "thiserror", @@ -2147,7 +2147,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "js_int", "ruma-common", @@ -2157,7 +2157,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.10.5" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "once_cell", "proc-macro-crate", @@ -2172,7 +2172,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "js_int", "ruma-common", @@ -2183,7 +2183,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.12.0" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "base64", "ed25519-dalek", @@ -2199,7 +2199,7 @@ dependencies = [ [[package]] name = "ruma-state-res" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=2bd5c131f49b2239750c39ed63b623cd5a01c965#2bd5c131f49b2239750c39ed63b623cd5a01c965" +source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" dependencies = [ "itertools", "js_int", diff --git a/Cargo.toml b/Cargo.toml index 801d363..87102c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ tower-http = { version = "0.3.4", features = ["add-extension", "cors", "compress # Used for matrix spec type definitions and helpers #ruma = { version = "0.4.0", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } -ruma = { git = "https://github.com/ruma/ruma", rev = "2bd5c131f49b2239750c39ed63b623cd5a01c965", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "af28dc8339773e5cad460289fa3c4e22d9a058cd", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "50c1db7e0a3a21fc794b0cce3b64285a4c750c71", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } diff --git a/src/api/client_server/account.rs b/src/api/client_server/account.rs index 309a361..50a6a18 100644 --- a/src/api/client_server/account.rs +++ b/src/api/client_server/account.rs @@ -30,7 +30,7 @@ const RANDOM_USER_ID_LENGTH: usize = 10; /// /// Note: This will not reserve the username, so the username might become invalid when trying to register pub async fn get_register_available_route( - body: Ruma, + body: Ruma, ) -> Result { // Validate user id let user_id = UserId::parse_with_server_name( @@ -73,9 +73,7 @@ pub async fn get_register_available_route( /// - If type is not guest and no username is given: Always fails after UIAA check /// - Creates a new account and populates it with default account data /// - If `inhibit_login` is false: Creates a device and returns device id and access_token -pub async fn register_route( - body: Ruma, -) -> Result { +pub async fn register_route(body: Ruma) -> Result { if !services().globals.allow_registration() && !body.from_appservice { return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -266,7 +264,7 @@ pub async fn register_route( /// - Forgets to-device events /// - Triggers device list updates pub async fn change_password_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); @@ -354,7 +352,7 @@ pub async fn whoami_route(body: Ruma) -> Result, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); @@ -426,7 +424,7 @@ pub async fn third_party_route( /// /// - 403 signals that The homeserver does not allow the third party identifier as a contact option. pub async fn request_3pid_management_token_via_email_route( - _body: Ruma, + _body: Ruma, ) -> Result { Err(Error::BadRequest( ErrorKind::ThreepidDenied, @@ -440,7 +438,7 @@ pub async fn request_3pid_management_token_via_email_route( /// /// - 403 signals that The homeserver does not allow the third party identifier as a contact option. pub async fn request_3pid_management_token_via_msisdn_route( - _body: Ruma, + _body: Ruma, ) -> Result { Err(Error::BadRequest( ErrorKind::ThreepidDenied, diff --git a/src/api/client_server/alias.rs b/src/api/client_server/alias.rs index b28606c..ab51b50 100644 --- a/src/api/client_server/alias.rs +++ b/src/api/client_server/alias.rs @@ -9,14 +9,14 @@ use ruma::{ }, federation, }, - RoomAliasId, + OwnedRoomAliasId, }; /// # `PUT /_matrix/client/r0/directory/room/{roomAlias}` /// /// Creates a new room alias on this server. pub async fn create_alias_route( - body: Ruma, + body: Ruma, ) -> Result { if body.room_alias.server_name() != services().globals.server_name() { return Err(Error::BadRequest( @@ -49,7 +49,7 @@ pub async fn create_alias_route( /// - TODO: additional access control checks /// - TODO: Update canonical alias event pub async fn delete_alias_route( - body: Ruma, + body: Ruma, ) -> Result { if body.room_alias.server_name() != services().globals.server_name() { return Err(Error::BadRequest( @@ -71,18 +71,22 @@ pub async fn delete_alias_route( /// /// - TODO: Suggest more servers to join via pub async fn get_alias_route( - body: Ruma, + body: Ruma, ) -> Result { - get_alias_helper(&body.room_alias).await + get_alias_helper(body.body.room_alias).await } -pub(crate) async fn get_alias_helper(room_alias: &RoomAliasId) -> Result { +pub(crate) async fn get_alias_helper( + room_alias: OwnedRoomAliasId, +) -> Result { if room_alias.server_name() != services().globals.server_name() { let response = services() .sending .send_federation_request( room_alias.server_name(), - federation::query::get_room_information::v1::Request { room_alias }, + federation::query::get_room_information::v1::Request { + room_alias: room_alias.to_owned(), + }, ) .await?; @@ -93,7 +97,7 @@ pub(crate) async fn get_alias_helper(room_alias: &RoomAliasId) -> Result room_id = Some(r), None => { for (_id, registration) in services().appservice.all()? { @@ -115,7 +119,9 @@ pub(crate) async fn get_alias_helper(room_alias: &RoomAliasId) -> Result Result, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); services() @@ -66,7 +66,7 @@ pub async fn get_latest_backup_info_route( /// /// Get information about an existing backup. pub async fn get_backup_info_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let algorithm = services() @@ -96,7 +96,7 @@ pub async fn get_backup_info_route( /// /// - Deletes both information about the backup, as well as all key data related to the backup pub async fn delete_backup_version_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -115,7 +115,7 @@ pub async fn delete_backup_version_route( /// - Adds the keys to the backup /// - Returns the new number of keys in this backup and the etag pub async fn add_backup_keys_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -162,7 +162,7 @@ pub async fn add_backup_keys_route( /// - Adds the keys to the backup /// - Returns the new number of keys in this backup and the etag pub async fn add_backup_keys_for_room_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -207,7 +207,7 @@ pub async fn add_backup_keys_for_room_route( /// - Adds the keys to the backup /// - Returns the new number of keys in this backup and the etag pub async fn add_backup_keys_for_session_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -246,7 +246,7 @@ pub async fn add_backup_keys_for_session_route( /// /// Retrieves all keys from the backup. pub async fn get_backup_keys_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -259,7 +259,7 @@ pub async fn get_backup_keys_route( /// /// Retrieves all keys from the backup for a given room. pub async fn get_backup_keys_for_room_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -274,7 +274,7 @@ pub async fn get_backup_keys_for_room_route( /// /// Retrieves a key from the backup. pub async fn get_backup_keys_for_session_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -293,7 +293,7 @@ pub async fn get_backup_keys_for_session_route( /// /// Delete the keys from the backup. pub async fn delete_backup_keys_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -316,7 +316,7 @@ pub async fn delete_backup_keys_route( /// /// Delete the keys from the backup for a given room. pub async fn delete_backup_keys_for_room_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -339,7 +339,7 @@ pub async fn delete_backup_keys_for_room_route( /// /// Delete a key from the backup. pub async fn delete_backup_keys_for_session_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/capabilities.rs b/src/api/client_server/capabilities.rs index 31d42d2..233e3c9 100644 --- a/src/api/client_server/capabilities.rs +++ b/src/api/client_server/capabilities.rs @@ -8,7 +8,7 @@ use std::collections::BTreeMap; /// /// Get information on the supported feature set and other relevent capabilities of this server. pub async fn get_capabilities_route( - _body: Ruma, + _body: Ruma, ) -> Result { let mut available = BTreeMap::new(); for room_version in &services().globals.unstable_room_versions { diff --git a/src/api/client_server/config.rs b/src/api/client_server/config.rs index dbd2b2c..12f9aea 100644 --- a/src/api/client_server/config.rs +++ b/src/api/client_server/config.rs @@ -17,7 +17,7 @@ use serde_json::{json, value::RawValue as RawJsonValue}; /// /// Sets some account data for the sender user. pub async fn set_global_account_data_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -43,7 +43,7 @@ pub async fn set_global_account_data_route( /// /// Sets some room account data for the sender user. pub async fn set_room_account_data_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -69,7 +69,7 @@ pub async fn set_room_account_data_route( /// /// Gets some account data for the sender user. pub async fn get_global_account_data_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -89,7 +89,7 @@ pub async fn get_global_account_data_route( /// /// Gets some room account data for the sender user. pub async fn get_room_account_data_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/context.rs b/src/api/client_server/context.rs index 2e0f257..1e62f91 100644 --- a/src/api/client_server/context.rs +++ b/src/api/client_server/context.rs @@ -13,7 +13,7 @@ use tracing::error; /// - Only works if the user is joined (TODO: always allow, but only show events if the user was /// joined, depending on history_visibility) pub async fn get_context_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/device.rs b/src/api/client_server/device.rs index d4c4178..aba061b 100644 --- a/src/api/client_server/device.rs +++ b/src/api/client_server/device.rs @@ -28,7 +28,7 @@ pub async fn get_devices_route( /// /// Get metadata on a single device of the sender user. pub async fn get_device_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -44,7 +44,7 @@ pub async fn get_device_route( /// /// Updates the metadata on a given device of the sender user. pub async fn update_device_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -72,7 +72,7 @@ pub async fn update_device_route( /// - Forgets to-device events /// - Triggers device list updates pub async fn delete_device_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); @@ -126,7 +126,7 @@ pub async fn delete_device_route( /// - Forgets to-device events /// - Triggers device list updates pub async fn delete_devices_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/directory.rs b/src/api/client_server/directory.rs index f07a225..645710f 100644 --- a/src/api/client_server/directory.rs +++ b/src/api/client_server/directory.rs @@ -11,10 +11,7 @@ use ruma::{ }, federation, }, - directory::{ - Filter, IncomingFilter, IncomingRoomNetwork, PublicRoomJoinRule, PublicRoomsChunk, - RoomNetwork, - }, + directory::{Filter, PublicRoomJoinRule, PublicRoomsChunk, RoomNetwork}, events::{ room::{ avatar::RoomAvatarEventContent, @@ -38,7 +35,7 @@ use tracing::{error, info, warn}; /// /// - Rooms are ordered by the number of joined members pub async fn get_public_rooms_filtered_route( - body: Ruma, + body: Ruma, ) -> Result { get_public_rooms_filtered_helper( body.server.as_deref(), @@ -56,14 +53,14 @@ pub async fn get_public_rooms_filtered_route( /// /// - Rooms are ordered by the number of joined members pub async fn get_public_rooms_route( - body: Ruma, + body: Ruma, ) -> Result { let response = get_public_rooms_filtered_helper( body.server.as_deref(), body.limit, body.since.as_deref(), - &IncomingFilter::default(), - &IncomingRoomNetwork::Matrix, + &Filter::default(), + &RoomNetwork::Matrix, ) .await?; @@ -81,7 +78,7 @@ pub async fn get_public_rooms_route( /// /// - TODO: Access control checks pub async fn set_room_visibility_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -111,7 +108,7 @@ pub async fn set_room_visibility_route( /// /// Gets the visibility of a given room in the room directory. pub async fn get_room_visibility_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().rooms.metadata.exists(&body.room_id)? { // Return 404 if the room doesn't exist @@ -131,8 +128,8 @@ pub(crate) async fn get_public_rooms_filtered_helper( server: Option<&ServerName>, limit: Option, since: Option<&str>, - filter: &IncomingFilter, - _network: &IncomingRoomNetwork, + filter: &Filter, + _network: &RoomNetwork, ) -> Result { if let Some(other_server) = server.filter(|server| *server != services().globals.server_name().as_str()) @@ -143,9 +140,9 @@ pub(crate) async fn get_public_rooms_filtered_helper( other_server, federation::directory::get_public_rooms_filtered::v1::Request { limit, - since, + since: since.map(ToOwned::to_owned), filter: Filter { - generic_search_term: filter.generic_search_term.as_deref(), + generic_search_term: filter.generic_search_term.clone(), room_types: filter.room_types.clone(), }, room_network: RoomNetwork::Matrix, diff --git a/src/api/client_server/filter.rs b/src/api/client_server/filter.rs index a0d5a19..e9a359d 100644 --- a/src/api/client_server/filter.rs +++ b/src/api/client_server/filter.rs @@ -10,7 +10,7 @@ use ruma::api::client::{ /// /// - A user can only access their own filters pub async fn get_filter_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let filter = match services().users.get_filter(sender_user, &body.filter_id)? { @@ -25,7 +25,7 @@ pub async fn get_filter_route( /// /// Creates a new filter to be used by other endpoints. pub async fn create_filter_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); Ok(create_filter::v3::Response::new( diff --git a/src/api/client_server/keys.rs b/src/api/client_server/keys.rs index b649166..ba89ece 100644 --- a/src/api/client_server/keys.rs +++ b/src/api/client_server/keys.rs @@ -65,9 +65,7 @@ pub async fn upload_keys_route( /// - Always fetches users from other servers over federation /// - Gets master keys, self-signing keys, user signing keys and device keys. /// - The master and self-signing keys contain signatures that the user is allowed to see -pub async fn get_keys_route( - body: Ruma, -) -> Result { +pub async fn get_keys_route(body: Ruma) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let response = @@ -93,7 +91,7 @@ pub async fn claim_keys_route( /// /// - Requires UIAA to verify password pub async fn upload_signing_keys_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); @@ -214,7 +212,7 @@ pub async fn upload_signatures_route( /// /// - TODO: left users pub async fn get_key_changes_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/media.rs b/src/api/client_server/media.rs index fa6def0..3410cc0 100644 --- a/src/api/client_server/media.rs +++ b/src/api/client_server/media.rs @@ -27,7 +27,7 @@ pub async fn get_media_config_route( /// - Some metadata will be saved in the database /// - Media will be saved in the media/ directory pub async fn create_content_route( - body: Ruma, + body: Ruma, ) -> Result { let mxc = format!( "mxc://{}/{}", @@ -57,7 +57,7 @@ pub async fn create_content_route( pub async fn get_remote_content( mxc: &str, server_name: &ruma::ServerName, - media_id: &str, + media_id: String, ) -> Result { let content_response = services() .sending @@ -65,7 +65,7 @@ pub async fn get_remote_content( server_name, get_content::v3::Request { allow_remote: false, - server_name, + server_name: server_name.to_owned(), media_id, }, ) @@ -90,7 +90,7 @@ pub async fn get_remote_content( /// /// - Only allows federation if `allow_remote` is true pub async fn get_content_route( - body: Ruma, + body: Ruma, ) -> Result { let mxc = format!("mxc://{}/{}", body.server_name, body.media_id); @@ -108,7 +108,7 @@ pub async fn get_content_route( }) } else if &*body.server_name != services().globals.server_name() && body.allow_remote { let remote_content_response = - get_remote_content(&mxc, &body.server_name, &body.media_id).await?; + get_remote_content(&mxc, &body.server_name, body.media_id.clone()).await?; Ok(remote_content_response) } else { Err(Error::BadRequest(ErrorKind::NotFound, "Media not found.")) @@ -121,7 +121,7 @@ pub async fn get_content_route( /// /// - Only allows federation if `allow_remote` is true pub async fn get_content_as_filename_route( - body: Ruma, + body: Ruma, ) -> Result { let mxc = format!("mxc://{}/{}", body.server_name, body.media_id); @@ -139,7 +139,7 @@ pub async fn get_content_as_filename_route( }) } else if &*body.server_name != services().globals.server_name() && body.allow_remote { let remote_content_response = - get_remote_content(&mxc, &body.server_name, &body.media_id).await?; + get_remote_content(&mxc, &body.server_name, body.media_id.clone()).await?; Ok(get_content_as_filename::v3::Response { content_disposition: Some(format!("inline: filename={}", body.filename)), @@ -158,7 +158,7 @@ pub async fn get_content_as_filename_route( /// /// - Only allows federation if `allow_remote` is true pub async fn get_content_thumbnail_route( - body: Ruma, + body: Ruma, ) -> Result { let mxc = format!("mxc://{}/{}", body.server_name, body.media_id); @@ -192,8 +192,8 @@ pub async fn get_content_thumbnail_route( height: body.height, width: body.width, method: body.method.clone(), - server_name: &body.server_name, - media_id: &body.media_id, + server_name: body.server_name.clone(), + media_id: body.media_id.clone(), }, ) .await?; diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index f6e94e6..8674a60 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -5,7 +5,7 @@ use ruma::{ membership::{ ban_user, forget_room, get_member_events, invite_user, join_room_by_id, join_room_by_id_or_alias, joined_members, joined_rooms, kick_user, leave_room, - unban_user, IncomingThirdPartySigned, + unban_user, ThirdPartySigned, }, }, federation::{self, membership::create_invite}, @@ -44,7 +44,7 @@ use super::get_alias_helper; /// - If the server knowns about this room: creates the join event and does auth rules locally /// - If the server does not know about the room: asks other servers over federation pub async fn join_room_by_id_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -81,7 +81,7 @@ pub async fn join_room_by_id_route( /// - If the server knowns about this room: creates the join event and does auth rules locally /// - If the server does not know about the room: asks other servers over federation pub async fn join_room_by_id_or_alias_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_deref().expect("user is authenticated"); let body = body.body; @@ -107,7 +107,7 @@ pub async fn join_room_by_id_or_alias_route( (servers, room_id) } Err(room_alias) => { - let response = get_alias_helper(&room_alias).await?; + let response = get_alias_helper(room_alias).await?; (response.servers.into_iter().collect(), response.room_id) } @@ -132,7 +132,7 @@ pub async fn join_room_by_id_or_alias_route( /// /// - This should always work if the user is currently joined. pub async fn leave_room_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -145,11 +145,11 @@ pub async fn leave_room_route( /// /// Tries to send an invite event into the room. pub async fn invite_user_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - if let invite_user::v3::IncomingInvitationRecipient::UserId { user_id } = &body.recipient { + if let invite_user::v3::InvitationRecipient::UserId { user_id } = &body.recipient { invite_helper(sender_user, user_id, &body.room_id, false).await?; Ok(invite_user::v3::Response {}) } else { @@ -161,7 +161,7 @@ pub async fn invite_user_route( /// /// Tries to send a kick event into the room. pub async fn kick_user_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -218,9 +218,7 @@ pub async fn kick_user_route( /// # `POST /_matrix/client/r0/rooms/{roomId}/ban` /// /// Tries to send a ban event into the room. -pub async fn ban_user_route( - body: Ruma, -) -> Result { +pub async fn ban_user_route(body: Ruma) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); // TODO: reason @@ -287,7 +285,7 @@ pub async fn ban_user_route( /// /// Tries to send an unban event into the room. pub async fn unban_user_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -349,7 +347,7 @@ pub async fn unban_user_route( /// Note: Other devices of the user have no way of knowing the room was forgotten, so this has to /// be called from every device pub async fn forget_room_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -385,7 +383,7 @@ pub async fn joined_rooms_route( /// /// - Only works if the user is currently joined pub async fn get_member_events_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -421,7 +419,7 @@ pub async fn get_member_events_route( /// - The sender user must be in the room /// - TODO: An appservice just needs a puppet joined pub async fn joined_members_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -462,7 +460,7 @@ async fn join_room_by_id_helper( sender_user: Option<&UserId>, room_id: &RoomId, servers: &[OwnedServerName], - _third_party_signed: Option<&IncomingThirdPartySigned>, + _third_party_signed: Option<&ThirdPartySigned>, ) -> Result { let sender_user = sender_user.expect("user is authenticated"); @@ -575,9 +573,9 @@ async fn join_room_by_id_helper( .send_federation_request( &remote_server, federation::membership::create_join_event::v2::Request { - room_id, - event_id, - pdu: &PduEvent::convert_to_outgoing_federation_event(join_event.clone()), + room_id: room_id.to_owned(), + event_id: event_id.to_owned(), + pdu: PduEvent::convert_to_outgoing_federation_event(join_event.clone()), }, ) .await?; @@ -896,9 +894,9 @@ async fn join_room_by_id_helper( .send_federation_request( &remote_server, federation::membership::create_join_event::v2::Request { - room_id, - event_id, - pdu: &PduEvent::convert_to_outgoing_federation_event(join_event.clone()), + room_id: room_id.to_owned(), + event_id: event_id.to_owned(), + pdu: PduEvent::convert_to_outgoing_federation_event(join_event.clone()), }, ) .await?; @@ -969,9 +967,9 @@ async fn make_join_request( .send_federation_request( remote_server, federation::membership::prepare_join_event::v1::Request { - room_id, - user_id: sender_user, - ver: &services().globals.supported_room_versions(), + room_id: room_id.to_owned(), + user_id: sender_user.to_owned(), + ver: services().globals.supported_room_versions(), }, ) .await; @@ -1105,18 +1103,18 @@ pub(crate) async fn invite_helper<'a>( (pdu, pdu_json, invite_room_state) }; - let room_version_id = &services().rooms.state.get_room_version(room_id)?; + let room_version_id = services().rooms.state.get_room_version(room_id)?; let response = services() .sending .send_federation_request( user_id.server_name(), create_invite::v2::Request { - room_id, - event_id: &pdu.event_id, - room_version: &room_version_id, - event: &PduEvent::convert_to_outgoing_federation_event(pdu_json.clone()), - invite_room_state: &invite_room_state, + room_id: room_id.to_owned(), + event_id: (&*pdu.event_id).to_owned(), + room_version: room_version_id.clone(), + event: PduEvent::convert_to_outgoing_federation_event(pdu_json.clone()), + invite_room_state, }, ) .await?; @@ -1124,7 +1122,7 @@ pub(crate) async fn invite_helper<'a>( let pub_key_map = RwLock::new(BTreeMap::new()); // We do not add the event_id field to the pdu here because of signature and hashes checks - let (event_id, value) = match gen_event_id_canonical_json(&response.event, room_version_id) + let (event_id, value) = match gen_event_id_canonical_json(&response.event, &room_version_id) { Ok(t) => t, Err(_) => { @@ -1136,7 +1134,7 @@ pub(crate) async fn invite_helper<'a>( } }; - if pdu.event_id != event_id { + if *pdu.event_id != *event_id { warn!("Server {} changed invite event, that's not allowed in the spec: ours: {:?}, theirs: {:?}", user_id.server_name(), pdu_json, value); } @@ -1363,7 +1361,10 @@ async fn remote_leave_room(user_id: &UserId, room_id: &RoomId) -> Result<()> { .sending .send_federation_request( &remote_server, - federation::membership::prepare_leave_event::v1::Request { room_id, user_id }, + federation::membership::prepare_leave_event::v1::Request { + room_id: room_id.to_owned(), + user_id: user_id.to_owned(), + }, ) .await; @@ -1440,9 +1441,9 @@ async fn remote_leave_room(user_id: &UserId, room_id: &RoomId) -> Result<()> { .send_federation_request( &remote_server, federation::membership::create_leave_event::v2::Request { - room_id, - event_id: &event_id, - pdu: &PduEvent::convert_to_outgoing_federation_event(leave_event.clone()), + room_id: room_id.to_owned(), + event_id, + pdu: PduEvent::convert_to_outgoing_federation_event(leave_event.clone()), }, ) .await?; diff --git a/src/api/client_server/message.rs b/src/api/client_server/message.rs index b04c262..6ad0751 100644 --- a/src/api/client_server/message.rs +++ b/src/api/client_server/message.rs @@ -19,7 +19,7 @@ use std::{ /// - The only requirement for the content is that it has to be valid json /// - Tries to send the event into the room, auth rules will determine if it is allowed pub async fn send_message_event_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_deref(); @@ -105,7 +105,7 @@ pub async fn send_message_event_route( /// - Only works if the user is joined (TODO: always allow, but only show events where the user was /// joined, depending on history_visibility) pub async fn get_message_events_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/presence.rs b/src/api/client_server/presence.rs index dfac3db..ef88d1a 100644 --- a/src/api/client_server/presence.rs +++ b/src/api/client_server/presence.rs @@ -6,7 +6,7 @@ use std::time::Duration; /// /// Sets the presence state of the sender user. pub async fn set_presence_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -43,7 +43,7 @@ pub async fn set_presence_route( /// /// - Only works if you share a room with the user pub async fn get_presence_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/profile.rs b/src/api/client_server/profile.rs index 5ace177..6400e89 100644 --- a/src/api/client_server/profile.rs +++ b/src/api/client_server/profile.rs @@ -20,7 +20,7 @@ use std::sync::Arc; /// /// - Also makes sure other users receive the update using presence EDUs pub async fn set_displayname_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -121,7 +121,7 @@ pub async fn set_displayname_route( /// /// - If user is on another server: Fetches displayname over federation pub async fn get_displayname_route( - body: Ruma, + body: Ruma, ) -> Result { if body.user_id.server_name() != services().globals.server_name() { let response = services() @@ -129,8 +129,8 @@ pub async fn get_displayname_route( .send_federation_request( body.user_id.server_name(), federation::query::get_profile_information::v1::Request { - user_id: &body.user_id, - field: Some(&ProfileField::DisplayName), + user_id: body.user_id.clone(), + field: Some(ProfileField::DisplayName), }, ) .await?; @@ -151,7 +151,7 @@ pub async fn get_displayname_route( /// /// - Also makes sure other users receive the update using presence EDUs pub async fn set_avatar_url_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -256,7 +256,7 @@ pub async fn set_avatar_url_route( /// /// - If user is on another server: Fetches avatar_url and blurhash over federation pub async fn get_avatar_url_route( - body: Ruma, + body: Ruma, ) -> Result { if body.user_id.server_name() != services().globals.server_name() { let response = services() @@ -264,8 +264,8 @@ pub async fn get_avatar_url_route( .send_federation_request( body.user_id.server_name(), federation::query::get_profile_information::v1::Request { - user_id: &body.user_id, - field: Some(&ProfileField::AvatarUrl), + user_id: body.user_id.clone(), + field: Some(ProfileField::AvatarUrl), }, ) .await?; @@ -288,7 +288,7 @@ pub async fn get_avatar_url_route( /// /// - If user is on another server: Fetches profile over federation pub async fn get_profile_route( - body: Ruma, + body: Ruma, ) -> Result { if body.user_id.server_name() != services().globals.server_name() { let response = services() @@ -296,7 +296,7 @@ pub async fn get_profile_route( .send_federation_request( body.user_id.server_name(), federation::query::get_profile_information::v1::Request { - user_id: &body.user_id, + user_id: body.user_id.clone(), field: None, }, ) diff --git a/src/api/client_server/push.rs b/src/api/client_server/push.rs index dc936a6..affd8e8 100644 --- a/src/api/client_server/push.rs +++ b/src/api/client_server/push.rs @@ -5,7 +5,7 @@ use ruma::{ push::{ delete_pushrule, get_pushers, get_pushrule, get_pushrule_actions, get_pushrule_enabled, get_pushrules_all, set_pusher, set_pushrule, set_pushrule_actions, - set_pushrule_enabled, RuleKind, + set_pushrule_enabled, RuleKind, RuleScope, }, }, events::{push_rules::PushRulesEvent, GlobalAccountDataEventType}, @@ -45,7 +45,7 @@ pub async fn get_pushrules_all_route( /// /// Retrieves a single specified push rule for this user. pub async fn get_pushrule_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -104,12 +104,12 @@ pub async fn get_pushrule_route( /// /// Creates a single specified push rule for this user. pub async fn set_pushrule_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let body = body.body; - if body.scope != "global" { + if body.scope != RuleScope::Global { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Scopes other than 'global' are not supported.", @@ -208,7 +208,7 @@ pub async fn set_pushrule_route( /// /// Gets the actions of a single specified push rule for this user. pub async fn get_pushrule_actions_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -269,11 +269,11 @@ pub async fn get_pushrule_actions_route( /// /// Sets the actions of a single specified push rule for this user. pub async fn set_pushrule_actions_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - if body.scope != "global" { + if body.scope != RuleScope::Global { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Scopes other than 'global' are not supported.", @@ -344,11 +344,11 @@ pub async fn set_pushrule_actions_route( /// /// Gets the enabled status of a single specified push rule for this user. pub async fn get_pushrule_enabled_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - if body.scope != "global" { + if body.scope != RuleScope::Global { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Scopes other than 'global' are not supported.", @@ -407,11 +407,11 @@ pub async fn get_pushrule_enabled_route( /// /// Sets the enabled status of a single specified push rule for this user. pub async fn set_pushrule_enabled_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - if body.scope != "global" { + if body.scope != RuleScope::Global { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Scopes other than 'global' are not supported.", @@ -487,11 +487,11 @@ pub async fn set_pushrule_enabled_route( /// /// Deletes a single specified push rule for this user. pub async fn delete_pushrule_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - if body.scope != "global" { + if body.scope != RuleScope::Global { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Scopes other than 'global' are not supported.", diff --git a/src/api/client_server/read_marker.rs b/src/api/client_server/read_marker.rs index d529c6a..b12468a 100644 --- a/src/api/client_server/read_marker.rs +++ b/src/api/client_server/read_marker.rs @@ -16,7 +16,7 @@ use std::collections::BTreeMap; /// - Updates fully-read account data event to `fully_read` /// - If `read_receipt` is set: Update private marker and public read receipt EDU pub async fn set_read_marker_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -89,7 +89,7 @@ pub async fn set_read_marker_route( /// /// Sets private read marker and public read receipt EDU. pub async fn create_receipt_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/redact.rs b/src/api/client_server/redact.rs index ab586c0..a29a561 100644 --- a/src/api/client_server/redact.rs +++ b/src/api/client_server/redact.rs @@ -14,7 +14,7 @@ use serde_json::value::to_raw_value; /// /// - TODO: Handle txn id pub async fn redact_event_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let body = body.body; diff --git a/src/api/client_server/report.rs b/src/api/client_server/report.rs index e45820e..ab5027c 100644 --- a/src/api/client_server/report.rs +++ b/src/api/client_server/report.rs @@ -10,7 +10,7 @@ use ruma::{ /// Reports an inappropriate event to homeserver admins /// pub async fn report_event_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/room.rs b/src/api/client_server/room.rs index 097f0e1..c77cfa9 100644 --- a/src/api/client_server/room.rs +++ b/src/api/client_server/room.rs @@ -46,7 +46,7 @@ use tracing::{info, warn}; /// - Send events implied by `name` and `topic` /// - Send invite events pub async fn create_room_route( - body: Ruma, + body: Ruma, ) -> Result { use create_room::v3::RoomPreset; @@ -421,7 +421,7 @@ pub async fn create_room_route( /// /// - You have to currently be joined to the room (TODO: Respect history visibility) pub async fn get_room_event_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -452,7 +452,7 @@ pub async fn get_room_event_route( /// /// - Only users joined to the room are allowed to call this TODO: Allow any user to call it if history_visibility is world readable pub async fn get_room_aliases_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -488,7 +488,7 @@ pub async fn get_room_aliases_route( /// - Moves local aliases /// - Modifies old room power levels to prevent users from speaking pub async fn upgrade_room_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/search.rs b/src/api/client_server/search.rs index 5b634a4..51255d5 100644 --- a/src/api/client_server/search.rs +++ b/src/api/client_server/search.rs @@ -15,7 +15,7 @@ use std::collections::BTreeMap; /// /// - Only works if the user is currently joined to the room (TODO: Respect history visibility) pub async fn search_events_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/session.rs b/src/api/client_server/session.rs index 7c8c128..64c0072 100644 --- a/src/api/client_server/session.rs +++ b/src/api/client_server/session.rs @@ -4,7 +4,7 @@ use ruma::{ api::client::{ error::ErrorKind, session::{get_login_types, login, logout, logout_all}, - uiaa::IncomingUserIdentifier, + uiaa::UserIdentifier, }, UserId, }; @@ -22,7 +22,7 @@ struct Claims { /// Get the supported login types of this server. One of these should be used as the `type` field /// when logging in. pub async fn get_login_types_route( - _body: Ruma, + _body: Ruma, ) -> Result { Ok(get_login_types::v3::Response::new(vec![ get_login_types::v3::LoginType::Password(Default::default()), @@ -40,15 +40,15 @@ pub async fn get_login_types_route( /// /// Note: You can use [`GET /_matrix/client/r0/login`](fn.get_supported_versions_route.html) to see /// supported login types. -pub async fn login_route(body: Ruma) -> Result { +pub async fn login_route(body: Ruma) -> Result { // Validate login method // TODO: Other login methods let user_id = match &body.login_info { - login::v3::IncomingLoginInfo::Password(login::v3::IncomingPassword { + login::v3::LoginInfo::Password(login::v3::Password { identifier, password, }) => { - let username = if let IncomingUserIdentifier::UserIdOrLocalpart(user_id) = identifier { + let username = if let UserIdentifier::UserIdOrLocalpart(user_id) = identifier { user_id.to_lowercase() } else { return Err(Error::BadRequest(ErrorKind::Forbidden, "Bad login type.")); @@ -84,7 +84,7 @@ pub async fn login_route(body: Ruma) -> Result { + login::v3::LoginInfo::Token(login::v3::Token { token }) => { if let Some(jwt_decoding_key) = services().globals.jwt_decoding_key() { let token = jsonwebtoken::decode::( token, diff --git a/src/api/client_server/state.rs b/src/api/client_server/state.rs index 36466b8..d9c1464 100644 --- a/src/api/client_server/state.rs +++ b/src/api/client_server/state.rs @@ -25,7 +25,7 @@ use ruma::{ /// - Tries to send the event into the room, auth rules will determine if it is allowed /// - If event is new canonical_alias: Rejects if alias is incorrect pub async fn send_state_event_for_key_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -50,7 +50,7 @@ pub async fn send_state_event_for_key_route( /// - Tries to send the event into the room, auth rules will determine if it is allowed /// - If event is new canonical_alias: Rejects if alias is incorrect pub async fn send_state_event_for_empty_key_route( - body: Ruma, + body: Ruma, ) -> Result> { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -81,7 +81,7 @@ pub async fn send_state_event_for_empty_key_route( /// /// - If not joined: Only works if current room history visibility is world readable pub async fn get_state_events_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -133,7 +133,7 @@ pub async fn get_state_events_route( /// /// - If not joined: Only works if current room history visibility is world readable pub async fn get_state_events_for_key_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -188,7 +188,7 @@ pub async fn get_state_events_for_key_route( /// /// - If not joined: Only works if current room history visibility is world readable pub async fn get_state_events_for_empty_key_route( - body: Ruma, + body: Ruma, ) -> Result> { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 94e4f5b..43ca238 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1,7 +1,7 @@ use crate::{services, Error, Result, Ruma, RumaResponse}; use ruma::{ api::client::{ - filter::{IncomingFilterDefinition, LazyLoadOptions}, + filter::{FilterDefinition, LazyLoadOptions}, sync::sync_events::{self, DeviceLists, UnreadNotificationsCount}, uiaa::UiaaResponse, }, @@ -55,7 +55,7 @@ use tracing::error; /// - Sync is handled in an async task, multiple requests from the same device with the same /// `since` will be cached pub async fn sync_events_route( - body: Ruma, + body: Ruma, ) -> Result> { let sender_user = body.sender_user.expect("user is authenticated"); let sender_device = body.sender_device.expect("user is authenticated"); @@ -124,7 +124,7 @@ pub async fn sync_events_route( async fn sync_helper_wrapper( sender_user: OwnedUserId, sender_device: OwnedDeviceId, - body: sync_events::v3::IncomingRequest, + body: sync_events::v3::Request, tx: Sender>>, ) { let since = body.since.clone(); @@ -157,12 +157,12 @@ async fn sync_helper_wrapper( async fn sync_helper( sender_user: OwnedUserId, sender_device: OwnedDeviceId, - body: sync_events::v3::IncomingRequest, + body: sync_events::v3::Request, // bool = caching allowed ) -> Result<(sync_events::v3::Response, bool), Error> { use sync_events::v3::{ - Ephemeral, GlobalAccountData, IncomingFilter, InviteState, InvitedRoom, JoinedRoom, - LeftRoom, Presence, RoomAccountData, RoomSummary, Rooms, State, Timeline, ToDevice, + Ephemeral, Filter, GlobalAccountData, InviteState, InvitedRoom, JoinedRoom, LeftRoom, + Presence, RoomAccountData, RoomSummary, Rooms, State, Timeline, ToDevice, }; // TODO: match body.set_presence { @@ -176,9 +176,9 @@ async fn sync_helper( // Load filter let filter = match body.filter { - None => IncomingFilterDefinition::default(), - Some(IncomingFilter::FilterDefinition(filter)) => filter, - Some(IncomingFilter::FilterId(filter_id)) => services() + None => FilterDefinition::default(), + Some(Filter::FilterDefinition(filter)) => filter, + Some(Filter::FilterId(filter_id)) => services() .users .get_filter(&sender_user, &filter_id)? .unwrap_or_default(), diff --git a/src/api/client_server/tag.rs b/src/api/client_server/tag.rs index c87e233..16f1600 100644 --- a/src/api/client_server/tag.rs +++ b/src/api/client_server/tag.rs @@ -14,7 +14,7 @@ use std::collections::BTreeMap; /// /// - Inserts the tag into the tag event of the room account data. pub async fn update_tag_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -58,7 +58,7 @@ pub async fn update_tag_route( /// /// - Removes the tag from the tag event of the room account data. pub async fn delete_tag_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); @@ -98,9 +98,7 @@ pub async fn delete_tag_route( /// Returns tags on the room. /// /// - Gets the tag event of the room account data. -pub async fn get_tags_route( - body: Ruma, -) -> Result { +pub async fn get_tags_route(body: Ruma) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let event = services().account_data.get( diff --git a/src/api/client_server/thirdparty.rs b/src/api/client_server/thirdparty.rs index 5665ad6..c2c1adf 100644 --- a/src/api/client_server/thirdparty.rs +++ b/src/api/client_server/thirdparty.rs @@ -7,7 +7,7 @@ use std::collections::BTreeMap; /// /// TODO: Fetches all metadata about protocols supported by the homeserver. pub async fn get_protocols_route( - _body: Ruma, + _body: Ruma, ) -> Result { // TODO Ok(get_protocols::v3::Response { diff --git a/src/api/client_server/to_device.rs b/src/api/client_server/to_device.rs index 139b845..26db4e4 100644 --- a/src/api/client_server/to_device.rs +++ b/src/api/client_server/to_device.rs @@ -14,7 +14,7 @@ use ruma::{ /// /// Send a to-device event to a set of client devices. pub async fn send_event_to_device_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_device = body.sender_device.as_deref(); diff --git a/src/api/client_server/typing.rs b/src/api/client_server/typing.rs index ecc926f..43217e1 100644 --- a/src/api/client_server/typing.rs +++ b/src/api/client_server/typing.rs @@ -5,7 +5,7 @@ use ruma::api::client::{error::ErrorKind, typing::create_typing_event}; /// /// Sets the typing state of the sender user. pub async fn create_typing_event_route( - body: Ruma, + body: Ruma, ) -> Result { use create_typing_event::v3::Typing; diff --git a/src/api/client_server/unversioned.rs b/src/api/client_server/unversioned.rs index 8a5c3d2..526598b 100644 --- a/src/api/client_server/unversioned.rs +++ b/src/api/client_server/unversioned.rs @@ -15,7 +15,7 @@ use crate::{Result, Ruma}; /// Note: Unstable features are used while developing new features. Clients should avoid using /// unstable features in their stable releases pub async fn get_supported_versions_route( - _body: Ruma, + _body: Ruma, ) -> Result { let resp = get_supported_versions::Response { versions: vec![ diff --git a/src/api/client_server/user_directory.rs b/src/api/client_server/user_directory.rs index 518daa5..c30bac5 100644 --- a/src/api/client_server/user_directory.rs +++ b/src/api/client_server/user_directory.rs @@ -14,7 +14,7 @@ use ruma::{ /// - Hides any local users that aren't in any public rooms (i.e. those that have the join rule set to public) /// and don't share a room with the sender pub async fn search_users_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let limit = u64::from(body.limit) as usize; diff --git a/src/api/client_server/voip.rs b/src/api/client_server/voip.rs index 6b1ee40..4990c17 100644 --- a/src/api/client_server/voip.rs +++ b/src/api/client_server/voip.rs @@ -10,7 +10,7 @@ type HmacSha1 = Hmac; /// /// TODO: Returns information about the recommended turn server. pub async fn turn_server_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 12b255b..2b854a6 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -31,7 +31,7 @@ use ruma::{ EndpointError, IncomingResponse, MatrixVersion, OutgoingRequest, OutgoingResponse, SendAccessToken, }, - directory::{IncomingFilter, IncomingRoomNetwork}, + directory::{Filter, RoomNetwork}, events::{ receipt::{ReceiptEvent, ReceiptEventContent, ReceiptType}, room::{ @@ -294,13 +294,7 @@ where } else { Err(Error::FederationError( destination.to_owned(), - RumaError::try_from_http_response(http_response).map_err(|e| { - warn!( - "Invalid {} response from {} on: {} {}", - status, &destination, url, e - ); - Error::BadServerResponse("Server returned bad error response.") - })?, + RumaError::from_http_response(http_response), )) } } @@ -586,7 +580,7 @@ pub async fn get_server_keys_deprecated_route() -> impl IntoResponse { /// /// Lists the public rooms on this server. pub async fn get_public_rooms_filtered_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -613,7 +607,7 @@ pub async fn get_public_rooms_filtered_route( /// /// Lists the public rooms on this server. pub async fn get_public_rooms_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -623,8 +617,8 @@ pub async fn get_public_rooms_route( None, body.limit, body.since.as_deref(), - &IncomingFilter::default(), - &IncomingRoomNetwork::Matrix, + &Filter::default(), + &RoomNetwork::Matrix, ) .await?; @@ -640,7 +634,7 @@ pub async fn get_public_rooms_route( /// /// Push EDUs and PDUs to this server. pub async fn send_transaction_message_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -916,7 +910,7 @@ pub async fn send_transaction_message_route( /// /// - Only works if a user of this server is currently invited or joined the room pub async fn get_event_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -963,7 +957,7 @@ pub async fn get_event_route( /// /// Retrieves events that the sender is missing. pub async fn get_missing_events_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -1042,7 +1036,7 @@ pub async fn get_missing_events_route( /// /// - This does not include the event itself pub async fn get_event_authorization_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -1101,7 +1095,7 @@ pub async fn get_event_authorization_route( /// /// Retrieves the current state of the room. pub async fn get_room_state_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -1181,7 +1175,7 @@ pub async fn get_room_state_route( /// /// Retrieves the current state of the room. pub async fn get_room_state_ids_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -1242,7 +1236,7 @@ pub async fn get_room_state_ids_route( /// /// Creates a join template. pub async fn create_join_event_template_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -1494,7 +1488,7 @@ async fn create_join_event( /// /// Submits a signed join event. pub async fn create_join_event_v1_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_servername = body .sender_servername @@ -1510,7 +1504,7 @@ pub async fn create_join_event_v1_route( /// /// Submits a signed join event. pub async fn create_join_event_v2_route( - body: Ruma, + body: Ruma, ) -> Result { let sender_servername = body .sender_servername @@ -1526,7 +1520,7 @@ pub async fn create_join_event_v2_route( /// /// Invites a remote user to a room. pub async fn create_invite_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -1643,7 +1637,7 @@ pub async fn create_invite_route( /// /// Gets information on all devices of the user. pub async fn get_devices_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -1690,7 +1684,7 @@ pub async fn get_devices_route( /// /// Resolve a room alias to a room id. pub async fn get_room_information_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); @@ -1715,7 +1709,7 @@ pub async fn get_room_information_route( /// /// Gets information on a profile. pub async fn get_profile_information_route( - body: Ruma, + body: Ruma, ) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); diff --git a/src/database/key_value/users.rs b/src/database/key_value/users.rs index cd5a535..1cabab0 100644 --- a/src/database/key_value/users.rs +++ b/src/database/key_value/users.rs @@ -1,7 +1,7 @@ use std::{collections::BTreeMap, mem::size_of}; use ruma::{ - api::client::{device::Device, error::ErrorKind, filter::IncomingFilterDefinition}, + api::client::{device::Device, error::ErrorKind, filter::FilterDefinition}, encryption::{CrossSigningKey, DeviceKeys, OneTimeKey}, events::{AnyToDeviceEvent, StateEventType}, serde::Raw, @@ -899,7 +899,7 @@ impl service::users::Data for KeyValueDatabase { } /// Creates a new sync filter. Returns the filter id. - fn create_filter(&self, user_id: &UserId, filter: &IncomingFilterDefinition) -> Result { + fn create_filter(&self, user_id: &UserId, filter: &FilterDefinition) -> Result { let filter_id = utils::random_string(4); let mut key = user_id.as_bytes().to_vec(); @@ -914,11 +914,7 @@ impl service::users::Data for KeyValueDatabase { Ok(filter_id) } - fn get_filter( - &self, - user_id: &UserId, - filter_id: &str, - ) -> Result> { + fn get_filter(&self, user_id: &UserId, filter_id: &str) -> Result> { let mut key = user_id.as_bytes().to_vec(); key.push(0xff); key.extend_from_slice(filter_id.as_bytes()); diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index b352647..85d21bf 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -638,8 +638,8 @@ impl Service { .send_federation_request( origin, get_room_state_ids::v1::Request { - room_id, - event_id: &incoming_pdu.event_id, + room_id: room_id.to_owned(), + event_id: (&*incoming_pdu.event_id).to_owned(), }, ) .await @@ -1112,7 +1112,9 @@ impl Service { .sending .send_federation_request( origin, - get_event::v1::Request { event_id: &next_id }, + get_event::v1::Request { + event_id: next_id.into(), + }, ) .await { @@ -1689,7 +1691,7 @@ impl Service { .send_federation_request( server, get_remote_server_keys::v2::Request::new( - origin, + origin.to_owned(), MilliSecondsSinceUnixEpoch::from_system_time( SystemTime::now() .checked_add(Duration::from_secs(3600)) diff --git a/src/service/sending/mod.rs b/src/service/sending/mod.rs index afa12fc..1861feb 100644 --- a/src/service/sending/mod.rs +++ b/src/service/sending/mod.rs @@ -496,7 +496,7 @@ impl Service { ) })?, appservice::event::push_events::v1::Request { - events: &pdu_jsons, + events: pdu_jsons, txn_id: (&*base64::encode_config( calculate_hash( &events @@ -638,9 +638,9 @@ impl Service { let response = server_server::send_request( server, send_transaction_message::v1::Request { - origin: services().globals.server_name(), - pdus: &pdu_jsons, - edus: &edu_jsons, + origin: services().globals.server_name().to_owned(), + pdus: pdu_jsons, + edus: edu_jsons, origin_server_ts: MilliSecondsSinceUnixEpoch::now(), transaction_id: (&*base64::encode_config( calculate_hash( diff --git a/src/service/uiaa/mod.rs b/src/service/uiaa/mod.rs index 672290c..147ce4d 100644 --- a/src/service/uiaa/mod.rs +++ b/src/service/uiaa/mod.rs @@ -5,7 +5,7 @@ pub use data::Data; use ruma::{ api::client::{ error::ErrorKind, - uiaa::{AuthType, IncomingAuthData, IncomingPassword, IncomingUserIdentifier, UiaaInfo}, + uiaa::{AuthData, AuthType, Password, UiaaInfo, UserIdentifier}, }, CanonicalJsonValue, DeviceId, UserId, }; @@ -44,7 +44,7 @@ impl Service { &self, user_id: &UserId, device_id: &DeviceId, - auth: &IncomingAuthData, + auth: &AuthData, uiaainfo: &UiaaInfo, ) -> Result<(bool, UiaaInfo)> { let mut uiaainfo = auth @@ -58,13 +58,13 @@ impl Service { match auth { // Find out what the user completed - IncomingAuthData::Password(IncomingPassword { + AuthData::Password(Password { identifier, password, .. }) => { let username = match identifier { - IncomingUserIdentifier::UserIdOrLocalpart(username) => username, + UserIdentifier::UserIdOrLocalpart(username) => username, _ => { return Err(Error::BadRequest( ErrorKind::Unrecognized, @@ -85,7 +85,7 @@ impl Service { argon2::verify_encoded(&hash, password.as_bytes()).unwrap_or(false); if !hash_matches { - uiaainfo.auth_error = Some(ruma::api::client::error::ErrorBody { + uiaainfo.auth_error = Some(ruma::api::client::error::StandardErrorBody { kind: ErrorKind::Forbidden, message: "Invalid username or password.".to_owned(), }); @@ -96,7 +96,7 @@ impl Service { // Password was correct! Let's add it to `completed` uiaainfo.completed.push(AuthType::Password); } - IncomingAuthData::Dummy(_) => { + AuthData::Dummy(_) => { uiaainfo.completed.push(AuthType::Dummy); } k => error!("type not supported: {:?}", k), diff --git a/src/service/users/data.rs b/src/service/users/data.rs index bc1db33..8553210 100644 --- a/src/service/users/data.rs +++ b/src/service/users/data.rs @@ -1,6 +1,6 @@ use crate::Result; use ruma::{ - api::client::{device::Device, filter::IncomingFilterDefinition}, + api::client::{device::Device, filter::FilterDefinition}, encryption::{CrossSigningKey, DeviceKeys, OneTimeKey}, events::AnyToDeviceEvent, serde::Raw, @@ -191,11 +191,7 @@ pub trait Data: Send + Sync { ) -> Box> + 'a>; /// Creates a new sync filter. Returns the filter id. - fn create_filter(&self, user_id: &UserId, filter: &IncomingFilterDefinition) -> Result; + fn create_filter(&self, user_id: &UserId, filter: &FilterDefinition) -> Result; - fn get_filter( - &self, - user_id: &UserId, - filter_id: &str, - ) -> Result>; + fn get_filter(&self, user_id: &UserId, filter_id: &str) -> Result>; } diff --git a/src/service/users/mod.rs b/src/service/users/mod.rs index 9dcfa8b..6be5c89 100644 --- a/src/service/users/mod.rs +++ b/src/service/users/mod.rs @@ -3,7 +3,7 @@ use std::{collections::BTreeMap, mem}; pub use data::Data; use ruma::{ - api::client::{device::Device, error::ErrorKind, filter::IncomingFilterDefinition}, + api::client::{device::Device, error::ErrorKind, filter::FilterDefinition}, encryption::{CrossSigningKey, DeviceKeys, OneTimeKey}, events::AnyToDeviceEvent, serde::Raw, @@ -326,11 +326,7 @@ impl Service { } /// Creates a new sync filter. Returns the filter id. - pub fn create_filter( - &self, - user_id: &UserId, - filter: &IncomingFilterDefinition, - ) -> Result { + pub fn create_filter(&self, user_id: &UserId, filter: &FilterDefinition) -> Result { self.db.create_filter(user_id, filter) } @@ -338,7 +334,7 @@ impl Service { &self, user_id: &UserId, filter_id: &str, - ) -> Result> { + ) -> Result> { self.db.get_filter(user_id, filter_id) } } diff --git a/src/utils/error.rs b/src/utils/error.rs index 9c8617f..0ef13ce 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -3,7 +3,7 @@ use std::convert::Infallible; use http::StatusCode; use ruma::{ api::client::{ - error::{Error as RumaError, ErrorKind}, + error::{Error as RumaError, ErrorBody, ErrorKind}, uiaa::{UiaaInfo, UiaaResponse}, }, OwnedServerName, @@ -131,8 +131,7 @@ impl Error { warn!("{}: {}", status_code, message); RumaResponse(UiaaResponse::MatrixError(RumaError { - kind, - message, + body: ErrorBody::Standard { kind, message }, status_code, })) } From f1d25746511dfaa16d4316b76d71275bd0a8a35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sat, 17 Dec 2022 09:21:19 +0100 Subject: [PATCH 36/56] finish upgrade ruma --- src/api/client_server/push.rs | 43 +++++++++++++------------- src/main.rs | 8 +++-- src/service/pusher/mod.rs | 18 +++++------ src/service/rooms/event_handler/mod.rs | 2 +- src/service/rooms/state_cache/mod.rs | 2 +- src/utils/error.rs | 5 ++- 6 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/api/client_server/push.rs b/src/api/client_server/push.rs index affd8e8..b044138 100644 --- a/src/api/client_server/push.rs +++ b/src/api/client_server/push.rs @@ -9,7 +9,7 @@ use ruma::{ }, }, events::{push_rules::PushRulesEvent, GlobalAccountDataEventType}, - push::{ConditionalPushRuleInit, PatternedPushRuleInit, SimplePushRuleInit}, + push::{ConditionalPushRuleInit, NewPushRule, PatternedPushRuleInit, SimplePushRuleInit}, }; /// # `GET /_matrix/client/r0/pushrules` @@ -132,66 +132,65 @@ pub async fn set_pushrule_route( .map_err(|_| Error::bad_database("Invalid account data event in db."))?; let global = &mut account_data.content.global; - match body.kind { - RuleKind::Override => { + match body.rule { + NewPushRule::Override(rule) => { global.override_.replace( ConditionalPushRuleInit { - actions: body.actions, + actions: rule.actions, default: false, enabled: true, - rule_id: body.rule_id, - conditions: body.conditions, + rule_id: rule.rule_id, + conditions: rule.conditions, } .into(), ); } - RuleKind::Underride => { + NewPushRule::Underride(rule) => { global.underride.replace( ConditionalPushRuleInit { - actions: body.actions, + actions: rule.actions, default: false, enabled: true, - rule_id: body.rule_id, - conditions: body.conditions, + rule_id: rule.rule_id, + conditions: rule.conditions, } .into(), ); } - RuleKind::Sender => { + NewPushRule::Sender(rule) => { global.sender.replace( SimplePushRuleInit { - actions: body.actions, + actions: rule.actions, default: false, enabled: true, - rule_id: body.rule_id, + rule_id: rule.rule_id, } .into(), ); } - RuleKind::Room => { + NewPushRule::Room(rule) => { global.room.replace( SimplePushRuleInit { - actions: body.actions, + actions: rule.actions, default: false, enabled: true, - rule_id: body.rule_id, + rule_id: rule.rule_id, } .into(), ); } - RuleKind::Content => { + NewPushRule::Content(rule) => { global.content.replace( PatternedPushRuleInit { - actions: body.actions, + actions: rule.actions, default: false, enabled: true, - rule_id: body.rule_id, - pattern: body.pattern.unwrap_or_default(), + rule_id: rule.rule_id, + pattern: rule.pattern, } .into(), ); } - _ => {} } services().account_data.update( @@ -212,7 +211,7 @@ pub async fn get_pushrule_actions_route( ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - if body.scope != "global" { + if body.scope != RuleScope::Global { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Scopes other than 'global' are not supported.", diff --git a/src/main.rs b/src/main.rs index e754b84..013c4de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,7 +29,7 @@ use http::{ use opentelemetry::trace::{FutureExt, Tracer}; use ruma::api::{ client::{ - error::{Error as RumaError, ErrorKind}, + error::{Error as RumaError, ErrorBody, ErrorKind}, uiaa::UiaaResponse, }, IncomingRequest, @@ -223,8 +223,10 @@ async fn unrecognized_method( if inner.status() == axum::http::StatusCode::METHOD_NOT_ALLOWED { warn!("Method not allowed: {method} {uri}"); return Ok(RumaResponse(UiaaResponse::MatrixError(RumaError { - kind: ErrorKind::Unrecognized, - message: "M_UNRECOGNIZED: Unrecognized request".to_owned(), + body: ErrorBody::Standard { + kind: ErrorKind::Unrecognized, + message: "M_UNRECOGNIZED: Unrecognized request".to_owned(), + }, status_code: StatusCode::METHOD_NOT_ALLOWED, })) .into_response()); diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index d3d157c..ba096a2 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -239,12 +239,12 @@ impl Service { device.tweaks = tweaks.clone(); } - let d = &[device]; + let d = vec![device]; let mut notifi = Notification::new(d); notifi.prio = NotificationPriority::Low; - notifi.event_id = Some(&event.event_id); - notifi.room_id = Some(&event.room_id); + notifi.event_id = Some((*event.event_id).to_owned()); + notifi.room_id = Some((*event.room_id).to_owned()); // TODO: missed calls notifi.counts = NotificationCounts::new(unread, uint!(0)); @@ -260,18 +260,16 @@ impl Service { self.send_request(&http.url, send_event_notification::v1::Request::new(notifi)) .await?; } else { - notifi.sender = Some(&event.sender); - notifi.event_type = Some(&event.kind); - let content = serde_json::value::to_raw_value(&event.content).ok(); - notifi.content = content.as_deref(); + notifi.sender = Some(event.sender.clone()); + notifi.event_type = Some(event.kind.clone()); + notifi.content = serde_json::value::to_raw_value(&event.content).ok(); if event.kind == RoomEventType::RoomMember { notifi.user_is_target = event.state_key.as_deref() == Some(event.sender.as_str()); } - let user_name = services().users.displayname(&event.sender)?; - notifi.sender_display_name = user_name.as_deref(); + notifi.sender_display_name = services().users.displayname(&event.sender)?; let room_name = if let Some(room_name_pdu) = services() .rooms @@ -287,7 +285,7 @@ impl Service { None }; - notifi.room_name = room_name.as_deref(); + notifi.room_name = room_name; self.send_request(&http.url, send_event_notification::v1::Request::new(notifi)) .await?; diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 85d21bf..3c49349 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -1113,7 +1113,7 @@ impl Service { .send_federation_request( origin, get_event::v1::Request { - event_id: next_id.into(), + event_id: (*next_id).to_owned(), }, ) .await diff --git a/src/service/rooms/state_cache/mod.rs b/src/service/rooms/state_cache/mod.rs index 6c9bed3..32afdd4 100644 --- a/src/service/rooms/state_cache/mod.rs +++ b/src/service/rooms/state_cache/mod.rs @@ -164,7 +164,7 @@ impl Service { .content .ignored_users .iter() - .any(|user| user == sender) + .any(|(user, _details)| user == sender) }); if is_ignored { diff --git a/src/utils/error.rs b/src/utils/error.rs index 0ef13ce..3e0d8ca 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -102,7 +102,10 @@ impl Error { if let Self::FederationError(origin, error) = self { let mut error = error.clone(); - error.message = format!("Answer from {}: {}", origin, error.message); + error.body = ErrorBody::Standard { + kind: Unknown, + message: format!("Answer from {}: {}", origin, error), + }; return RumaResponse(UiaaResponse::MatrixError(error)); } From 6d5e54a66b96ab504eeb6cca03499fb03761dcb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sun, 18 Dec 2022 06:37:03 +0100 Subject: [PATCH 37/56] fix: jaeger support --- Cargo.lock | 31 +++++++++++++++++++ Cargo.toml | 1 + src/api/client_server/sync.rs | 2 +- .../key_value/rooms/state_accessor.rs | 9 ++---- src/main.rs | 24 +++++++++++--- src/service/rooms/auth_chain/mod.rs | 1 - src/service/rooms/event_handler/mod.rs | 10 +++--- src/service/rooms/state_accessor/data.rs | 7 ++--- src/service/rooms/state_accessor/mod.rs | 9 ++---- 9 files changed, 65 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a659dec..bb5943a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -419,6 +419,7 @@ dependencies = [ "tower-http", "tracing", "tracing-flame", + "tracing-opentelemetry", "tracing-subscriber", "trust-dns-resolver", ] @@ -574,6 +575,19 @@ dependencies = [ "zeroize", ] +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.3.2" @@ -1573,6 +1587,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c24f96e21e7acc813c7a8394ee94978929db2bcc46cf6b5014fc612bf7760c22" dependencies = [ + "fnv", "futures-channel", "futures-util", "indexmap", @@ -1590,6 +1605,8 @@ checksum = "1ca41c4933371b61c2a2f214bf16931499af4ec90543604ec828f7a625c09113" dependencies = [ "async-trait", "crossbeam-channel", + "dashmap", + "fnv", "futures-channel", "futures-executor", "futures-util", @@ -2891,6 +2908,20 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ebb87a95ea13271332df069020513ab70bdb5637ca42d6e492dc3bbbad48de" +dependencies = [ + "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + [[package]] name = "tracing-subscriber" version = "0.3.16" diff --git a/Cargo.toml b/Cargo.toml index 87102c0..737799d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,6 +69,7 @@ tracing-subscriber = { version = "0.3.16", features = ["env-filter"] } tracing-flame = "0.2.0" opentelemetry = { version = "0.18.0", features = ["rt-tokio"] } opentelemetry-jaeger = { version = "0.17.0", features = ["rt-tokio"] } +tracing-opentelemetry = "0.18.0" lru-cache = "0.1.2" rusqlite = { version = "0.28.0", optional = true, features = ["bundled"] } parking_lot = { version = "0.12.1", optional = true } diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 43ca238..568a23c 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -873,7 +873,7 @@ async fn sync_helper( let since_state_ids = match since_shortstatehash { Some(s) => services().rooms.state_accessor.state_full_ids(s).await?, - None => BTreeMap::new(), + None => HashMap::new(), }; let left_event_id = match services().rooms.state_accessor.room_state_get_id( diff --git a/src/database/key_value/rooms/state_accessor.rs b/src/database/key_value/rooms/state_accessor.rs index 70e59ac..0f0c0dc 100644 --- a/src/database/key_value/rooms/state_accessor.rs +++ b/src/database/key_value/rooms/state_accessor.rs @@ -1,7 +1,4 @@ -use std::{ - collections::{BTreeMap, HashMap}, - sync::Arc, -}; +use std::{collections::HashMap, sync::Arc}; use crate::{database::KeyValueDatabase, service, services, utils, Error, PduEvent, Result}; use async_trait::async_trait; @@ -9,7 +6,7 @@ use ruma::{events::StateEventType, EventId, RoomId}; #[async_trait] impl service::rooms::state_accessor::Data for KeyValueDatabase { - async fn state_full_ids(&self, shortstatehash: u64) -> Result>> { + async fn state_full_ids(&self, shortstatehash: u64) -> Result>> { let full_state = services() .rooms .state_compressor @@ -17,7 +14,7 @@ impl service::rooms::state_accessor::Data for KeyValueDatabase { .pop() .expect("there is always one layer") .1; - let mut result = BTreeMap::new(); + let mut result = HashMap::new(); let mut i = 0; for compressed in full_state.into_iter() { let parsed = services() diff --git a/src/main.rs b/src/main.rs index 013c4de..fa33c09 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,6 @@ use http::{ header::{self, HeaderName}, Method, StatusCode, Uri, }; -use opentelemetry::trace::{FutureExt, Tracer}; use ruma::api::{ client::{ error::{Error as RumaError, ErrorBody, ErrorKind}, @@ -93,14 +92,29 @@ async fn main() { if config.allow_jaeger { opentelemetry::global::set_text_map_propagator(opentelemetry_jaeger::Propagator::new()); let tracer = opentelemetry_jaeger::new_agent_pipeline() + .with_auto_split_batch(true) + .with_service_name("conduit") .install_batch(opentelemetry::runtime::Tokio) .unwrap(); + let telemetry = tracing_opentelemetry::layer().with_tracer(tracer); - let span = tracer.start("conduit"); - start.with_current_context().await; - drop(span); + let filter_layer = match EnvFilter::try_new(&config.log) { + Ok(s) => s, + Err(e) => { + eprintln!( + "It looks like your log config is invalid. The following error occurred: {}", + e + ); + EnvFilter::try_new("warn").unwrap() + } + }; - println!("exporting"); + let subscriber = tracing_subscriber::Registry::default() + .with(filter_layer) + .with(telemetry); + tracing::subscriber::set_global_default(subscriber).unwrap(); + start.await; + println!("exporting remaining spans"); opentelemetry::global::shutdown_tracer_provider(); } else { let registry = tracing_subscriber::Registry::default(); diff --git a/src/service/rooms/auth_chain/mod.rs b/src/service/rooms/auth_chain/mod.rs index d3b6e40..3963604 100644 --- a/src/service/rooms/auth_chain/mod.rs +++ b/src/service/rooms/auth_chain/mod.rs @@ -15,7 +15,6 @@ pub struct Service { } impl Service { - #[tracing::instrument(skip(self))] pub fn get_cached_eventid_authchain<'a>( &'a self, key: &[u64], diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 3c49349..0bba61c 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -7,7 +7,7 @@ use ruma::{ RoomVersionId, }; use std::{ - collections::{btree_map, hash_map, BTreeMap, HashMap, HashSet}, + collections::{hash_map, BTreeMap, HashMap, HashSet}, pin::Pin, sync::{Arc, RwLock, RwLockWriteGuard}, time::{Duration, Instant, SystemTime}, @@ -553,7 +553,7 @@ impl Service { let mut auth_chain_sets = Vec::with_capacity(extremity_sstatehashes.len()); for (sstatehash, prev_event) in extremity_sstatehashes { - let mut leaf_state: BTreeMap<_, _> = services() + let mut leaf_state: HashMap<_, _> = services() .rooms .state_accessor .state_full_ids(sstatehash) @@ -660,7 +660,7 @@ impl Service { ) .await; - let mut state: BTreeMap<_, Arc> = BTreeMap::new(); + let mut state: HashMap<_, Arc> = HashMap::new(); for (pdu, _) in state_vec { let state_key = pdu.state_key.clone().ok_or_else(|| { Error::bad_database("Found non-state pdu in state events.") @@ -672,10 +672,10 @@ impl Service { )?; match state.entry(shortstatekey) { - btree_map::Entry::Vacant(v) => { + hash_map::Entry::Vacant(v) => { v.insert(Arc::from(&*pdu.event_id)); } - btree_map::Entry::Occupied(_) => return Err( + hash_map::Entry::Occupied(_) => return Err( Error::bad_database("State event's type and state_key combination exists multiple times."), ), } diff --git a/src/service/rooms/state_accessor/data.rs b/src/service/rooms/state_accessor/data.rs index 340b19c..f3ae3c2 100644 --- a/src/service/rooms/state_accessor/data.rs +++ b/src/service/rooms/state_accessor/data.rs @@ -1,7 +1,4 @@ -use std::{ - collections::{BTreeMap, HashMap}, - sync::Arc, -}; +use std::{collections::HashMap, sync::Arc}; use async_trait::async_trait; use ruma::{events::StateEventType, EventId, RoomId}; @@ -12,7 +9,7 @@ use crate::{PduEvent, Result}; pub trait Data: Send + Sync { /// Builds a StateMap by iterating over all keys that start /// with state_hash, this gives the full state for the given state_hash. - async fn state_full_ids(&self, shortstatehash: u64) -> Result>>; + async fn state_full_ids(&self, shortstatehash: u64) -> Result>>; async fn state_full( &self, diff --git a/src/service/rooms/state_accessor/mod.rs b/src/service/rooms/state_accessor/mod.rs index 1a9c4a9..87d9936 100644 --- a/src/service/rooms/state_accessor/mod.rs +++ b/src/service/rooms/state_accessor/mod.rs @@ -1,8 +1,5 @@ mod data; -use std::{ - collections::{BTreeMap, HashMap}, - sync::Arc, -}; +use std::{collections::HashMap, sync::Arc}; pub use data::Data; use ruma::{events::StateEventType, EventId, RoomId}; @@ -16,7 +13,8 @@ pub struct Service { impl Service { /// Builds a StateMap by iterating over all keys that start /// with state_hash, this gives the full state for the given state_hash. - pub async fn state_full_ids(&self, shortstatehash: u64) -> Result>> { + #[tracing::instrument(skip(self))] + pub async fn state_full_ids(&self, shortstatehash: u64) -> Result>> { self.db.state_full_ids(shortstatehash).await } @@ -39,7 +37,6 @@ impl Service { } /// Returns a single PDU from `room_id` with key (`event_type`, `state_key`). - #[tracing::instrument(skip(self))] pub fn state_get( &self, shortstatehash: u64, From 683eefbd0bef1a5a84bd9fbd31fe11b3106f6bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sun, 18 Dec 2022 06:52:18 +0100 Subject: [PATCH 38/56] Update README --- DEPLOY.md | 2 +- README.md | 28 +++++++++++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/DEPLOY.md b/DEPLOY.md index 89631f5..1d1fc13 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -2,7 +2,7 @@ > ## Getting help > -> If you run into any problems while setting up Conduit, write an email to `timo@koesters.xyz`, ask us +> If you run into any problems while setting up Conduit, write an email to `conduit@koesters.xyz`, ask us > in `#conduit:fachschaften.org` or [open an issue on GitLab](https://gitlab.com/famedly/conduit/-/issues/new). ## Installing Conduit diff --git a/README.md b/README.md index ab47176..f73f6aa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,12 @@ # Conduit - ### A Matrix homeserver written in Rust +#### What is Matrix? +[Matrix](https://matrix.org) is an open network for secure and decentralized +communication. Users from every Matrix homeserver can chat with users from all +other Matrix servers. You can even use bridges (also called Matrix appservices) +to communicate with users outside of Matrix, like a community on Discord. + #### What is the goal? An efficient Matrix homeserver that's easy to set up and just works. You can install @@ -13,9 +18,10 @@ friends or company. Yes! You can test our Conduit instance by opening a Matrix client ( or Element Android for example) and registering on the `conduit.rs` homeserver. -It is hosted on a ODROID HC 2 with 2GB RAM and a SAMSUNG Exynos 5422 CPU, which -was used in the Samsung Galaxy S5. It joined many big rooms including Matrix -HQ. +*Registration is currently disabled because of scammers. For an account please + message us (see contact section below).* + +Server hosting for conduit.rs is donated by the Matrix.org Foundation. #### What is the current status? @@ -25,8 +31,8 @@ from time to time. There are still a few important features missing: -- E2EE verification over federation -- Outgoing read receipts, typing, presence over federation +- E2EE emoji comparison over federation (E2EE chat works) +- Outgoing read receipts, typing, presence over federation (incoming works) Check out the [Conduit 1.0 Release Milestone](https://gitlab.com/famedly/conduit/-/milestones/3). @@ -50,13 +56,21 @@ If you want to connect an Appservice to Conduit, take a look at [APPSERVICES.md] #### Thanks to -Thanks to Famedly, Prototype Fund (DLR and German BMBF) and all other individuals for financially supporting this project. +Thanks to FUTO, Famedly, Prototype Fund (DLR and German BMBF) and all individuals for financially supporting this project. Thanks to the contributors to Conduit and all libraries we use, for example: - Ruma: A clean library for the Matrix Spec in Rust - axum: A modular web framework +#### Contact + +If you run into any question, feel free to +- Ask us in `#conduit:fachschaften.org` on Matrix +- Write an E-Mail to `conduit@koesters.xyz` +- Send an direct message to `timo@fachschaften.org` on Matrix +- [Open an issue on GitLab](https://gitlab.com/famedly/conduit/-/issues/new) + #### Donate Liberapay: \ From 2a0515f5289ed712ecd4a68dfc57e7529fe1b57e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sun, 18 Dec 2022 07:47:18 +0100 Subject: [PATCH 39/56] Replace println/dbg calls with corresponding macros from tracing crate --- src/database/abstraction/sqlite.rs | 17 +----- src/database/mod.rs | 20 +++---- src/main.rs | 78 +++++++++++++------------- src/service/rooms/auth_chain/mod.rs | 36 ++++++------ src/service/rooms/event_handler/mod.rs | 5 +- 5 files changed, 68 insertions(+), 88 deletions(-) diff --git a/src/database/abstraction/sqlite.rs b/src/database/abstraction/sqlite.rs index 4961fd7..af3e192 100644 --- a/src/database/abstraction/sqlite.rs +++ b/src/database/abstraction/sqlite.rs @@ -135,7 +135,6 @@ type TupleOfBytes = (Vec, Vec); impl SqliteTable { fn get_with_guard(&self, guard: &Connection, key: &[u8]) -> Result>> { - //dbg!(&self.name); Ok(guard .prepare(format!("SELECT value FROM {} WHERE key = ?", self.name).as_str())? .query_row([key], |row| row.get(0)) @@ -143,7 +142,6 @@ impl SqliteTable { } fn insert_with_guard(&self, guard: &Connection, key: &[u8], value: &[u8]) -> Result<()> { - //dbg!(&self.name); guard.execute( format!( "INSERT OR REPLACE INTO {} (key, value) VALUES (?, ?)", @@ -176,10 +174,7 @@ impl SqliteTable { statement .query_map([], |row| Ok((row.get_unwrap(0), row.get_unwrap(1)))) .unwrap() - .map(move |r| { - //dbg!(&name); - r.unwrap() - }), + .map(move |r| r.unwrap()), ); Box::new(PreparedStatementIterator { @@ -276,10 +271,7 @@ impl KvTree for SqliteTable { statement .query_map([from], |row| Ok((row.get_unwrap(0), row.get_unwrap(1)))) .unwrap() - .map(move |r| { - //dbg!(&name); - r.unwrap() - }), + .map(move |r| r.unwrap()), ); Box::new(PreparedStatementIterator { iterator, @@ -301,10 +293,7 @@ impl KvTree for SqliteTable { statement .query_map([from], |row| Ok((row.get_unwrap(0), row.get_unwrap(1)))) .unwrap() - .map(move |r| { - //dbg!(&name); - r.unwrap() - }), + .map(move |r| r.unwrap()), ); Box::new(PreparedStatementIterator { diff --git a/src/database/mod.rs b/src/database/mod.rs index 46ffad0..ebaa746 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -258,7 +258,7 @@ impl KeyValueDatabase { }; if config.max_request_size < 1024 { - eprintln!("ERROR: Max request size is less than 1KB. Please increase it."); + error!(?config.max_request_size, "Max request size is less than 1KB. Please increase it."); } let db_raw = Box::new(Self { @@ -483,7 +483,7 @@ impl KeyValueDatabase { for user in services().rooms.state_cache.room_members(&room?) { let user = user?; if user.server_name() != services().globals.server_name() { - println!("Migration: Creating user {}", user); + info!(?user, "Migration: creating user"); services().users.create(&user, None)?; } } @@ -545,7 +545,6 @@ impl KeyValueDatabase { current_state: HashSet<_>, last_roomstates: &mut HashMap<_, _>| { counter += 1; - println!("counter: {}", counter); let last_roomsstatehash = last_roomstates.get(current_room); let states_parents = last_roomsstatehash.map_or_else( @@ -742,15 +741,13 @@ impl KeyValueDatabase { new_key.extend_from_slice(word); new_key.push(0xff); new_key.extend_from_slice(pdu_id_count); - println!("old {:?}", key); - println!("new {:?}", new_key); Some((new_key, Vec::new())) }) .peekable(); while iter.peek().is_some() { db.tokenids.insert_batch(&mut iter.by_ref().take(1000))?; - println!("smaller batch done"); + debug!("Inserted smaller batch"); } info!("Deleting starts"); @@ -760,7 +757,6 @@ impl KeyValueDatabase { .iter() .filter_map(|(key, _)| { if key.starts_with(b"!") { - println!("del {:?}", key); Some(key) } else { None @@ -769,7 +765,6 @@ impl KeyValueDatabase { .collect(); for key in batch2 { - println!("del"); db.tokenids.remove(&key)?; } @@ -945,7 +940,6 @@ impl KeyValueDatabase { #[cfg(unix)] use tokio::signal::unix::{signal, SignalKind}; - use tracing::info; use std::time::{Duration, Instant}; @@ -961,23 +955,23 @@ impl KeyValueDatabase { #[cfg(unix)] tokio::select! { _ = i.tick() => { - info!("cleanup: Timer ticked"); + debug!("cleanup: Timer ticked"); } _ = s.recv() => { - info!("cleanup: Received SIGHUP"); + debug!("cleanup: Received SIGHUP"); } }; #[cfg(not(unix))] { i.tick().await; - info!("cleanup: Timer ticked") + debug!("cleanup: Timer ticked") } let start = Instant::now(); if let Err(e) = services().globals.cleanup() { error!("cleanup: Errored: {}", e); } else { - info!("cleanup: Finished in {:?}", start.elapsed()); + debug!("cleanup: Finished in {:?}", start.elapsed()); } } }); diff --git a/src/main.rs b/src/main.rs index fa33c09..49ac22d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,7 +40,7 @@ use tower_http::{ trace::TraceLayer, ServiceBuilderExt as _, }; -use tracing::{info, warn}; +use tracing::{error, info, warn}; use tracing_subscriber::{prelude::*, EnvFilter}; pub use conduit::*; // Re-export everything from the library crate @@ -68,27 +68,16 @@ async fn main() { let config = match raw_config.extract::() { Ok(s) => s, Err(e) => { - eprintln!("It looks like your config is invalid. The following error occured while parsing it: {}", e); + eprintln!( + "It looks like your config is invalid. The following error occurred: {}", + e + ); std::process::exit(1); } }; config.warn_deprecated(); - if let Err(e) = KeyValueDatabase::load_or_create(config).await { - eprintln!( - "The database couldn't be loaded or created. The following error occured: {}", - e - ); - std::process::exit(1); - }; - - let config = &services().globals.config; - - let start = async { - run_server().await.unwrap(); - }; - if config.allow_jaeger { opentelemetry::global::set_text_map_propagator(opentelemetry_jaeger::Propagator::new()); let tracer = opentelemetry_jaeger::new_agent_pipeline() @@ -113,35 +102,44 @@ async fn main() { .with(filter_layer) .with(telemetry); tracing::subscriber::set_global_default(subscriber).unwrap(); - start.await; - println!("exporting remaining spans"); - opentelemetry::global::shutdown_tracer_provider(); + } else if config.tracing_flame { + let registry = tracing_subscriber::Registry::default(); + let (flame_layer, _guard) = + tracing_flame::FlameLayer::with_file("./tracing.folded").unwrap(); + let flame_layer = flame_layer.with_empty_samples(false); + + let filter_layer = EnvFilter::new("trace,h2=off"); + + let subscriber = registry.with(filter_layer).with(flame_layer); + tracing::subscriber::set_global_default(subscriber).unwrap(); } else { let registry = tracing_subscriber::Registry::default(); - if config.tracing_flame { - let (flame_layer, _guard) = - tracing_flame::FlameLayer::with_file("./tracing.folded").unwrap(); - let flame_layer = flame_layer.with_empty_samples(false); + let fmt_layer = tracing_subscriber::fmt::Layer::new(); + let filter_layer = match EnvFilter::try_new(&config.log) { + Ok(s) => s, + Err(e) => { + eprintln!("It looks like your config is invalid. The following error occured while parsing it: {}", e); + EnvFilter::try_new("warn").unwrap() + } + }; - let filter_layer = EnvFilter::new("trace,h2=off"); + let subscriber = registry.with(filter_layer).with(fmt_layer); + tracing::subscriber::set_global_default(subscriber).unwrap(); + } - let subscriber = registry.with(filter_layer).with(flame_layer); - tracing::subscriber::set_global_default(subscriber).unwrap(); - start.await; - } else { - let fmt_layer = tracing_subscriber::fmt::Layer::new(); - let filter_layer = match EnvFilter::try_new(&config.log) { - Ok(s) => s, - Err(e) => { - eprintln!("It looks like your log config is invalid. The following error occurred: {}", e); - EnvFilter::try_new("warn").unwrap() - } - }; + info!("Loading database"); + if let Err(error) = KeyValueDatabase::load_or_create(config).await { + error!(?error, "The database couldn't be loaded or created"); - let subscriber = registry.with(filter_layer).with(fmt_layer); - tracing::subscriber::set_global_default(subscriber).unwrap(); - start.await; - } + std::process::exit(1); + }; + let config = &services().globals.config; + + info!("Starting server"); + run_server().await.unwrap(); + + if config.allow_jaeger { + opentelemetry::global::shutdown_tracer_provider(); } } diff --git a/src/service/rooms/auth_chain/mod.rs b/src/service/rooms/auth_chain/mod.rs index 3963604..92fdd0c 100644 --- a/src/service/rooms/auth_chain/mod.rs +++ b/src/service/rooms/auth_chain/mod.rs @@ -6,7 +6,7 @@ use std::{ pub use data::Data; use ruma::{api::client::error::ErrorKind, EventId, RoomId}; -use tracing::log::warn; +use tracing::{debug, error, warn}; use crate::{services, Error, Result}; @@ -88,10 +88,10 @@ impl Service { .rooms .auth_chain .cache_auth_chain(vec![sevent_id], Arc::clone(&auth_chain))?; - println!( - "cache missed event {} with auth chain len {}", - event_id, - auth_chain.len() + debug!( + event_id = ?event_id, + chain_length = ?auth_chain.len(), + "Cache missed event" ); chunk_cache.extend(auth_chain.iter()); @@ -101,11 +101,11 @@ impl Service { } }; } - println!( - "chunk missed with len {}, event hits2: {}, misses2: {}", - chunk_cache.len(), - hits2, - misses2 + debug!( + chunk_cache_length = ?chunk_cache.len(), + hits = ?hits2, + misses = ?misses2, + "Chunk missed", ); let chunk_cache = Arc::new(chunk_cache); services() @@ -115,11 +115,11 @@ impl Service { full_auth_chain.extend(chunk_cache.iter()); } - println!( - "total: {}, chunk hits: {}, misses: {}", - full_auth_chain.len(), - hits, - misses + debug!( + chain_length = ?full_auth_chain.len(), + hits = ?hits, + misses = ?misses, + "Auth chain stats", ); Ok(full_auth_chain @@ -151,10 +151,10 @@ impl Service { } } Ok(None) => { - warn!("Could not find pdu mentioned in auth events: {}", event_id); + warn!(?event_id, "Could not find pdu mentioned in auth events"); } - Err(e) => { - warn!("Could not load event in auth chain: {} {}", event_id, e); + Err(error) => { + error!(?event_id, ?error, "Could not load event in auth chain"); } } } diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 0bba61c..cf1f370 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -839,8 +839,8 @@ impl Service { info!("Preparing for stateres to derive new room state"); let mut extremity_sstatehashes = HashMap::new(); - info!("Loading extremities"); - for id in dbg!(&extremities) { + info!(?extremities, "Loading extremities"); + for id in &extremities { match services().rooms.timeline.get_pdu(id)? { Some(leaf_pdu) => { extremity_sstatehashes.insert( @@ -1273,7 +1273,6 @@ impl Service { // This return value is the key used for sorting events, // events are then sorted by power level, time, // and lexically by event_id. - println!("{}", event_id); Ok(( int!(0), MilliSecondsSinceUnixEpoch( From 2a04c213f98cfd340fcb55b9d30a0751e796d431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sun, 18 Dec 2022 09:44:46 +0100 Subject: [PATCH 40/56] improvement: handle restricted joins locally --- src/api/client_server/membership.rs | 124 +++++++++++++++++++++------- src/service/globals/mod.rs | 2 +- 2 files changed, 97 insertions(+), 29 deletions(-) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 8674a60..d6a1bd8 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -13,8 +13,9 @@ use ruma::{ canonical_json::to_canonical_value, events::{ room::{ - join_rules::{JoinRule, RoomJoinRulesEventContent}, + join_rules::{AllowRule, JoinRule, RoomJoinRulesEventContent}, member::{MembershipState, RoomMemberEventContent}, + power_levels::RoomPowerLevelsEventContent, }, RoomEventType, StateEventType, }, @@ -751,6 +752,96 @@ async fn join_room_by_id_helper( .state .set_room_state(room_id, statehash_after_join, &state_lock)?; } else { + let join_rules_event = services().rooms.state_accessor.room_state_get( + &room_id, + &StateEventType::RoomJoinRules, + "", + )?; + let power_levels_event = services().rooms.state_accessor.room_state_get( + &room_id, + &StateEventType::RoomPowerLevels, + "", + )?; + + let join_rules_event_content: Option = join_rules_event + .as_ref() + .map(|join_rules_event| { + serde_json::from_str(join_rules_event.content.get()).map_err(|e| { + warn!("Invalid join rules event: {}", e); + Error::bad_database("Invalid join rules event in db.") + }) + }) + .transpose()?; + let power_levels_event_content: Option = power_levels_event + .as_ref() + .map(|power_levels_event| { + serde_json::from_str(power_levels_event.content.get()).map_err(|e| { + warn!("Invalid power levels event: {}", e); + Error::bad_database("Invalid power levels event in db.") + }) + }) + .transpose()?; + + let restriction_rooms = match join_rules_event_content { + Some(RoomJoinRulesEventContent { + join_rule: JoinRule::Restricted(restricted), + }) + | Some(RoomJoinRulesEventContent { + join_rule: JoinRule::KnockRestricted(restricted), + }) => restricted + .allow + .into_iter() + .filter_map(|a| match a { + AllowRule::RoomMembership(r) => Some(r.room_id), + _ => None, + }) + .collect(), + _ => Vec::new(), + }; + + let authorized_user = restriction_rooms + .iter() + .find_map(|restriction_room_id| { + if !services() + .rooms + .state_cache + .is_joined(sender_user, restriction_room_id) + .ok()? + { + return None; + } + let authorized_user = power_levels_event_content + .as_ref() + .and_then(|c| { + c.users + .iter() + .filter(|(uid, i)| { + uid.server_name() == services().globals.server_name() + && **i > ruma::int!(0) + && services() + .rooms + .state_cache + .is_joined(uid, restriction_room_id) + .unwrap_or(false) + }) + .max_by_key(|(_, i)| *i) + .map(|(u, _)| u.to_owned()) + }) + .or_else(|| { + // TODO: Check here if user is actually allowed to invite. Currently the auth + // check will just fail in this case. + services() + .rooms + .state_cache + .room_members(restriction_room_id) + .filter_map(|r| r.ok()) + .filter(|uid| uid.server_name() == services().globals.server_name()) + .next() + }); + Some(authorized_user) + }) + .flatten(); + let event = RoomMemberEventContent { membership: MembershipState::Join, displayname: services().users.displayname(sender_user)?, @@ -759,7 +850,7 @@ async fn join_room_by_id_helper( third_party_invite: None, blurhash: services().users.blurhash(sender_user)?, reason: None, - join_authorized_via_users_server: None, + join_authorized_via_users_server: authorized_user, }; // Try normal join first @@ -779,32 +870,9 @@ async fn join_room_by_id_helper( Err(e) => e, }; - // TODO: Conduit does not implement restricted join rules yet, we always ask over - // federation - let join_rules_event = services().rooms.state_accessor.room_state_get( - &room_id, - &StateEventType::RoomJoinRules, - "", - )?; - - let join_rules_event_content: Option = join_rules_event - .as_ref() - .map(|join_rules_event| { - serde_json::from_str(join_rules_event.content.get()).map_err(|e| { - warn!("Invalid join rules event: {}", e); - Error::bad_database("Invalid join rules event in db.") - }) - }) - .transpose()?; - - if matches!( - join_rules_event_content, - Some(RoomJoinRulesEventContent { - join_rule: JoinRule::Restricted { .. } - }) | Some(RoomJoinRulesEventContent { - join_rule: JoinRule::KnockRestricted { .. } - }) - ) { + if !restriction_rooms.is_empty() { + // We couldn't do the join locally, maybe federation can help to satisfy the restricted + // join requirements let (make_join_response, remote_server) = make_join_request(sender_user, room_id, servers).await?; diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index affc051..c0fcb4b 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -168,7 +168,7 @@ impl Service { .supported_room_versions() .contains(&s.config.default_room_version) { - error!("Room version in config isn't supported, falling back to default version"); + error!(config=?s.config.default_room_version, fallback=?crate::config::default_default_room_version(), "Room version in config isn't supported, falling back to default version"); s.config.default_room_version = crate::config::default_default_room_version(); }; From c86313d4fa5b4d074e5ef40442a8a272d915dd3a Mon Sep 17 00:00:00 2001 From: Nyaaori <+@nyaaori.cat> Date: Wed, 21 Dec 2022 10:42:12 +0100 Subject: [PATCH 41/56] chore: code cleanup https://rust-lang.github.io/rust-clippy/master/index.html#op_ref https://rust-lang.github.io/rust-clippy/master/index.html#str_to_string https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes --- src/api/client_server/account.rs | 9 ++-- src/api/client_server/directory.rs | 2 +- src/api/client_server/membership.rs | 15 +++--- src/api/ruma_wrapper/axum.rs | 3 +- src/api/server_server.rs | 15 +++--- src/config/mod.rs | 2 +- src/database/abstraction/sqlite.rs | 2 +- src/database/mod.rs | 4 +- src/main.rs | 12 ++--- src/service/admin/mod.rs | 69 +++++++++----------------- src/service/rooms/auth_chain/mod.rs | 5 +- src/service/rooms/event_handler/mod.rs | 2 +- src/service/rooms/state_cache/data.rs | 2 +- src/service/rooms/timeline/mod.rs | 2 +- src/utils/error.rs | 4 +- 15 files changed, 56 insertions(+), 92 deletions(-) diff --git a/src/api/client_server/account.rs b/src/api/client_server/account.rs index 50a6a18..7459254 100644 --- a/src/api/client_server/account.rs +++ b/src/api/client_server/account.rs @@ -225,8 +225,7 @@ pub async fn register_route(body: Ruma) -> Result t, Err(_) => { // Event could not be converted to canonical json @@ -594,7 +594,7 @@ async fn join_room_by_id_helper( } }; - if &signed_event_id != event_id { + if signed_event_id != event_id { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Server sent event with wrong event id", @@ -753,12 +753,12 @@ async fn join_room_by_id_helper( .set_room_state(room_id, statehash_after_join, &state_lock)?; } else { let join_rules_event = services().rooms.state_accessor.room_state_get( - &room_id, + room_id, &StateEventType::RoomJoinRules, "", )?; let power_levels_event = services().rooms.state_accessor.room_state_get( - &room_id, + room_id, &StateEventType::RoomPowerLevels, "", )?; @@ -835,8 +835,7 @@ async fn join_room_by_id_helper( .state_cache .room_members(restriction_room_id) .filter_map(|r| r.ok()) - .filter(|uid| uid.server_name() == services().globals.server_name()) - .next() + .find(|uid| uid.server_name() == services().globals.server_name()) }); Some(authorized_user) }) @@ -982,7 +981,7 @@ async fn join_room_by_id_helper( } }; - if &signed_event_id != event_id { + if signed_event_id != event_id { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Server sent event with wrong event id", @@ -1179,7 +1178,7 @@ pub(crate) async fn invite_helper<'a>( user_id.server_name(), create_invite::v2::Request { room_id: room_id.to_owned(), - event_id: (&*pdu.event_id).to_owned(), + event_id: (*pdu.event_id).to_owned(), room_version: room_version_id.clone(), event: PduEvent::convert_to_outgoing_federation_event(pdu_json.clone()), invite_room_state, diff --git a/src/api/ruma_wrapper/axum.rs b/src/api/ruma_wrapper/axum.rs index d056f3f..ed28f9d 100644 --- a/src/api/ruma_wrapper/axum.rs +++ b/src/api/ruma_wrapper/axum.rs @@ -308,8 +308,7 @@ impl Credentials for XMatrix { fn decode(value: &http::HeaderValue) -> Option { debug_assert!( value.as_bytes().starts_with(b"X-Matrix "), - "HeaderValue to decode should start with \"X-Matrix ..\", received = {:?}", - value, + "HeaderValue to decode should start with \"X-Matrix ..\", received = {value:?}", ); let parameters = str::from_utf8(&value.as_bytes()["X-Matrix ".len()..]) diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 2b854a6..fc3e2c0 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -84,8 +84,8 @@ pub enum FedDest { impl FedDest { fn into_https_string(self) -> String { match self { - Self::Literal(addr) => format!("https://{}", addr), - Self::Named(host, port) => format!("https://{}{}", host, port), + Self::Literal(addr) => format!("https://{addr}"), + Self::Named(host, port) => format!("https://{host}{port}"), } } @@ -385,7 +385,7 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe } if let Some(port) = force_port { - FedDest::Named(delegated_hostname, format!(":{}", port)) + FedDest::Named(delegated_hostname, format!(":{port}")) } else { add_port_to_hostname(&delegated_hostname) } @@ -427,7 +427,7 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe } if let Some(port) = force_port { - FedDest::Named(hostname.clone(), format!(":{}", port)) + FedDest::Named(hostname.clone(), format!(":{port}")) } else { add_port_to_hostname(&hostname) } @@ -460,7 +460,7 @@ async fn query_srv_record(hostname: &'_ str) -> Option { if let Ok(Some(host_port)) = services() .globals .dns_resolver() - .srv_lookup(format!("_matrix._tcp.{}", hostname)) + .srv_lookup(format!("_matrix._tcp.{hostname}")) .await .map(|srv| { srv.iter().next().map(|result| { @@ -482,10 +482,7 @@ async fn request_well_known(destination: &str) -> Option { &services() .globals .default_client() - .get(&format!( - "https://{}/.well-known/matrix/server", - destination - )) + .get(&format!("https://{destination}/.well-known/matrix/server")) .send() .await .ok()? diff --git a/src/config/mod.rs b/src/config/mod.rs index 6b862bb..8a4b54e 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -197,7 +197,7 @@ impl fmt::Display for Config { msg += &format!("{}: {}\n", line.1 .0, line.1 .1); } - write!(f, "{}", msg) + write!(f, "{msg}") } } diff --git a/src/database/abstraction/sqlite.rs b/src/database/abstraction/sqlite.rs index af3e192..b69efb6 100644 --- a/src/database/abstraction/sqlite.rs +++ b/src/database/abstraction/sqlite.rs @@ -106,7 +106,7 @@ impl KeyValueDatabaseEngine for Arc { } fn open_tree(&self, name: &str) -> Result> { - self.write_lock().execute(&format!("CREATE TABLE IF NOT EXISTS {} ( \"key\" BLOB PRIMARY KEY, \"value\" BLOB NOT NULL )", name), [])?; + self.write_lock().execute(&format!("CREATE TABLE IF NOT EXISTS {name} ( \"key\" BLOB PRIMARY KEY, \"value\" BLOB NOT NULL )"), [])?; Ok(Arc::new(SqliteTable { engine: Arc::clone(self), diff --git a/src/database/mod.rs b/src/database/mod.rs index ebaa746..78bb358 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -827,7 +827,7 @@ impl KeyValueDatabase { let rule = rules_list.content.get(content_rule_transformation[0]); if rule.is_some() { let mut rule = rule.unwrap().clone(); - rule.rule_id = content_rule_transformation[1].to_string(); + rule.rule_id = content_rule_transformation[1].to_owned(); rules_list.content.remove(content_rule_transformation[0]); rules_list.content.insert(rule); } @@ -850,7 +850,7 @@ impl KeyValueDatabase { let rule = rules_list.underride.get(transformation[0]); if let Some(rule) = rule { let mut rule = rule.clone(); - rule.rule_id = transformation[1].to_string(); + rule.rule_id = transformation[1].to_owned(); rules_list.underride.remove(transformation[0]); rules_list.underride.insert(rule); } diff --git a/src/main.rs b/src/main.rs index 49ac22d..da80507 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,10 +68,7 @@ async fn main() { let config = match raw_config.extract::() { Ok(s) => s, Err(e) => { - eprintln!( - "It looks like your config is invalid. The following error occurred: {}", - e - ); + eprintln!("It looks like your config is invalid. The following error occurred: {e}"); std::process::exit(1); } }; @@ -91,8 +88,7 @@ async fn main() { Ok(s) => s, Err(e) => { eprintln!( - "It looks like your log config is invalid. The following error occurred: {}", - e + "It looks like your log config is invalid. The following error occurred: {e}" ); EnvFilter::try_new("warn").unwrap() } @@ -118,7 +114,7 @@ async fn main() { let filter_layer = match EnvFilter::try_new(&config.log) { Ok(s) => s, Err(e) => { - eprintln!("It looks like your config is invalid. The following error occured while parsing it: {}", e); + eprintln!("It looks like your config is invalid. The following error occured while parsing it: {e}"); EnvFilter::try_new("warn").unwrap() } }; @@ -534,6 +530,6 @@ fn method_to_filter(method: Method) -> MethodFilter { Method::POST => MethodFilter::POST, Method::PUT => MethodFilter::PUT, Method::TRACE => MethodFilter::TRACE, - m => panic!("Unsupported HTTP method: {:?}", m), + m => panic!("Unsupported HTTP method: {m:?}"), } } diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index e2b2fd8..77f351a 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -287,13 +287,11 @@ impl Service { Err(error) => { let markdown_message = format!( "Encountered an error while handling the command:\n\ - ```\n{}\n```", - error, + ```\n{error}\n```", ); let html_message = format!( "Encountered an error while handling the command:\n\ -
\n{}\n
", - error, +
\n{error}\n
", ); RoomMessageEventContent::text_html(markdown_message, html_message) @@ -338,17 +336,14 @@ impl Service { match parsed_config { Ok(yaml) => match services().appservice.register_appservice(yaml) { Ok(id) => RoomMessageEventContent::text_plain(format!( - "Appservice registered with ID: {}.", - id + "Appservice registered with ID: {id}." )), Err(e) => RoomMessageEventContent::text_plain(format!( - "Failed to register appservice: {}", - e + "Failed to register appservice: {e}" )), }, Err(e) => RoomMessageEventContent::text_plain(format!( - "Could not parse appservice config: {}", - e + "Could not parse appservice config: {e}" )), } } else { @@ -365,8 +360,7 @@ impl Service { { Ok(()) => RoomMessageEventContent::text_plain("Appservice unregistered."), Err(e) => RoomMessageEventContent::text_plain(format!( - "Failed to unregister appservice: {}", - e + "Failed to unregister appservice: {e}" )), }, AdminCommand::ListAppservices => { @@ -459,8 +453,7 @@ impl Service { .count(); let elapsed = start.elapsed(); RoomMessageEventContent::text_plain(format!( - "Loaded auth chain with length {} in {:?}", - count, elapsed + "Loaded auth chain with length {count} in {elapsed:?}" )) } else { RoomMessageEventContent::text_plain("Event not found.") @@ -474,30 +467,26 @@ impl Service { Ok(value) => { match ruma::signatures::reference_hash(&value, &RoomVersionId::V6) { Ok(hash) => { - let event_id = EventId::parse(format!("${}", hash)); + let event_id = EventId::parse(format!("${hash}")); match serde_json::from_value::( serde_json::to_value(value).expect("value is json"), ) { Ok(pdu) => RoomMessageEventContent::text_plain(format!( - "EventId: {:?}\n{:#?}", - event_id, pdu + "EventId: {event_id:?}\n{pdu:#?}" )), Err(e) => RoomMessageEventContent::text_plain(format!( - "EventId: {:?}\nCould not parse event: {}", - event_id, e + "EventId: {event_id:?}\nCould not parse event: {e}" )), } } Err(e) => RoomMessageEventContent::text_plain(format!( - "Could not parse PDU JSON: {:?}", - e + "Could not parse PDU JSON: {e:?}" )), } } Err(e) => RoomMessageEventContent::text_plain(format!( - "Invalid json in command body: {}", - e + "Invalid json in command body: {e}" )), } } else { @@ -545,8 +534,7 @@ impl Service { AdminCommand::DatabaseMemoryUsage => match services().globals.db.memory_usage() { Ok(response) => RoomMessageEventContent::text_plain(response), Err(e) => RoomMessageEventContent::text_plain(format!( - "Failed to get database memory usage: {}", - e + "Failed to get database memory usage: {e}" )), }, AdminCommand::ShowConfig => { @@ -561,8 +549,7 @@ impl Service { Ok(id) => id, Err(e) => { return Ok(RoomMessageEventContent::text_plain(format!( - "The supplied username is not a valid username: {}", - e + "The supplied username is not a valid username: {e}" ))) } }; @@ -589,12 +576,10 @@ impl Service { .set_password(&user_id, Some(new_password.as_str())) { Ok(()) => RoomMessageEventContent::text_plain(format!( - "Successfully reset the password for user {}: {}", - user_id, new_password + "Successfully reset the password for user {user_id}: {new_password}" )), Err(e) => RoomMessageEventContent::text_plain(format!( - "Couldn't reset the password for user {}: {}", - user_id, e + "Couldn't reset the password for user {user_id}: {e}" )), } } @@ -609,8 +594,7 @@ impl Service { Ok(id) => id, Err(e) => { return Ok(RoomMessageEventContent::text_plain(format!( - "The supplied username is not a valid username: {}", - e + "The supplied username is not a valid username: {e}" ))) } }; @@ -676,8 +660,7 @@ impl Service { let user_id = Arc::::from(user_id); if services().users.exists(&user_id)? { RoomMessageEventContent::text_plain(format!( - "Making {} leave all rooms before deactivation...", - user_id + "Making {user_id} leave all rooms before deactivation..." )); services().users.deactivate_account(&user_id)?; @@ -687,13 +670,11 @@ impl Service { } RoomMessageEventContent::text_plain(format!( - "User {} has been deactivated", - user_id + "User {user_id} has been deactivated" )) } else { RoomMessageEventContent::text_plain(format!( - "User {} doesn't exist on this server", - user_id + "User {user_id} doesn't exist on this server" )) } } @@ -709,8 +690,7 @@ impl Service { Ok(user_id) => user_ids.push(user_id), Err(_) => { return Ok(RoomMessageEventContent::text_plain(format!( - "{} is not a valid username", - username + "{username} is not a valid username" ))) } } @@ -746,8 +726,7 @@ impl Service { if admins.is_empty() { RoomMessageEventContent::text_plain(format!( - "Deactivated {} accounts.", - deactivation_count + "Deactivated {deactivation_count} accounts." )) } else { RoomMessageEventContent::text_plain(format!("Deactivated {} accounts.\nSkipped admin accounts: {:?}. Use --force to deactivate admin accounts", deactivation_count, admins.join(", "))) @@ -767,8 +746,8 @@ impl Service { fn usage_to_html(&self, text: &str, server_name: &ServerName) -> String { // Replace `@conduit:servername:-subcmdname` with `@conduit:servername: subcmdname` let text = text.replace( - &format!("@conduit:{}:-", server_name), - &format!("@conduit:{}: ", server_name), + &format!("@conduit:{server_name}:-"), + &format!("@conduit:{server_name}: "), ); // For the conduit admin room, subcommands become main commands diff --git a/src/service/rooms/auth_chain/mod.rs b/src/service/rooms/auth_chain/mod.rs index 92fdd0c..da1944e 100644 --- a/src/service/rooms/auth_chain/mod.rs +++ b/src/service/rooms/auth_chain/mod.rs @@ -15,10 +15,7 @@ pub struct Service { } impl Service { - pub fn get_cached_eventid_authchain<'a>( - &'a self, - key: &[u64], - ) -> Result>>> { + pub fn get_cached_eventid_authchain(&self, key: &[u64]) -> Result>>> { self.db.get_cached_eventid_authchain(key) } diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index cf1f370..7531674 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -639,7 +639,7 @@ impl Service { origin, get_room_state_ids::v1::Request { room_id: room_id.to_owned(), - event_id: (&*incoming_pdu.event_id).to_owned(), + event_id: (*incoming_pdu.event_id).to_owned(), }, ) .await diff --git a/src/service/rooms/state_cache/data.rs b/src/service/rooms/state_cache/data.rs index 42de56d..d8bb4a4 100644 --- a/src/service/rooms/state_cache/data.rs +++ b/src/service/rooms/state_cache/data.rs @@ -37,7 +37,7 @@ pub trait Data: Send + Sync { room_id: &RoomId, ) -> Box> + 'a>; - fn server_in_room<'a>(&'a self, server: &ServerName, room_id: &RoomId) -> Result; + fn server_in_room(&self, server: &ServerName, room_id: &RoomId) -> Result; /// Returns an iterator of all rooms a server participates in (as far as we know). fn server_rooms<'a>( diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 619dca2..34399d4 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -378,7 +378,7 @@ impl Service { )?; let server_user = format!("@conduit:{}", services().globals.server_name()); - let to_conduit = body.starts_with(&format!("{}: ", server_user)); + let to_conduit = body.starts_with(&format!("{server_user}: ")); // This will evaluate to false if the emergency password is set up so that // the administrator can execute commands as conduit diff --git a/src/utils/error.rs b/src/utils/error.rs index 3e0d8ca..4f044ca 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -104,12 +104,12 @@ impl Error { let mut error = error.clone(); error.body = ErrorBody::Standard { kind: Unknown, - message: format!("Answer from {}: {}", origin, error), + message: format!("Answer from {origin}: {error}"), }; return RumaResponse(UiaaResponse::MatrixError(error)); } - let message = format!("{}", self); + let message = format!("{self}"); use ErrorKind::*; let (kind, status_code) = match self { From 7c196f4e00b74bed247a03e701439bdac759914e Mon Sep 17 00:00:00 2001 From: Nyaaori <+@nyaaori.cat> Date: Fri, 9 Sep 2022 19:17:29 +0200 Subject: [PATCH 42/56] feat: Add max prev events config option, allowing adjusting limit for prev_events fetching --- src/config/mod.rs | 6 ++++++ src/service/globals/mod.rs | 4 ++++ src/service/rooms/event_handler/mod.rs | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index 8a4b54e..b974fb1 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -40,6 +40,8 @@ pub struct Config { pub max_request_size: u32, #[serde(default = "default_max_concurrent_requests")] pub max_concurrent_requests: u16, + #[serde(default = "default_max_fetch_prev_events")] + pub max_fetch_prev_events: u16, #[serde(default = "false_fn")] pub allow_registration: bool, #[serde(default = "true_fn")] @@ -249,6 +251,10 @@ fn default_max_concurrent_requests() -> u16 { 100 } +fn default_max_fetch_prev_events() -> u16 { + 100_u16 +} + fn default_log() -> String { "warn,state_res=warn,_=off,sled=off".to_owned() } diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index c0fcb4b..bb823e2 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -222,6 +222,10 @@ impl Service { self.config.max_request_size } + pub fn max_fetch_prev_events(&self) -> u16 { + self.config.max_fetch_prev_events + } + pub fn allow_registration(&self) -> bool { self.config.allow_registration } diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 7531674..5633bc5 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -1226,7 +1226,7 @@ impl Service { .await .pop() { - if amount > 100 { + if amount > services().globals.max_fetch_prev_events() { // Max limit reached warn!("Max prev event limit reached!"); graph.insert(prev_event_id.clone(), HashSet::new()); From 7cc346bc18d50d614bd07f4d2dbe0186eb024389 Mon Sep 17 00:00:00 2001 From: Nyaaori <+@nyaaori.cat> Date: Wed, 21 Dec 2022 11:45:12 +0100 Subject: [PATCH 43/56] feat: Implement membership ban/join/leave/invite reason support --- src/api/client_server/membership.rs | 37 +++++++++++++++++++---------- src/api/client_server/room.rs | 2 +- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 87954ed..61c67cb 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -69,6 +69,7 @@ pub async fn join_room_by_id_route( join_room_by_id_helper( body.sender_user.as_deref(), &body.room_id, + body.reason.clone(), &servers, body.third_party_signed.as_ref(), ) @@ -117,6 +118,7 @@ pub async fn join_room_by_id_or_alias_route( let join_room_response = join_room_by_id_helper( Some(sender_user), &room_id, + body.reason.clone(), &servers, body.third_party_signed.as_ref(), ) @@ -137,7 +139,7 @@ pub async fn leave_room_route( ) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - leave_room(sender_user, &body.room_id).await?; + leave_room(sender_user, &body.room_id, body.reason.clone()).await?; Ok(leave_room::v3::Response::new()) } @@ -151,7 +153,14 @@ pub async fn invite_user_route( let sender_user = body.sender_user.as_ref().expect("user is authenticated"); if let invite_user::v3::InvitationRecipient::UserId { user_id } = &body.recipient { - invite_helper(sender_user, user_id, &body.room_id, false).await?; + invite_helper( + sender_user, + user_id, + &body.room_id, + body.reason.clone(), + false, + ) + .await?; Ok(invite_user::v3::Response {}) } else { Err(Error::BadRequest(ErrorKind::NotFound, "User not found.")) @@ -185,7 +194,7 @@ pub async fn kick_user_route( .map_err(|_| Error::bad_database("Invalid member event in database."))?; event.membership = MembershipState::Leave; - // TODO: reason + event.reason = body.reason.clone(); let mutex_state = Arc::clone( services() @@ -222,8 +231,6 @@ pub async fn kick_user_route( pub async fn ban_user_route(body: Ruma) -> Result { let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - // TODO: reason - let event = services() .rooms .state_accessor @@ -240,7 +247,7 @@ pub async fn ban_user_route(body: Ruma) -> Result, room_id: &RoomId, + reason: Option, servers: &[OwnedServerName], _third_party_signed: Option<&ThirdPartySigned>, ) -> Result { @@ -533,7 +542,7 @@ async fn join_room_by_id_helper( is_direct: None, third_party_invite: None, blurhash: services().users.blurhash(sender_user)?, - reason: None, + reason, join_authorized_via_users_server, }) .expect("event is valid, we just created it"), @@ -848,7 +857,7 @@ async fn join_room_by_id_helper( is_direct: None, third_party_invite: None, blurhash: services().users.blurhash(sender_user)?, - reason: None, + reason: reason.clone(), join_authorized_via_users_server: authorized_user, }; @@ -920,7 +929,7 @@ async fn join_room_by_id_helper( is_direct: None, third_party_invite: None, blurhash: services().users.blurhash(sender_user)?, - reason: None, + reason, join_authorized_via_users_server, }) .expect("event is valid, we just created it"), @@ -1123,6 +1132,7 @@ pub(crate) async fn invite_helper<'a>( sender_user: &UserId, user_id: &UserId, room_id: &RoomId, + reason: Option, is_direct: bool, ) -> Result<()> { if user_id.server_name() != services().globals.server_name() { @@ -1145,7 +1155,7 @@ pub(crate) async fn invite_helper<'a>( membership: MembershipState::Invite, third_party_invite: None, blurhash: None, - reason: None, + reason, join_authorized_via_users_server: None, }) .expect("member event is valid value"); @@ -1269,7 +1279,7 @@ pub(crate) async fn invite_helper<'a>( is_direct: Some(is_direct), third_party_invite: None, blurhash: services().users.blurhash(user_id)?, - reason: None, + reason, join_authorized_via_users_server: None, }) .expect("event is valid, we just created it"), @@ -1308,13 +1318,13 @@ pub async fn leave_all_rooms(user_id: &UserId) -> Result<()> { Err(_) => continue, }; - let _ = leave_room(user_id, &room_id).await; + let _ = leave_room(user_id, &room_id, None).await; } Ok(()) } -pub async fn leave_room(user_id: &UserId, room_id: &RoomId) -> Result<()> { +pub async fn leave_room(user_id: &UserId, room_id: &RoomId, reason: Option) -> Result<()> { // Ask a remote server if we don't have this room if !services().rooms.metadata.exists(room_id)? && room_id.server_name() != services().globals.server_name() @@ -1382,6 +1392,7 @@ pub async fn leave_room(user_id: &UserId, room_id: &RoomId) -> Result<()> { .map_err(|_| Error::bad_database("Invalid member event in database."))?; event.membership = MembershipState::Leave; + event.reason = reason; services().rooms.timeline.build_and_append_pdu( PduBuilder { diff --git a/src/api/client_server/room.rs b/src/api/client_server/room.rs index c77cfa9..830e085 100644 --- a/src/api/client_server/room.rs +++ b/src/api/client_server/room.rs @@ -398,7 +398,7 @@ pub async fn create_room_route( // 8. Events implied by invite (and TODO: invite_3pid) drop(state_lock); for user_id in &body.invite { - let _ = invite_helper(sender_user, user_id, &room_id, body.is_direct).await; + let _ = invite_helper(sender_user, user_id, &room_id, None, body.is_direct).await; } // Homeserver specific stuff From 76a82339a2fd8e0d1197cf298bfbaff400b3c34b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 21 Dec 2022 09:56:07 +0100 Subject: [PATCH 44/56] tweak default rocksdb settings --- src/config/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index b974fb1..31a586f 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -224,7 +224,7 @@ fn default_database_backend() -> String { } fn default_db_cache_capacity_mb() -> f64 { - 10.0 + 1000.0 } fn default_conduit_cache_capacity_modifier() -> f64 { @@ -232,7 +232,7 @@ fn default_conduit_cache_capacity_modifier() -> f64 { } fn default_rocksdb_max_open_files() -> i32 { - 20 + 1000 } fn default_pdu_cache_capacity() -> u32 { From c7a7c913d4513e0002f85c4d0118ceffc7bbbd8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 21 Dec 2022 13:44:41 +0100 Subject: [PATCH 45/56] Bump ruma --- Cargo.lock | 48 +++++++++++++++----------- Cargo.toml | 2 +- src/service/rooms/event_handler/mod.rs | 2 +- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb5943a..bbfda3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,6 +181,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" + [[package]] name = "base64ct" version = "1.5.3" @@ -377,7 +383,7 @@ dependencies = [ "async-trait", "axum", "axum-server", - "base64", + "base64 0.13.1", "bytes", "clap", "crossbeam", @@ -941,7 +947,7 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ - "base64", + "base64 0.13.1", "bitflags", "bytes", "headers-core", @@ -1249,7 +1255,7 @@ version = "8.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aa4b4af834c6cfd35d8763d359661b90f2e45d8f750a0849156c7f4671af09c" dependencies = [ - "base64", + "base64 0.13.1", "pem", "ring", "serde", @@ -1714,7 +1720,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03c64931a1a212348ec4f3b4362585eca7159d0d09cbdf4a7f74f02173596fd4" dependencies = [ - "base64", + "base64 0.13.1", ] [[package]] @@ -1999,7 +2005,7 @@ name = "reqwest" version = "0.11.9" source = "git+https://github.com/timokoesters/reqwest?rev=57b7cf4feb921573dfafad7d34b9ac6e44ead0bd#57b7cf4feb921573dfafad7d34b9ac6e44ead0bd" dependencies = [ - "base64", + "base64 0.13.1", "bytes", "encoding_rs", "futures-core", @@ -2070,7 +2076,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.7.4" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ "assign", "js_int", @@ -2088,7 +2094,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.7.0" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ "js_int", "ruma-common", @@ -2099,7 +2105,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.15.3" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ "assign", "bytes", @@ -2116,9 +2122,9 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.10.5" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ - "base64", + "base64 0.20.0", "bytes", "form_urlencoded", "http", @@ -2144,7 +2150,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ "js_int", "ruma-common", @@ -2155,7 +2161,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ "js_int", "thiserror", @@ -2164,7 +2170,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ "js_int", "ruma-common", @@ -2174,7 +2180,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.10.5" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ "once_cell", "proc-macro-crate", @@ -2189,7 +2195,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ "js_int", "ruma-common", @@ -2200,9 +2206,9 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.12.0" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ - "base64", + "base64 0.20.0", "ed25519-dalek", "pkcs8", "rand 0.7.3", @@ -2216,7 +2222,7 @@ dependencies = [ [[package]] name = "ruma-state-res" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=af28dc8339773e5cad460289fa3c4e22d9a058cd#af28dc8339773e5cad460289fa3c4e22d9a058cd" +source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" dependencies = [ "itertools", "js_int", @@ -2247,7 +2253,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b50162d19404029c1ceca6f6980fe40d45c8b369f6f44446fa14bb39573b5bb9" dependencies = [ - "base64", + "base64 0.13.1", "blake2b_simd", "constant_time_eq", "crossbeam-utils", @@ -2289,7 +2295,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" dependencies = [ - "base64", + "base64 0.13.1", ] [[package]] @@ -2298,7 +2304,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" dependencies = [ - "base64", + "base64 0.13.1", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 737799d..6d8af44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ tower-http = { version = "0.3.4", features = ["add-extension", "cors", "compress # Used for matrix spec type definitions and helpers #ruma = { version = "0.4.0", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } -ruma = { git = "https://github.com/ruma/ruma", rev = "af28dc8339773e5cad460289fa3c4e22d9a058cd", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "50c1db7e0a3a21fc794b0cce3b64285a4c750c71", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 5633bc5..bc67f7a 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -313,7 +313,7 @@ impl Service { Ok(ruma::signatures::Verified::Signatures) => { // Redact warn!("Calculated hash does not match: {}", event_id); - match ruma::canonical_json::redact(&value, room_version_id) { + match ruma::canonical_json::redact(value, room_version_id, None) { Ok(obj) => obj, Err(_) => { return Err(Error::BadRequest( From f7db3490f668b9cf1b38491728c1c60c5ac49fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 21 Dec 2022 10:25:54 +0100 Subject: [PATCH 46/56] Bump version to v0.5.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbfda3f..e773892 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,7 +378,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "conduit" -version = "0.4.0-next" +version = "0.5.0" dependencies = [ "async-trait", "axum", diff --git a/Cargo.toml b/Cargo.toml index 6d8af44..7dc6448 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ authors = ["timokoesters "] homepage = "https://conduit.rs" repository = "https://gitlab.com/famedly/conduit" readme = "README.md" -version = "0.4.0-next" +version = "0.5.0" rust-version = "1.64" edition = "2021" From 2a66ad4329c012e482b80deeaf750eb9360d758d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 21 Dec 2022 16:08:05 +0100 Subject: [PATCH 47/56] Bump version to 0.6.0-alpha --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7dc6448..019f9ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ authors = ["timokoesters "] homepage = "https://conduit.rs" repository = "https://gitlab.com/famedly/conduit" readme = "README.md" -version = "0.5.0" +version = "0.6.0-alpha" rust-version = "1.64" edition = "2021" From 19156c7bbf8dab7267db235807ea80255ee91e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 21 Dec 2022 16:15:56 +0100 Subject: [PATCH 48/56] Update Cargo.lock --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index e773892..505c71c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -378,7 +378,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "conduit" -version = "0.5.0" +version = "0.6.0-alpha" dependencies = [ "async-trait", "axum", From 0a4e8e59094b5ace727262820d05899ffa1be3bd Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Fri, 16 Dec 2022 13:06:59 -0800 Subject: [PATCH 49/56] update rust toolchain hash --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 924300c..5db8168 100644 --- a/flake.nix +++ b/flake.nix @@ -34,7 +34,7 @@ # This will need to be updated when `package.rust-version` is changed in # `Cargo.toml` - sha256 = "sha256-KXx+ID0y4mg2B3LHp7IyaiMrdexF6octADnAtFIOjrY="; + sha256 = "sha256-8len3i8oTwJSOJZMosGGXHBL5BVuGQnWOT2St5YAUFU="; }; builder = (pkgs.callPackage naersk { From 9f74555c88a7705f393c3175e9bda60aaf438c62 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Fri, 16 Dec 2022 13:09:35 -0800 Subject: [PATCH 50/56] update flake.lock --- flake.lock | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/flake.lock b/flake.lock index 9217ff2..bfe0a9b 100644 --- a/flake.lock +++ b/flake.lock @@ -8,11 +8,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1665815894, - "narHash": "sha256-Vboo1L4NMGLKZKVLnOPi9OHlae7uoNyfgvyIUm+SVXE=", + "lastModified": 1671776618, + "narHash": "sha256-myjhExbKIzZy+kqqFyqvX59KErqYZVNTPsCfgByTOKo=", "owner": "nix-community", "repo": "fenix", - "rev": "2348450241a5f945f0ba07e44ecbfac2f541d7f4", + "rev": "64d1607710b99e72d9afb2cde11bd1c2cea7cb91", "type": "github" }, "original": { @@ -23,11 +23,11 @@ }, "flake-utils": { "locked": { - "lastModified": 1659877975, - "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", "owner": "numtide", "repo": "flake-utils", - "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", "type": "github" }, "original": { @@ -43,11 +43,11 @@ ] }, "locked": { - "lastModified": 1662220400, - "narHash": "sha256-9o2OGQqu4xyLZP9K6kNe1pTHnyPz0Wr3raGYnr9AIgY=", + "lastModified": 1671096816, + "narHash": "sha256-ezQCsNgmpUHdZANDCILm3RvtO1xH8uujk/+EqNvzIOg=", "owner": "nix-community", "repo": "naersk", - "rev": "6944160c19cb591eb85bbf9b2f2768a935623ed3", + "rev": "d998160d6a076cfe8f9741e56aeec7e267e3e114", "type": "github" }, "original": { @@ -58,11 +58,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1665856037, - "narHash": "sha256-/RvIWnGKdTSoIq5Xc2HwPIL0TzRslzU6Rqk4Img6UNg=", + "lastModified": 1671780662, + "narHash": "sha256-Tsc64sN8LLHa7eqDZVVeubI8CyqIjs9l5tQ5EeRlgvM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c95ebc5125ffffcd431df0ad8620f0926b8125b8", + "rev": "339063a22409514cb2baea677b329e618faa6a08", "type": "github" }, "original": { @@ -82,11 +82,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1665765556, - "narHash": "sha256-w9L5j0TIB5ay4aRwzGCp8mgvGsu5dVJQvbEFutwr6xE=", + "lastModified": 1671750139, + "narHash": "sha256-xbL8BZU87rHfQkF3tuFXduNGPW8fDwFI+0fFmRJx66E=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "018b8429cf3fa9d8aed916704e41dfedeb0f4f78", + "rev": "a06525517b0b69cd97f2c39a4012d96f44bf0776", "type": "github" }, "original": { From 315944968b4f84c31f7f1396a8409b4a13e52709 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Fri, 23 Dec 2022 00:20:05 -0800 Subject: [PATCH 51/56] remind people to update the hash And offer help since it's pretty easy but impossible if you don't have Nix installed. --- Cargo.toml | 6 +++++- flake.nix | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 019f9ce..16c04bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,9 +7,13 @@ homepage = "https://conduit.rs" repository = "https://gitlab.com/famedly/conduit" readme = "README.md" version = "0.6.0-alpha" -rust-version = "1.64" edition = "2021" +# When changing this, change the hash near the text "THE rust-version HASH" in +# `/flake.nix` too. If you don't have Nix installed or otherwise don't know how +# to do this, ping `@charles:computer.surgery` in the matrix room. +rust-version = "1.64" + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/flake.nix b/flake.nix index 5db8168..e10e8bb 100644 --- a/flake.nix +++ b/flake.nix @@ -32,8 +32,7 @@ # Use the Rust version defined in `Cargo.toml` channel = cargoToml.package.rust-version; - # This will need to be updated when `package.rust-version` is changed in - # `Cargo.toml` + # THE rust-version HASH sha256 = "sha256-8len3i8oTwJSOJZMosGGXHBL5BVuGQnWOT2St5YAUFU="; }; From 112b76b1c134be7514986e30e72c2be5ebda5323 Mon Sep 17 00:00:00 2001 From: r3g_5z Date: Sun, 8 Jan 2023 02:44:25 -0500 Subject: [PATCH 52/56] Add Contributor's Covenant Code of Conduct Signed-off-by: r3g_5z --- CODE_OF_CONDUCT.md | 134 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..1b06035 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,134 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement over email at +coc@koesters.xyz or over Matrix at @timo:conduit.rs. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations + From 391beddaf4034e114020c707198414fd6e4d141a Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 8 Jan 2023 12:44:59 -0800 Subject: [PATCH 53/56] fix nix docs I made some silly copy paste errors while writing this... --- nix/README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/nix/README.md b/nix/README.md index d92f910..77bad0f 100644 --- a/nix/README.md +++ b/nix/README.md @@ -107,7 +107,7 @@ in recommendedProxySettings = true; virtualHosts = { - "${server_name}" = { + "${matrix_hostname}" = { forceSSL = true; enableACME = true; @@ -124,14 +124,6 @@ in } ]; - extraConfig = '' - merge_slashes off; - ''; - - "${matrix_hostname}" = { - forceSSL = true; - enableACME = true; - locations."/_matrix/" = { proxyPass = "http://backend_conduit$request_uri"; proxyWebsockets = true; @@ -141,6 +133,15 @@ in ''; }; + extraConfig = '' + merge_slashes off; + ''; + }; + + "${server_name}" = { + forceSSL = true; + enableACME = true; + locations."=/.well-known/matrix/server" = { # Use the contents of the derivation built previously alias = "${well_known_server}"; From 844508bc482f0bafab61111b8fad70684368bd8d Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 9 Jan 2023 08:09:41 -0800 Subject: [PATCH 54/56] document `trusted_servers` option --- conduit-example.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/conduit-example.toml b/conduit-example.toml index 0549030..6089aa5 100644 --- a/conduit-example.toml +++ b/conduit-example.toml @@ -43,6 +43,10 @@ allow_federation = true # Enable the display name lightning bolt on registration. enable_lightning_bolt = true +# Servers listed here will be used to gather public keys of other servers. +# Generally, copying this exactly should be enough. (Currently, Conduit doesn't +# support batched key requests, so this list should only contain Synapse +# servers.) trusted_servers = ["matrix.org"] #max_concurrent_requests = 100 # How many requests Conduit sends to other servers at the same time From 809c9b44817faa4b4c4126a11d9bb9e5486ba3c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sat, 14 Jan 2023 21:20:16 +0100 Subject: [PATCH 55/56] Maybe fix room joins This is a workaround for https://github.com/hyperium/hyper/issues/2312 --- src/service/globals/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index bb823e2..cd3be08 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -345,6 +345,7 @@ impl Service { fn reqwest_client_builder(config: &Config) -> Result { let mut reqwest_client_builder = reqwest::Client::builder() + .pool_max_idle_per_host(0) .connect_timeout(Duration::from_secs(30)) .timeout(Duration::from_secs(60 * 3)); From f01b96588dae3ffbfca267a1ff51477decba998a Mon Sep 17 00:00:00 2001 From: The one with the braid Date: Thu, 19 Jan 2023 07:21:04 +0100 Subject: [PATCH 56/56] fix: adjust CI config to runner requirements - make use of more stable BTRFS driver - set default pull policy to `if-not-present` Signed-off-by: The one with the braid --- .gitlab-ci.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 91258ea..d05bb89 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,14 +16,17 @@ variables: .docker-shared-settings: stage: "build docker image" - image: jdrouet/docker-with-buildx:20.10.21-0.9.1 + image: + name: jdrouet/docker-with-buildx:20.10.21-0.9.1 + pull_policy: if-not-present needs: [] - tags: ["docker"] + tags: [ "docker" ] variables: # Docker in Docker: DOCKER_HOST: tcp://docker:2375/ DOCKER_TLS_CERTDIR: "" - DOCKER_DRIVER: overlay2 + # Famedly runners use BTRFS, overlayfs and overlay2 often break jobs + DOCKER_DRIVER: btrfs services: - docker:dind script: