From f3b6b3e222caa3c01a6a301d38ff15e98f8b973f Mon Sep 17 00:00:00 2001 From: AndSDev Date: Tue, 7 Nov 2023 12:46:53 +0000 Subject: [PATCH 001/129] feat: send push notification on invite to invited user and etc --- src/service/rooms/timeline/mod.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 25e1c54d..e419980c 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -320,12 +320,25 @@ impl Service { let mut notifies = Vec::new(); let mut highlights = Vec::new(); - for user in services() + let mut push_target = services() .rooms .state_cache - .get_our_real_users(&pdu.room_id)? - .iter() - { + .get_our_real_users(&pdu.room_id)?; + + if pdu.kind == TimelineEventType::RoomMember { + if let Some(state_key) = &pdu.state_key { + let target_user_id = UserId::parse(state_key.clone()) + .expect("This state_key was previously validated"); + + if !push_target.contains(&target_user_id) { + let mut target = push_target.as_ref().clone(); + target.insert(target_user_id); + push_target = Arc::new(target); + } + } + } + + for user in push_target.iter() { // Don't notify the user of their own events if user == &pdu.sender { continue; From 98e81c62174a587c54ed111e0eca617c1d423efd Mon Sep 17 00:00:00 2001 From: Val Lorentz Date: Sun, 3 Dec 2023 19:38:09 +0100 Subject: [PATCH 002/129] Log underlying error when rejecting sendjoin response --- src/api/client_server/membership.rs | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 4a1f3743..346f2575 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -619,7 +619,7 @@ async fn join_room_by_id_helper( )); } - if let Ok(signature) = signed_value["signatures"] + match signed_value["signatures"] .as_object() .ok_or(Error::BadRequest( ErrorKind::InvalidParam, @@ -630,18 +630,20 @@ async fn join_room_by_id_helper( 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 {remote_server} sent invalid signature in sendjoin signatures for event {signed_value:?}", - ); + }) { + Ok(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()); + } + Err(e) => { + warn!( + "Server {remote_server} sent invalid signature in sendjoin signatures for event {signed_value:?}: {e:?}", + ); + } } } From 9d7f7b871b9783dbdce15e0491b0eaa9d948b21f Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sat, 23 Dec 2023 21:00:00 -0800 Subject: [PATCH 003/129] don't panic on missing presence status for a user --- src/api/client_server/presence.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/api/client_server/presence.rs b/src/api/client_server/presence.rs index ef88d1a0..e5cd1b8e 100644 --- a/src/api/client_server/presence.rs +++ b/src/api/client_server/presence.rs @@ -1,5 +1,8 @@ -use crate::{services, utils, Result, Ruma}; -use ruma::api::client::presence::{get_presence, set_presence}; +use crate::{services, utils, Error, Result, Ruma}; +use ruma::api::client::{ + error::ErrorKind, + presence::{get_presence, set_presence}, +}; use std::time::Duration; /// # `PUT /_matrix/client/r0/presence/{userId}/status` @@ -79,6 +82,9 @@ pub async fn get_presence_route( presence: presence.content.presence, }) } else { - todo!(); + Err(Error::BadRequest( + ErrorKind::NotFound, + "Presence state for this user was not found", + )) } } From 8f3f5c01f924820994f8bf5fe20abc5a3e6b8866 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sat, 23 Dec 2023 22:02:24 -0800 Subject: [PATCH 004/129] add shebang to .envrc All this really does is make syntax highlighting and shellcheck work by default in more editors. --- .envrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.envrc b/.envrc index 3550a30f..b9238c3b 100644 --- a/.envrc +++ b/.envrc @@ -1 +1,3 @@ +#!/usr/bin/env bash + use flake From 835f4ad8cfa8a222a56e21f37646a86c1acd90a7 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Tue, 16 Jan 2024 13:52:56 -0800 Subject: [PATCH 005/129] declare 1.5 support --- src/api/client_server/unversioned.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/api/client_server/unversioned.rs b/src/api/client_server/unversioned.rs index 797b9529..70e260ec 100644 --- a/src/api/client_server/unversioned.rs +++ b/src/api/client_server/unversioned.rs @@ -26,6 +26,7 @@ pub async fn get_supported_versions_route( "v1.2".to_owned(), "v1.3".to_owned(), "v1.4".to_owned(), + "v1.5".to_owned(), ], unstable_features: BTreeMap::from_iter([("org.matrix.e2e_cross_signing".to_owned(), true)]), }; From dc2f53e77393cf49ae9f6da9bb1db20abdf59230 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sat, 23 Dec 2023 20:40:56 -0800 Subject: [PATCH 006/129] comment out heed backend things The code in conduit doesn't compile. --- Cargo.lock | 136 +---------------------------------------------------- Cargo.toml | 6 +-- 2 files changed, 4 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c8596aa..b4bcdc0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,15 +180,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bindgen" version = "0.65.1" @@ -368,11 +359,9 @@ dependencies = [ "base64 0.21.2", "bytes", "clap", - "crossbeam", "directories", "figment", "futures-util", - "heed", "hmac", "http", "image", @@ -487,20 +476,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crossbeam" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" -dependencies = [ - "cfg-if", - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - [[package]] name = "crossbeam-channel" version = "0.5.8" @@ -511,40 +486,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset 0.9.0", - "scopeguard", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.16" @@ -986,42 +927,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "heed" -version = "0.10.6" -source = "git+https://github.com/timokoesters/heed.git?rev=f6f825da7fb2c758867e05ad973ef800a6fe1d5d#f6f825da7fb2c758867e05ad973ef800a6fe1d5d" -dependencies = [ - "bytemuck", - "byteorder", - "heed-traits", - "heed-types", - "libc", - "lmdb-rkv-sys", - "once_cell", - "page_size", - "serde", - "synchronoise", - "url", -] - -[[package]] -name = "heed-traits" -version = "0.7.0" -source = "git+https://github.com/timokoesters/heed.git?rev=f6f825da7fb2c758867e05ad973ef800a6fe1d5d#f6f825da7fb2c758867e05ad973ef800a6fe1d5d" - -[[package]] -name = "heed-types" -version = "0.7.2" -source = "git+https://github.com/timokoesters/heed.git?rev=f6f825da7fb2c758867e05ad973ef800a6fe1d5d#f6f825da7fb2c758867e05ad973ef800a6fe1d5d" -dependencies = [ - "bincode", - "bytemuck", - "byteorder", - "heed-traits", - "serde", - "serde_json", -] - [[package]] name = "hermit-abi" version = "0.2.6" @@ -1379,17 +1284,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" -[[package]] -name = "lmdb-rkv-sys" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b9ce6b3be08acefa3003c57b7565377432a89ec24476bbe72e11d101f852fe" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "lock_api" version = "0.4.10" @@ -1473,15 +1367,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - [[package]] name = "mime" version = "0.3.17" @@ -1524,7 +1409,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.7.1", + "memoffset", "pin-utils", "static_assertions", ] @@ -1701,16 +1586,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "page_size" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebde548fbbf1ea81a99b128872779c437752fb99f217c45245e1a61dcd9edcd" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -2727,15 +2602,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "synchronoise" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dbc01390fc626ce8d1cffe3376ded2b72a11bb70e1c75f404a210e4daa4def2" -dependencies = [ - "crossbeam-queue", -] - [[package]] name = "thiserror" version = "1.0.40" diff --git a/Cargo.toml b/Cargo.toml index ff1785e4..6cc66508 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,10 +78,10 @@ tracing-opentelemetry = "0.18.0" lru-cache = "0.1.2" rusqlite = { version = "0.29.0", optional = true, features = ["bundled"] } parking_lot = { version = "0.12.1", optional = true } -crossbeam = { version = "0.8.2", optional = true } +# crossbeam = { version = "0.8.2", optional = true } num_cpus = "1.15.0" threadpool = "1.8.1" -heed = { git = "https://github.com/timokoesters/heed.git", rev = "f6f825da7fb2c758867e05ad973ef800a6fe1d5d", optional = true } +# heed = { git = "https://github.com/timokoesters/heed.git", rev = "f6f825da7fb2c758867e05ad973ef800a6fe1d5d", optional = true } # Used for ruma wrapper serde_html_form = "0.2.0" @@ -112,7 +112,7 @@ default = ["conduit_bin", "backend_sqlite", "backend_rocksdb", "systemd"] #backend_sled = ["sled"] backend_persy = ["persy", "parking_lot"] backend_sqlite = ["sqlite"] -backend_heed = ["heed", "crossbeam"] +#backend_heed = ["heed", "crossbeam"] backend_rocksdb = ["rocksdb"] jemalloc = ["tikv-jemalloc-ctl", "tikv-jemallocator"] sqlite = ["rusqlite", "parking_lot", "tokio/signal"] From 92c5b6b86cb40704da2a638847a4cc37dfe61212 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sat, 23 Dec 2023 19:34:27 -0800 Subject: [PATCH 007/129] fix `cargo check` lints --- src/api/client_server/keys.rs | 4 ++-- src/api/client_server/session.rs | 2 ++ src/api/server_server.rs | 2 +- src/database/key_value/rooms/threads.rs | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/api/client_server/keys.rs b/src/api/client_server/keys.rs index 7dbe040d..9fd00897 100644 --- a/src/api/client_server/keys.rs +++ b/src/api/client_server/keys.rs @@ -360,7 +360,7 @@ pub(crate) async fn get_keys_helper bool>( .bad_query_ratelimiter .read() .unwrap() - .get(&*server) + .get(server) { // Exponential backoff let mut min_elapsed_duration = Duration::from_secs(30) * (*tries) * (*tries); @@ -393,7 +393,7 @@ pub(crate) async fn get_keys_helper bool>( ), ) .await - .map_err(|e| Error::BadServerResponse("Query took too long")), + .map_err(|_e| Error::BadServerResponse("Query took too long")), ) }) .collect(); diff --git a/src/api/client_server/session.rs b/src/api/client_server/session.rs index 5ce62af9..5ffd8134 100644 --- a/src/api/client_server/session.rs +++ b/src/api/client_server/session.rs @@ -163,6 +163,8 @@ pub async fn login_route(body: Ruma) -> Result Result> + 'a>> { let prefix = services() .rooms @@ -27,7 +27,7 @@ impl service::rooms::threads::Data for KeyValueDatabase { self.threadid_userids .iter_from(¤t, true) .take_while(move |(k, _)| k.starts_with(&prefix)) - .map(move |(pduid, users)| { + .map(move |(pduid, _users)| { let count = utils::u64_from_bytes(&pduid[(mem::size_of::())..]) .map_err(|_| Error::bad_database("Invalid pduid in threadid_userids."))?; let mut pdu = services() From ab1fff2642be961f052dde06b2c03c588d904d51 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sat, 23 Dec 2023 19:48:14 -0800 Subject: [PATCH 008/129] fix `cargo clippy` lints --- src/api/client_server/membership.rs | 10 +- src/api/client_server/message.rs | 2 +- src/api/client_server/relations.rs | 6 +- src/api/client_server/session.rs | 10 +- src/api/client_server/state.rs | 6 +- src/api/client_server/sync.rs | 175 +++++++++--------- src/api/server_server.rs | 10 +- src/config/proxy.rs | 7 +- src/database/abstraction/watchers.rs | 1 + .../key_value/rooms/state_accessor.rs | 6 +- src/database/key_value/rooms/state_cache.rs | 2 + src/database/key_value/rooms/threads.rs | 4 +- src/database/key_value/rooms/timeline.rs | 11 +- src/main.rs | 2 +- src/service/rooms/edus/read_receipt/data.rs | 1 + src/service/rooms/event_handler/mod.rs | 4 +- src/service/rooms/lazy_loading/mod.rs | 1 + src/service/rooms/pdu_metadata/data.rs | 1 + src/service/rooms/pdu_metadata/mod.rs | 7 +- src/service/rooms/search/data.rs | 1 + src/service/rooms/spaces/mod.rs | 43 ++--- src/service/rooms/state/mod.rs | 4 +- src/service/rooms/state_accessor/mod.rs | 16 +- src/service/rooms/state_cache/data.rs | 2 + src/service/rooms/state_compressor/mod.rs | 12 +- src/service/rooms/threads/data.rs | 1 + src/service/rooms/threads/mod.rs | 4 +- src/service/rooms/timeline/data.rs | 2 + src/service/rooms/timeline/mod.rs | 53 +++--- src/service/sending/data.rs | 1 + src/service/users/mod.rs | 1 + 31 files changed, 203 insertions(+), 203 deletions(-) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 346f2575..ed59691d 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -400,7 +400,7 @@ pub async fn get_member_events_route( if !services() .rooms .state_accessor - .user_can_see_state_events(&sender_user, &body.room_id)? + .user_can_see_state_events(sender_user, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -435,7 +435,7 @@ pub async fn joined_members_route( if !services() .rooms .state_accessor - .user_can_see_state_events(&sender_user, &body.room_id)? + .user_can_see_state_events(sender_user, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -712,7 +712,7 @@ async fn join_room_by_id_helper( } info!("Running send_join auth check"); - if !state_res::event_auth::auth_check( + let authenticated = 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 @@ -735,7 +735,9 @@ async fn join_room_by_id_helper( .map_err(|e| { warn!("Auth check failed: {e}"); Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed") - })? { + })?; + + if !authenticated { return Err(Error::BadRequest( ErrorKind::InvalidParam, "Auth check failed", diff --git a/src/api/client_server/message.rs b/src/api/client_server/message.rs index 750e0303..0952092b 100644 --- a/src/api/client_server/message.rs +++ b/src/api/client_server/message.rs @@ -124,7 +124,7 @@ pub async fn get_message_events_route( let to = body .to .as_ref() - .and_then(|t| PduCount::try_from_string(&t).ok()); + .and_then(|t| PduCount::try_from_string(t).ok()); services().rooms.lazy_loading.lazy_load_confirm_delivery( sender_user, diff --git a/src/api/client_server/relations.rs b/src/api/client_server/relations.rs index a7cea786..124f1310 100644 --- a/src/api/client_server/relations.rs +++ b/src/api/client_server/relations.rs @@ -23,7 +23,7 @@ pub async fn get_relating_events_with_rel_type_and_event_type_route( let to = body .to .as_ref() - .and_then(|t| PduCount::try_from_string(&t).ok()); + .and_then(|t| PduCount::try_from_string(t).ok()); // Use limit or else 10, with maximum 100 let limit = body @@ -73,7 +73,7 @@ pub async fn get_relating_events_with_rel_type_route( let to = body .to .as_ref() - .and_then(|t| PduCount::try_from_string(&t).ok()); + .and_then(|t| PduCount::try_from_string(t).ok()); // Use limit or else 10, with maximum 100 let limit = body @@ -121,7 +121,7 @@ pub async fn get_relating_events_route( let to = body .to .as_ref() - .and_then(|t| PduCount::try_from_string(&t).ok()); + .and_then(|t| PduCount::try_from_string(t).ok()); // Use limit or else 10, with maximum 100 let limit = body diff --git a/src/api/client_server/session.rs b/src/api/client_server/session.rs index 5ffd8134..c17bd99b 100644 --- a/src/api/client_server/session.rs +++ b/src/api/client_server/session.rs @@ -117,12 +117,10 @@ pub async fn login_route(body: Ruma) -> Result { warn!("Unsupported or unknown login type: {:?}", &body.login_info); diff --git a/src/api/client_server/state.rs b/src/api/client_server/state.rs index d6d39390..174282a1 100644 --- a/src/api/client_server/state.rs +++ b/src/api/client_server/state.rs @@ -85,7 +85,7 @@ pub async fn get_state_events_route( if !services() .rooms .state_accessor - .user_can_see_state_events(&sender_user, &body.room_id)? + .user_can_see_state_events(sender_user, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -118,7 +118,7 @@ pub async fn get_state_events_for_key_route( if !services() .rooms .state_accessor - .user_can_see_state_events(&sender_user, &body.room_id)? + .user_can_see_state_events(sender_user, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -157,7 +157,7 @@ pub async fn get_state_events_for_empty_key_route( if !services() .rooms .state_accessor - .user_can_see_state_events(&sender_user, &body.room_id)? + .user_can_see_state_events(sender_user, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index a275b066..57572284 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -554,6 +554,7 @@ async fn sync_helper( } } +#[allow(clippy::too_many_arguments)] async fn load_joined_room( sender_user: &UserId, sender_device: &DeviceId, @@ -590,7 +591,7 @@ async fn load_joined_room( || services() .rooms .user - .last_notification_read(&sender_user, &room_id)? + .last_notification_read(sender_user, room_id)? > since; let mut timeline_users = HashSet::new(); @@ -599,16 +600,16 @@ async fn load_joined_room( } services().rooms.lazy_loading.lazy_load_confirm_delivery( - &sender_user, - &sender_device, - &room_id, + sender_user, + sender_device, + room_id, sincecount, )?; // Database queries: let current_shortstatehash = - if let Some(s) = services().rooms.state.get_room_shortstatehash(&room_id)? { + if let Some(s) = services().rooms.state.get_room_shortstatehash(room_id)? { s } else { error!("Room {} has no state", room_id); @@ -618,7 +619,7 @@ async fn load_joined_room( let since_shortstatehash = services() .rooms .user - .get_token_shortstatehash(&room_id, since)?; + .get_token_shortstatehash(room_id, since)?; let (heroes, joined_member_count, invited_member_count, joined_since_last_sync, state_events) = if timeline_pdus.is_empty() && since_shortstatehash == Some(current_shortstatehash) { @@ -630,12 +631,12 @@ async fn load_joined_room( let joined_member_count = services() .rooms .state_cache - .room_joined_count(&room_id)? + .room_joined_count(room_id)? .unwrap_or(0); let invited_member_count = services() .rooms .state_cache - .room_invited_count(&room_id)? + .room_invited_count(room_id)? .unwrap_or(0); // Recalculate heroes (first 5 members) @@ -648,7 +649,7 @@ async fn load_joined_room( for hero in services() .rooms .timeline - .all_pdus(&sender_user, &room_id)? + .all_pdus(sender_user, room_id)? .filter_map(|pdu| pdu.ok()) // Ignore all broken pdus .filter(|(_, pdu)| pdu.kind == TimelineEventType::RoomMember) .map(|(_, pdu)| { @@ -669,11 +670,11 @@ async fn load_joined_room( ) && (services() .rooms .state_cache - .is_joined(&user_id, &room_id)? + .is_joined(&user_id, room_id)? || services() .rooms .state_cache - .is_invited(&user_id, &room_id)?) + .is_invited(&user_id, room_id)?) { Ok::<_, Error>(Some(state_key.clone())) } else { @@ -789,17 +790,17 @@ async fn load_joined_room( // Reset lazy loading because this is an initial sync services().rooms.lazy_loading.lazy_load_reset( - &sender_user, - &sender_device, - &room_id, + sender_user, + sender_device, + room_id, )?; // The state_events above should contain all timeline_users, let's mark them as lazy // loaded. services().rooms.lazy_loading.lazy_load_mark_sent( - &sender_user, - &sender_device, - &room_id, + sender_user, + sender_device, + room_id, lazy_loaded, next_batchcount, ); @@ -866,14 +867,14 @@ async fn load_joined_room( } if !services().rooms.lazy_loading.lazy_load_was_sent_before( - &sender_user, - &sender_device, - &room_id, + sender_user, + sender_device, + room_id, &event.sender, )? || lazy_load_send_redundant { if let Some(member_event) = services().rooms.state_accessor.room_state_get( - &room_id, + room_id, &StateEventType::RoomMember, event.sender.as_str(), )? { @@ -884,9 +885,9 @@ async fn load_joined_room( } services().rooms.lazy_loading.lazy_load_mark_sent( - &sender_user, - &sender_device, - &room_id, + sender_user, + sender_device, + room_id, lazy_loaded, next_batchcount, ); @@ -934,7 +935,7 @@ async fn load_joined_room( match new_membership { MembershipState::Join => { // A new user joined an encrypted room - if !share_encrypted_room(&sender_user, &user_id, &room_id)? { + if !share_encrypted_room(sender_user, &user_id, room_id)? { device_list_updates.insert(user_id); } } @@ -954,15 +955,15 @@ async fn load_joined_room( services() .rooms .state_cache - .room_members(&room_id) + .room_members(room_id) .flatten() .filter(|user_id| { // Don't send key updates from the sender to the sender - &sender_user != user_id + sender_user != user_id }) .filter(|user_id| { // Only send keys if the sender doesn't share an encrypted room with the target already - !share_encrypted_room(&sender_user, user_id, &room_id) + !share_encrypted_room(sender_user, user_id, room_id) .unwrap_or(false) }), ); @@ -997,7 +998,7 @@ async fn load_joined_room( services() .rooms .user - .notification_count(&sender_user, &room_id)? + .notification_count(sender_user, room_id)? .try_into() .expect("notification count can't go that high"), ) @@ -1010,7 +1011,7 @@ async fn load_joined_room( services() .rooms .user - .highlight_count(&sender_user, &room_id)? + .highlight_count(sender_user, room_id)? .try_into() .expect("highlight count can't go that high"), ) @@ -1039,15 +1040,15 @@ async fn load_joined_room( .rooms .edus .read_receipt - .readreceipts_since(&room_id, since) + .readreceipts_since(room_id, since) .filter_map(|r| r.ok()) // Filter out buggy events .map(|(_, _, v)| v) .collect(); - if services().rooms.edus.typing.last_typing_update(&room_id)? > since { + if services().rooms.edus.typing.last_typing_update(room_id)? > since { edus.push( serde_json::from_str( - &serde_json::to_string(&services().rooms.edus.typing.typings_all(&room_id)?) + &serde_json::to_string(&services().rooms.edus.typing.typings_all(room_id)?) .expect("event is valid, we just created it"), ) .expect("event is valid, we just created it"), @@ -1056,7 +1057,7 @@ async fn load_joined_room( // Save the state after this sync so we can send the correct state diff next sync services().rooms.user.associate_token_shortstatehash( - &room_id, + room_id, next_batch, current_shortstatehash, )?; @@ -1065,7 +1066,7 @@ async fn load_joined_room( account_data: RoomAccountData { events: services() .account_data - .changes_since(Some(&room_id), &sender_user, since)? + .changes_since(Some(room_id), sender_user, since)? .into_iter() .filter_map(|(_, v)| { serde_json::from_str(v.json().get()) @@ -1110,13 +1111,13 @@ fn load_timeline( if services() .rooms .timeline - .last_timeline_count(&sender_user, &room_id)? + .last_timeline_count(sender_user, room_id)? > roomsincecount { let mut non_timeline_pdus = services() .rooms .timeline - .pdus_until(&sender_user, &room_id, PduCount::max())? + .pdus_until(sender_user, room_id, PduCount::max())? .filter_map(|r| { // Filter out buggy events if r.is_err() { @@ -1172,7 +1173,6 @@ fn share_encrypted_room( pub async fn sync_events_v4_route( body: Ruma, ) -> Result> { - dbg!(&body.body); let sender_user = body.sender_user.expect("user is authenticated"); let sender_device = body.sender_device.expect("user is authenticated"); let mut body = body.body; @@ -1232,7 +1232,7 @@ pub async fn sync_events_v4_route( for room_id in &all_joined_rooms { let current_shortstatehash = - if let Some(s) = services().rooms.state.get_room_shortstatehash(&room_id)? { + if let Some(s) = services().rooms.state.get_room_shortstatehash(room_id)? { s } else { error!("Room {} has no state", room_id); @@ -1242,7 +1242,7 @@ pub async fn sync_events_v4_route( let since_shortstatehash = services() .rooms .user - .get_token_shortstatehash(&room_id, globalsince)?; + .get_token_shortstatehash(room_id, globalsince)?; let since_sender_member: Option = since_shortstatehash .and_then(|shortstatehash| { @@ -1331,7 +1331,7 @@ pub async fn sync_events_v4_route( if !share_encrypted_room( &sender_user, &user_id, - &room_id, + room_id, )? { device_list_changes.insert(user_id); } @@ -1352,7 +1352,7 @@ pub async fn sync_events_v4_route( services() .rooms .state_cache - .room_members(&room_id) + .room_members(room_id) .flatten() .filter(|user_id| { // Don't send key updates from the sender to the sender @@ -1360,7 +1360,7 @@ pub async fn sync_events_v4_route( }) .filter(|user_id| { // Only send keys if the sender doesn't share an encrypted room with the target already - !share_encrypted_room(&sender_user, user_id, &room_id) + !share_encrypted_room(&sender_user, user_id, room_id) .unwrap_or(false) }), ); @@ -1451,7 +1451,7 @@ pub async fn sync_events_v4_route( } sync_events::v4::SyncOp { op: SlidingOp::Sync, - range: Some(r.clone()), + range: Some(r), index: None, room_ids, room_id: None, @@ -1523,7 +1523,7 @@ pub async fn sync_events_v4_route( let roomsincecount = PduCount::Normal(*roomsince); let (timeline_pdus, limited) = - load_timeline(&sender_user, &room_id, roomsincecount, *timeline_limit)?; + load_timeline(&sender_user, room_id, roomsincecount, *timeline_limit)?; if roomsince != &0 && timeline_pdus.is_empty() { continue; @@ -1555,63 +1555,58 @@ pub async fn sync_events_v4_route( let required_state = required_state_request .iter() - .map(|state| { + .flat_map(|state| { services() .rooms .state_accessor - .room_state_get(&room_id, &state.0, &state.1) + .room_state_get(room_id, &state.0, &state.1) + .ok() + .flatten() + .map(|state| state.to_sync_state_event()) }) - .filter_map(|r| r.ok()) - .filter_map(|o| o) - .map(|state| state.to_sync_state_event()) .collect(); // Heroes let heroes = services() .rooms .state_cache - .room_members(&room_id) + .room_members(room_id) .filter_map(|r| r.ok()) .filter(|member| member != &sender_user) - .map(|member| { - Ok::<_, Error>( - services() - .rooms - .state_accessor - .get_member(&room_id, &member)? - .map(|memberevent| { - ( - memberevent - .displayname - .unwrap_or_else(|| member.to_string()), - memberevent.avatar_url, - ) - }), - ) + .flat_map(|member| { + services() + .rooms + .state_accessor + .get_member(room_id, &member) + .ok() + .flatten() + .map(|memberevent| { + ( + memberevent + .displayname + .unwrap_or_else(|| member.to_string()), + memberevent.avatar_url, + ) + }) }) - .filter_map(|r| r.ok()) - .filter_map(|o| o) .take(5) .collect::>(); - let name = if heroes.len() > 1 { - let last = heroes[0].0.clone(); - Some( - heroes[1..] + let name = match &heroes[..] { + [] => None, + [only] => Some(only.0.clone()), + [firsts @ .., last] => Some( + firsts .iter() .map(|h| h.0.clone()) .collect::>() .join(", ") + " and " - + &last, - ) - } else if heroes.len() == 1 { - Some(heroes[0].0.clone()) - } else { - None + + &last.0, + ), }; - let avatar = if heroes.len() == 1 { - heroes[0].1.clone() + let avatar = if let [only] = &heroes[..] { + only.1.clone() } else { None }; @@ -1619,15 +1614,11 @@ pub async fn sync_events_v4_route( rooms.insert( room_id.clone(), sync_events::v4::SlidingSyncRoom { - name: services() - .rooms - .state_accessor - .get_name(&room_id)? - .or_else(|| name), + name: services().rooms.state_accessor.get_name(room_id)?.or(name), avatar: services() .rooms .state_accessor - .get_avatar(&room_id)? + .get_avatar(room_id)? .map_or(avatar, |a| a.url), initial: Some(roomsince == &0), is_dm: None, @@ -1637,7 +1628,7 @@ pub async fn sync_events_v4_route( services() .rooms .user - .highlight_count(&sender_user, &room_id)? + .highlight_count(&sender_user, room_id)? .try_into() .expect("notification count can't go that high"), ), @@ -1645,7 +1636,7 @@ pub async fn sync_events_v4_route( services() .rooms .user - .notification_count(&sender_user, &room_id)? + .notification_count(&sender_user, room_id)? .try_into() .expect("notification count can't go that high"), ), @@ -1658,7 +1649,7 @@ pub async fn sync_events_v4_route( (services() .rooms .state_cache - .room_joined_count(&room_id)? + .room_joined_count(room_id)? .unwrap_or(0) as u32) .into(), ), @@ -1666,7 +1657,7 @@ pub async fn sync_events_v4_route( (services() .rooms .state_cache - .room_invited_count(&room_id)? + .room_invited_count(room_id)? .unwrap_or(0) as u32) .into(), ), @@ -1689,7 +1680,7 @@ pub async fn sync_events_v4_route( let _ = tokio::time::timeout(duration, watcher).await; } - Ok(dbg!(sync_events::v4::Response { + Ok(sync_events::v4::Response { initial: globalsince == 0, txn_id: body.txn_id.clone(), pos: next_batch.to_string(), @@ -1744,5 +1735,5 @@ pub async fn sync_events_v4_route( }, }, delta_token: None, - })) + }) } diff --git a/src/api/server_server.rs b/src/api/server_server.rs index a11857dc..79f921e3 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -666,7 +666,7 @@ pub fn parse_incoming_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) { + 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 @@ -724,7 +724,7 @@ pub async fn send_transaction_message_route( continue; } - let r = parse_incoming_pdu(&pdu); + let r = parse_incoming_pdu(pdu); let (event_id, value, room_id) = match r { Ok(t) => t, Err(e) => { @@ -992,7 +992,7 @@ pub async fn get_event_route( if !services().rooms.state_accessor.server_can_see_event( sender_servername, - &room_id, + room_id, &body.event_id, )? { return Err(Error::BadRequest( @@ -1058,7 +1058,7 @@ pub async fn get_backfill_route( let all_events = services() .rooms .timeline - .pdus_until(&user_id!("@doesntmatter:conduit.rs"), &body.room_id, until)? + .pdus_until(user_id!("@doesntmatter:conduit.rs"), &body.room_id, until)? .take(limit.try_into().unwrap()); let events = all_events @@ -1075,7 +1075,7 @@ pub async fn get_backfill_route( }) .map(|(_, pdu)| services().rooms.timeline.get_pdu_json(&pdu.event_id)) .filter_map(|r| r.ok().flatten()) - .map(|pdu| PduEvent::convert_to_outgoing_federation_event(pdu)) + .map(PduEvent::convert_to_outgoing_federation_event) .collect(); Ok(get_backfill::v1::Response { diff --git a/src/config/proxy.rs b/src/config/proxy.rs index dcf304e9..c03463e7 100644 --- a/src/config/proxy.rs +++ b/src/config/proxy.rs @@ -29,7 +29,9 @@ use crate::Result; /// would be used for `ordinary.onion`, `matrix.myspecial.onion`, but not `hello.myspecial.onion`. #[derive(Clone, Debug, Deserialize)] #[serde(rename_all = "snake_case")] +#[derive(Default)] pub enum ProxyConfig { + #[default] None, Global { #[serde(deserialize_with = "crate::utils::deserialize_from_str")] @@ -48,11 +50,6 @@ impl ProxyConfig { }) } } -impl Default for ProxyConfig { - fn default() -> Self { - ProxyConfig::None - } -} #[derive(Clone, Debug, Deserialize)] pub struct PartialProxyConfig { diff --git a/src/database/abstraction/watchers.rs b/src/database/abstraction/watchers.rs index 55cb60b3..01156abd 100644 --- a/src/database/abstraction/watchers.rs +++ b/src/database/abstraction/watchers.rs @@ -8,6 +8,7 @@ use tokio::sync::watch; #[derive(Default)] pub(super) struct Watchers { + #[allow(clippy::type_complexity)] watchers: RwLock, (watch::Sender<()>, watch::Receiver<()>)>>, } diff --git a/src/database/key_value/rooms/state_accessor.rs b/src/database/key_value/rooms/state_accessor.rs index ad08f46e..fe40b937 100644 --- a/src/database/key_value/rooms/state_accessor.rs +++ b/src/database/key_value/rooms/state_accessor.rs @@ -20,7 +20,7 @@ impl service::rooms::state_accessor::Data for KeyValueDatabase { let parsed = services() .rooms .state_compressor - .parse_compressed_state_event(&compressed)?; + .parse_compressed_state_event(compressed)?; result.insert(parsed.0, parsed.1); i += 1; @@ -49,7 +49,7 @@ impl service::rooms::state_accessor::Data for KeyValueDatabase { let (_, eventid) = services() .rooms .state_compressor - .parse_compressed_state_event(&compressed)?; + .parse_compressed_state_event(compressed)?; if let Some(pdu) = services().rooms.timeline.get_pdu(&eventid)? { result.insert( ( @@ -101,7 +101,7 @@ impl service::rooms::state_accessor::Data for KeyValueDatabase { services() .rooms .state_compressor - .parse_compressed_state_event(&compressed) + .parse_compressed_state_event(compressed) .ok() .map(|(_, id)| id) })) diff --git a/src/database/key_value/rooms/state_cache.rs b/src/database/key_value/rooms/state_cache.rs index d0ea0c2c..3dcaf4ae 100644 --- a/src/database/key_value/rooms/state_cache.rs +++ b/src/database/key_value/rooms/state_cache.rs @@ -471,6 +471,7 @@ impl service::rooms::state_cache::Data for KeyValueDatabase { } /// Returns an iterator over all rooms a user was invited to. + #[allow(clippy::type_complexity)] #[tracing::instrument(skip(self))] fn rooms_invited<'a>( &'a self, @@ -549,6 +550,7 @@ impl service::rooms::state_cache::Data for KeyValueDatabase { } /// Returns an iterator over all rooms a user left. + #[allow(clippy::type_complexity)] #[tracing::instrument(skip(self))] fn rooms_left<'a>( &'a self, diff --git a/src/database/key_value/rooms/threads.rs b/src/database/key_value/rooms/threads.rs index 35c4e6e2..5e3dc970 100644 --- a/src/database/key_value/rooms/threads.rs +++ b/src/database/key_value/rooms/threads.rs @@ -52,13 +52,13 @@ impl service::rooms::threads::Data for KeyValueDatabase { .collect::>() .join(&[0xff][..]); - self.threadid_userids.insert(&root_id, &users)?; + self.threadid_userids.insert(root_id, &users)?; Ok(()) } fn get_participants(&self, root_id: &[u8]) -> Result>> { - if let Some(users) = self.threadid_userids.get(&root_id)? { + if let Some(users) = self.threadid_userids.get(root_id)? { Ok(Some( users .split(|b| *b == 0xff) diff --git a/src/database/key_value/rooms/timeline.rs b/src/database/key_value/rooms/timeline.rs index ba1e85ef..f322d430 100644 --- a/src/database/key_value/rooms/timeline.rs +++ b/src/database/key_value/rooms/timeline.rs @@ -39,11 +39,10 @@ impl service::rooms::timeline::Data for KeyValueDatabase { /// Returns the `count` of this pdu's id. fn get_pdu_count(&self, event_id: &EventId) -> Result> { - Ok(self - .eventid_pduid + self.eventid_pduid .get(event_id.as_bytes())? .map(|pdu_id| pdu_count(&pdu_id)) - .transpose()?) + .transpose() } /// Returns the json of a pdu. @@ -80,7 +79,7 @@ impl service::rooms::timeline::Data for KeyValueDatabase { /// Returns the pdu's id. fn get_pdu_id(&self, event_id: &EventId) -> Result>> { - Ok(self.eventid_pduid.get(event_id.as_bytes())?) + self.eventid_pduid.get(event_id.as_bytes()) } /// Returns the pdu. @@ -230,7 +229,7 @@ impl service::rooms::timeline::Data for KeyValueDatabase { room_id: &RoomId, until: PduCount, ) -> Result> + 'a>> { - let (prefix, current) = count_to_id(&room_id, until, 1, true)?; + let (prefix, current) = count_to_id(room_id, until, 1, true)?; let user_id = user_id.to_owned(); @@ -257,7 +256,7 @@ impl service::rooms::timeline::Data for KeyValueDatabase { room_id: &RoomId, from: PduCount, ) -> Result> + 'a>> { - let (prefix, current) = count_to_id(&room_id, from, 1, false)?; + let (prefix, current) = count_to_id(room_id, from, 1, false)?; let user_id = user_id.to_owned(); diff --git a/src/main.rs b/src/main.rs index c74d6ddb..683e0914 100644 --- a/src/main.rs +++ b/src/main.rs @@ -238,7 +238,7 @@ async fn spawn_task( .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR) } -async fn unrecognized_method( +async fn unrecognized_method( req: axum::http::Request, next: axum::middleware::Next, ) -> std::result::Result { diff --git a/src/service/rooms/edus/read_receipt/data.rs b/src/service/rooms/edus/read_receipt/data.rs index a183d196..044dad82 100644 --- a/src/service/rooms/edus/read_receipt/data.rs +++ b/src/service/rooms/edus/read_receipt/data.rs @@ -11,6 +11,7 @@ pub trait Data: Send + Sync { ) -> Result<()>; /// Returns an iterator over the most recent read_receipts in a room that happened after the event with id `since`. + #[allow(clippy::type_complexity)] fn readreceipts_since<'a>( &'a self, room_id: &RoomId, diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 29199781..e7db6f78 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -92,7 +92,7 @@ impl Service { )); } - services().rooms.event_handler.acl_check(origin, &room_id)?; + services().rooms.event_handler.acl_check(origin, room_id)?; // 1. Skip the PDU if we already have it as a timeline event if let Some(pdu_id) = services().rooms.timeline.get_pdu_id(event_id)? { @@ -276,6 +276,7 @@ impl Service { r } + #[allow(clippy::type_complexity, clippy::too_many_arguments)] #[tracing::instrument(skip(self, create_event, value, pub_key_map))] fn handle_outlier_pdu<'a>( &'a self, @@ -1009,6 +1010,7 @@ impl Service { /// b. Look at outlier pdu tree /// c. Ask origin server over federation /// d. TODO: Ask other servers over federation? + #[allow(clippy::type_complexity)] #[tracing::instrument(skip_all)] pub(crate) fn fetch_and_handle_outliers<'a>( &'a self, diff --git a/src/service/rooms/lazy_loading/mod.rs b/src/service/rooms/lazy_loading/mod.rs index e6e4f896..c51a57e9 100644 --- a/src/service/rooms/lazy_loading/mod.rs +++ b/src/service/rooms/lazy_loading/mod.rs @@ -14,6 +14,7 @@ use super::timeline::PduCount; pub struct Service { pub db: &'static dyn Data, + #[allow(clippy::type_complexity)] pub lazy_load_waiting: Mutex>>, } diff --git a/src/service/rooms/pdu_metadata/data.rs b/src/service/rooms/pdu_metadata/data.rs index 6c4cb3ce..a4df34cc 100644 --- a/src/service/rooms/pdu_metadata/data.rs +++ b/src/service/rooms/pdu_metadata/data.rs @@ -5,6 +5,7 @@ use ruma::{EventId, RoomId, UserId}; pub trait Data: Send + Sync { fn add_relation(&self, from: u64, to: u64) -> Result<()>; + #[allow(clippy::type_complexity)] fn relations_until<'a>( &'a self, user_id: &'a UserId, diff --git a/src/service/rooms/pdu_metadata/mod.rs b/src/service/rooms/pdu_metadata/mod.rs index 9ce74f4d..411f4f54 100644 --- a/src/service/rooms/pdu_metadata/mod.rs +++ b/src/service/rooms/pdu_metadata/mod.rs @@ -40,6 +40,7 @@ impl Service { } } + #[allow(clippy::too_many_arguments)] pub fn paginate_relations_with_filter( &self, sender_user: &UserId, @@ -82,7 +83,7 @@ impl Service { services() .rooms .state_accessor - .user_can_see_event(sender_user, &room_id, &pdu.event_id) + .user_can_see_event(sender_user, room_id, &pdu.event_id) .unwrap_or(false) }) .take_while(|&(k, _)| Some(k) != to) // Stop at `to` @@ -106,7 +107,7 @@ impl Service { let events_before: Vec<_> = services() .rooms .pdu_metadata - .relations_until(sender_user, &room_id, target, from)? + .relations_until(sender_user, room_id, target, from)? .filter(|r| { r.as_ref().map_or(true, |(_, pdu)| { filter_event_type.as_ref().map_or(true, |t| &pdu.kind == t) @@ -129,7 +130,7 @@ impl Service { services() .rooms .state_accessor - .user_can_see_event(sender_user, &room_id, &pdu.event_id) + .user_can_see_event(sender_user, room_id, &pdu.event_id) .unwrap_or(false) }) .take_while(|&(k, _)| Some(k) != to) // Stop at `to` diff --git a/src/service/rooms/search/data.rs b/src/service/rooms/search/data.rs index 6eef38fb..7ea7e3d1 100644 --- a/src/service/rooms/search/data.rs +++ b/src/service/rooms/search/data.rs @@ -4,6 +4,7 @@ use ruma::RoomId; pub trait Data: Send + Sync { fn index_pdu(&self, shortroomid: u64, pdu_id: &[u8], message_body: &str) -> Result<()>; + #[allow(clippy::type_complexity)] fn search_pdus<'a>( &'a self, room_id: &RoomId, diff --git a/src/service/rooms/spaces/mod.rs b/src/service/rooms/spaces/mod.rs index 53232f46..615e9ca0 100644 --- a/src/service/rooms/spaces/mod.rs +++ b/src/service/rooms/spaces/mod.rs @@ -197,7 +197,7 @@ impl Service { if let Ok(response) = services() .sending .send_federation_request( - &server, + server, federation::space::get_hierarchy::v1::Request { room_id: current_room.to_owned(), suggested_only, @@ -235,7 +235,7 @@ impl Service { .room .allowed_room_ids .into_iter() - .map(|room| AllowRule::room_membership(room)) + .map(AllowRule::room_membership) .collect(), }) } @@ -245,7 +245,7 @@ impl Service { .room .allowed_room_ids .into_iter() - .map(|room| AllowRule::room_membership(room)) + .map(AllowRule::room_membership) .collect(), }) } @@ -313,7 +313,7 @@ impl Service { canonical_alias: services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomCanonicalAlias, "")? + .room_state_get(room_id, &StateEventType::RoomCanonicalAlias, "")? .map_or(Ok(None), |s| { serde_json::from_str(s.content.get()) .map(|c: RoomCanonicalAliasEventContent| c.alias) @@ -321,11 +321,11 @@ impl Service { Error::bad_database("Invalid canonical alias event in database.") }) })?, - name: services().rooms.state_accessor.get_name(&room_id)?, + name: services().rooms.state_accessor.get_name(room_id)?, num_joined_members: services() .rooms .state_cache - .room_joined_count(&room_id)? + .room_joined_count(room_id)? .unwrap_or_else(|| { warn!("Room {} has no member count", room_id); 0 @@ -336,7 +336,7 @@ impl Service { topic: services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomTopic, "")? + .room_state_get(room_id, &StateEventType::RoomTopic, "")? .map_or(Ok(None), |s| { serde_json::from_str(s.content.get()) .map(|c: RoomTopicEventContent| Some(c.topic)) @@ -348,7 +348,7 @@ impl Service { world_readable: services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomHistoryVisibility, "")? + .room_state_get(room_id, &StateEventType::RoomHistoryVisibility, "")? .map_or(Ok(false), |s| { serde_json::from_str(s.content.get()) .map(|c: RoomHistoryVisibilityEventContent| { @@ -363,7 +363,7 @@ impl Service { guest_can_join: services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomGuestAccess, "")? + .room_state_get(room_id, &StateEventType::RoomGuestAccess, "")? .map_or(Ok(false), |s| { serde_json::from_str(s.content.get()) .map(|c: RoomGuestAccessEventContent| { @@ -376,7 +376,7 @@ impl Service { avatar_url: services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomAvatar, "")? + .room_state_get(room_id, &StateEventType::RoomAvatar, "")? .map(|s| { serde_json::from_str(s.content.get()) .map(|c: RoomAvatarEventContent| c.url) @@ -389,7 +389,7 @@ impl Service { let join_rule = services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomJoinRules, "")? + .room_state_get(room_id, &StateEventType::RoomJoinRules, "")? .map(|s| { serde_json::from_str(s.content.get()) .map(|c: RoomJoinRulesEventContent| c.join_rule) @@ -415,7 +415,7 @@ impl Service { room_type: services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomCreate, "")? + .room_state_get(room_id, &StateEventType::RoomCreate, "")? .map(|s| { serde_json::from_str::(s.content.get()).map_err(|e| { error!("Invalid room create event in database: {}", e); @@ -455,7 +455,7 @@ impl Service { SpaceRoomJoinRule::Invite => services() .rooms .state_cache - .is_joined(sender_user, &room_id)?, + .is_joined(sender_user, room_id)?, _ => false, }; @@ -479,17 +479,14 @@ impl Service { match join_rule { JoinRule::Restricted(r) => { for rule in &r.allow { - match rule { - join_rules::AllowRule::RoomMembership(rm) => { - if let Ok(true) = services() - .rooms - .state_cache - .is_joined(sender_user, &rm.room_id) - { - return Ok(true); - } + if let join_rules::AllowRule::RoomMembership(rm) = rule { + if let Ok(true) = services() + .rooms + .state_cache + .is_joined(sender_user, &rm.room_id) + { + return Ok(true); } - _ => {} } } diff --git a/src/service/rooms/state/mod.rs b/src/service/rooms/state/mod.rs index 48c60203..c209eb5a 100644 --- a/src/service/rooms/state/mod.rs +++ b/src/service/rooms/state/mod.rs @@ -41,7 +41,7 @@ impl Service { services() .rooms .state_compressor - .parse_compressed_state_event(&new) + .parse_compressed_state_event(new) .ok() .map(|(_, id)| id) }) { @@ -412,7 +412,7 @@ impl Service { services() .rooms .state_compressor - .parse_compressed_state_event(&compressed) + .parse_compressed_state_event(compressed) .ok() }) .filter_map(|(shortstatekey, event_id)| { diff --git a/src/service/rooms/state_accessor/mod.rs b/src/service/rooms/state_accessor/mod.rs index a4a62fe4..b00dc58c 100644 --- a/src/service/rooms/state_accessor/mod.rs +++ b/src/service/rooms/state_accessor/mod.rs @@ -180,7 +180,7 @@ impl Service { return Ok(*visibility); } - let currently_member = services().rooms.state_cache.is_joined(&user_id, &room_id)?; + let currently_member = services().rooms.state_cache.is_joined(user_id, room_id)?; let history_visibility = self .state_get(shortstatehash, &StateEventType::RoomHistoryVisibility, "")? @@ -197,11 +197,11 @@ impl Service { HistoryVisibility::Shared => currently_member, HistoryVisibility::Invited => { // Allow if any member on requesting server was AT LEAST invited, else deny - self.user_was_invited(shortstatehash, &user_id) + self.user_was_invited(shortstatehash, user_id) } HistoryVisibility::Joined => { // Allow if any member on requested server was joined, else deny - self.user_was_joined(shortstatehash, &user_id) + self.user_was_joined(shortstatehash, user_id) } _ => { error!("Unknown history visibility {history_visibility}"); @@ -221,10 +221,10 @@ impl Service { /// the room's history_visibility at that event's state. #[tracing::instrument(skip(self, user_id, room_id))] pub fn user_can_see_state_events(&self, user_id: &UserId, room_id: &RoomId) -> Result { - let currently_member = services().rooms.state_cache.is_joined(&user_id, &room_id)?; + let currently_member = services().rooms.state_cache.is_joined(user_id, room_id)?; let history_visibility = self - .room_state_get(&room_id, &StateEventType::RoomHistoryVisibility, "")? + .room_state_get(room_id, &StateEventType::RoomHistoryVisibility, "")? .map_or(Ok(HistoryVisibility::Shared), |s| { serde_json::from_str(s.content.get()) .map(|c: RoomHistoryVisibilityEventContent| c.history_visibility) @@ -276,7 +276,7 @@ impl Service { services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomName, "")? + .room_state_get(room_id, &StateEventType::RoomName, "")? .map_or(Ok(None), |s| { serde_json::from_str(s.content.get()) .map(|c: RoomNameEventContent| c.name) @@ -288,7 +288,7 @@ impl Service { services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomAvatar, "")? + .room_state_get(room_id, &StateEventType::RoomAvatar, "")? .map_or(Ok(None), |s| { serde_json::from_str(s.content.get()) .map_err(|_| Error::bad_database("Invalid room avatar event in database.")) @@ -303,7 +303,7 @@ impl Service { services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomMember, user_id.as_str())? + .room_state_get(room_id, &StateEventType::RoomMember, user_id.as_str())? .map_or(Ok(None), |s| { serde_json::from_str(s.content.get()) .map_err(|_| Error::bad_database("Invalid room member event in database.")) diff --git a/src/service/rooms/state_cache/data.rs b/src/service/rooms/state_cache/data.rs index d8bb4a44..8921909f 100644 --- a/src/service/rooms/state_cache/data.rs +++ b/src/service/rooms/state_cache/data.rs @@ -78,6 +78,7 @@ pub trait Data: Send + Sync { ) -> Box> + 'a>; /// Returns an iterator over all rooms a user was invited to. + #[allow(clippy::type_complexity)] fn rooms_invited<'a>( &'a self, user_id: &UserId, @@ -96,6 +97,7 @@ pub trait Data: Send + Sync { ) -> Result>>>; /// Returns an iterator over all rooms a user left. + #[allow(clippy::type_complexity)] fn rooms_left<'a>( &'a self, user_id: &UserId, diff --git a/src/service/rooms/state_compressor/mod.rs b/src/service/rooms/state_compressor/mod.rs index d29b020b..6118e06b 100644 --- a/src/service/rooms/state_compressor/mod.rs +++ b/src/service/rooms/state_compressor/mod.rs @@ -16,6 +16,7 @@ use self::data::StateDiff; pub struct Service { pub db: &'static dyn Data, + #[allow(clippy::type_complexity)] pub stateinfo_cache: Mutex< LruCache< u64, @@ -33,6 +34,7 @@ pub type CompressedStateEvent = [u8; 2 * size_of::()]; impl Service { /// Returns a stack with info on shortstatehash, full state, added diff and removed diff for the selected shortstatehash and each parent layer. + #[allow(clippy::type_complexity)] #[tracing::instrument(skip(self))] pub fn load_shortstatehash_info( &self, @@ -131,6 +133,7 @@ impl Service { /// * `statediffremoved` - Removed from base. Each vec is shortstatekey+shorteventid /// * `diff_to_sibling` - Approximately how much the diff grows each time for this layer /// * `parent_states` - A stack with info on shortstatehash, full state, added diff and removed diff for each parent layer + #[allow(clippy::type_complexity)] #[tracing::instrument(skip( self, statediffnew, @@ -164,7 +167,7 @@ impl Service { for removed in statediffremoved.iter() { if !parent_new.remove(removed) { // It was not added in the parent and we removed it - parent_removed.insert(removed.clone()); + parent_removed.insert(*removed); } // Else it was added in the parent and we removed it again. We can forget this change } @@ -172,7 +175,7 @@ impl Service { for new in statediffnew.iter() { if !parent_removed.remove(new) { // It was not touched in the parent and we added it - parent_new.insert(new.clone()); + parent_new.insert(*new); } // Else it was removed in the parent and we added it again. We can forget this change } @@ -217,7 +220,7 @@ impl Service { for removed in statediffremoved.iter() { if !parent_new.remove(removed) { // It was not added in the parent and we removed it - parent_removed.insert(removed.clone()); + parent_removed.insert(*removed); } // Else it was added in the parent and we removed it again. We can forget this change } @@ -225,7 +228,7 @@ impl Service { for new in statediffnew.iter() { if !parent_removed.remove(new) { // It was not touched in the parent and we added it - parent_new.insert(new.clone()); + parent_new.insert(*new); } // Else it was removed in the parent and we added it again. We can forget this change } @@ -253,6 +256,7 @@ impl Service { } /// Returns the new shortstatehash, and the state diff from the previous room state + #[allow(clippy::type_complexity)] pub fn save_state( &self, room_id: &RoomId, diff --git a/src/service/rooms/threads/data.rs b/src/service/rooms/threads/data.rs index 9221e8e8..e7159de0 100644 --- a/src/service/rooms/threads/data.rs +++ b/src/service/rooms/threads/data.rs @@ -2,6 +2,7 @@ use crate::{PduEvent, Result}; use ruma::{api::client::threads::get_threads::v1::IncludeThreads, OwnedUserId, RoomId, UserId}; pub trait Data: Send + Sync { + #[allow(clippy::type_complexity)] fn threads_until<'a>( &'a self, user_id: &'a UserId, diff --git a/src/service/rooms/threads/mod.rs b/src/service/rooms/threads/mod.rs index fb703839..c6193bc8 100644 --- a/src/service/rooms/threads/mod.rs +++ b/src/service/rooms/threads/mod.rs @@ -26,7 +26,7 @@ impl Service { self.db.threads_until(user_id, room_id, until, include) } - pub fn add_to_thread<'a>(&'a self, root_event_id: &EventId, pdu: &PduEvent) -> Result<()> { + pub fn add_to_thread(&self, root_event_id: &EventId, pdu: &PduEvent) -> Result<()> { let root_id = &services() .rooms .timeline @@ -103,7 +103,7 @@ impl Service { } let mut users = Vec::new(); - if let Some(userids) = self.db.get_participants(&root_id)? { + if let Some(userids) = self.db.get_participants(root_id)? { users.extend_from_slice(&userids); users.push(pdu.sender.clone()); } else { diff --git a/src/service/rooms/timeline/data.rs b/src/service/rooms/timeline/data.rs index afa2cfbf..6290b8cc 100644 --- a/src/service/rooms/timeline/data.rs +++ b/src/service/rooms/timeline/data.rs @@ -66,6 +66,7 @@ pub trait Data: Send + Sync { /// Returns an iterator over all events and their tokens in a room that happened before the /// event with id `until` in reverse-chronological order. + #[allow(clippy::type_complexity)] fn pdus_until<'a>( &'a self, user_id: &UserId, @@ -75,6 +76,7 @@ pub trait Data: Send + Sync { /// Returns an iterator over all events in a room that happened after the event with id `from` /// in chronological order. + #[allow(clippy::type_complexity)] fn pdus_after<'a>( &'a self, user_id: &UserId, diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 25e1c54d..61b73378 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -58,8 +58,8 @@ impl PduCount { } pub fn try_from_string(token: &str) -> Result { - if token.starts_with('-') { - token[1..].parse().map(PduCount::Backfilled) + if let Some(stripped) = token.strip_prefix('-') { + stripped.parse().map(PduCount::Backfilled) } else { token.parse().map(PduCount::Normal) } @@ -112,7 +112,7 @@ pub struct Service { impl Service { #[tracing::instrument(skip(self))] pub fn first_pdu_in_room(&self, room_id: &RoomId) -> Result>> { - self.all_pdus(&user_id!("@doesntmatter:conduit.rs"), &room_id)? + self.all_pdus(user_id!("@doesntmatter:conduit.rs"), room_id)? .next() .map(|o| o.map(|(_, p)| Arc::new(p))) .transpose() @@ -458,7 +458,7 @@ impl Service { let to_conduit = body.starts_with(&format!("{server_user}: ")) || body.starts_with(&format!("{server_user} ")) || body == format!("{server_user}:") - || body == format!("{server_user}"); + || body == server_user; // This will evaluate to false if the emergency password is set up so that // the administrator can execute commands as conduit @@ -842,7 +842,7 @@ impl Service { let target = pdu .state_key() - .filter(|v| v.starts_with("@")) + .filter(|v| v.starts_with('@')) .unwrap_or(sender.as_str()); let server_name = services().globals.server_name(); let server_user = format!("@conduit:{}", server_name); @@ -850,7 +850,7 @@ impl Service { .map_err(|_| Error::bad_database("Invalid content in pdu."))?; if content.membership == MembershipState::Leave { - if target == &server_user { + if target == server_user { warn!("Conduit user cannot leave from admins room"); return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -876,7 +876,7 @@ impl Service { } if content.membership == MembershipState::Ban && pdu.state_key().is_some() { - if target == &server_user { + if target == server_user { warn!("Conduit user cannot be banned in admins room"); return Err(Error::BadRequest( ErrorKind::Forbidden, @@ -1048,7 +1048,7 @@ impl Service { #[tracing::instrument(skip(self, room_id))] pub async fn backfill_if_required(&self, room_id: &RoomId, from: PduCount) -> Result<()> { let first_pdu = self - .all_pdus(&user_id!("@doesntmatter:conduit.rs"), &room_id)? + .all_pdus(user_id!("@doesntmatter:conduit.rs"), room_id)? .next() .expect("Room is not empty")?; @@ -1060,7 +1060,7 @@ impl Service { let power_levels: RoomPowerLevelsEventContent = services() .rooms .state_accessor - .room_state_get(&room_id, &StateEventType::RoomPowerLevels, "")? + .room_state_get(room_id, &StateEventType::RoomPowerLevels, "")? .map(|ev| { serde_json::from_str(ev.content.get()) .map_err(|_| Error::bad_database("invalid m.room.power_levels event")) @@ -1091,11 +1091,9 @@ impl Service { .await; match response { Ok(response) => { - let mut pub_key_map = RwLock::new(BTreeMap::new()); + let pub_key_map = RwLock::new(BTreeMap::new()); for pdu in response.pdus { - if let Err(e) = self - .backfill_pdu(backfill_server, pdu, &mut pub_key_map) - .await + if let Err(e) = self.backfill_pdu(backfill_server, pdu, &pub_key_map).await { warn!("Failed to add backfilled pdu: {e}"); } @@ -1142,7 +1140,7 @@ impl Service { services() .rooms .event_handler - .handle_incoming_pdu(origin, &event_id, &room_id, value, false, &pub_key_map) + .handle_incoming_pdu(origin, &event_id, &room_id, value, false, pub_key_map) .await?; let value = self.get_pdu_json(&event_id)?.expect("We just created it"); @@ -1175,24 +1173,21 @@ impl Service { drop(insert_lock); - match pdu.kind { - TimelineEventType::RoomMessage => { - #[derive(Deserialize)] - struct ExtractBody { - body: Option, - } + if pdu.kind == TimelineEventType::RoomMessage { + #[derive(Deserialize)] + struct ExtractBody { + body: Option, + } - let content = serde_json::from_str::(pdu.content.get()) - .map_err(|_| Error::bad_database("Invalid content in pdu."))?; + let content = serde_json::from_str::(pdu.content.get()) + .map_err(|_| Error::bad_database("Invalid content in pdu."))?; - if let Some(body) = content.body { - services() - .rooms - .search - .index_pdu(shortroomid, &pdu_id, &body)?; - } + if let Some(body) = content.body { + services() + .rooms + .search + .index_pdu(shortroomid, &pdu_id, &body)?; } - _ => {} } drop(mutex_lock); diff --git a/src/service/sending/data.rs b/src/service/sending/data.rs index 2e574e23..8b4d236f 100644 --- a/src/service/sending/data.rs +++ b/src/service/sending/data.rs @@ -5,6 +5,7 @@ use crate::Result; use super::{OutgoingKind, SendingEventType}; pub trait Data: Send + Sync { + #[allow(clippy::type_complexity)] fn active_requests<'a>( &'a self, ) -> Box, OutgoingKind, SendingEventType)>> + 'a>; diff --git a/src/service/users/mod.rs b/src/service/users/mod.rs index 6faa6d8e..dc34d533 100644 --- a/src/service/users/mod.rs +++ b/src/service/users/mod.rs @@ -34,6 +34,7 @@ pub struct SlidingSyncCache { pub struct Service { pub db: &'static dyn Data, + #[allow(clippy::type_complexity)] pub connections: Mutex>>>, } From 0d17aedae50e58226bc91f10253679cfc280b9ff Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sat, 23 Dec 2023 20:30:31 -0800 Subject: [PATCH 009/129] fix `cargo doc` lints Rustdoc (rightfully) thought the `[commandbody]` "tags" were broken links, so I've just made them links to nothing instead. --- src/api/server_server.rs | 2 +- src/service/admin/mod.rs | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 79f921e3..db17d586 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -341,7 +341,7 @@ fn add_port_to_hostname(destination_str: &str) -> FedDest { } /// Returns: actual_destination, host header -/// Implemented according to the specification at https://matrix.org/docs/spec/server_server/r0.1.4#resolving-server-names +/// Implemented according to the specification at /// Numbers in comments below refer to bullet points in linked section of specification async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDest) { debug!("Finding actual destination for {destination}"); diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index b22f8ed4..64958fc7 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -50,7 +50,7 @@ enum AdminCommand { /// Registering a new bridge using the ID of an existing bridge will replace /// the old one. /// - /// [commandbody] + /// [commandbody]() /// # ``` /// # yaml content here /// # ``` @@ -96,7 +96,7 @@ enum AdminCommand { /// Removing a mass amount of users from a room may cause a significant amount of leave events. /// The time to leave rooms may depend significantly on joined rooms and servers. /// - /// [commandbody] + /// [commandbody]() /// # ``` /// # User list here /// # ``` @@ -121,7 +121,7 @@ enum AdminCommand { /// The PDU event is only checked for validity and is not added to the /// database. /// - /// [commandbody] + /// [commandbody]() /// # ``` /// # PDU json content here /// # ``` @@ -165,14 +165,14 @@ enum AdminCommand { EnableRoom { room_id: Box }, /// Verify json signatures - /// [commandbody] + /// [commandbody]() /// # ``` /// # json here /// # ``` SignJson, /// Verify json signatures - /// [commandbody] + /// [commandbody]() /// # ``` /// # json here /// # ``` @@ -858,12 +858,15 @@ impl Service { .expect("Regex compilation should not fail"); let text = re.replace_all(&text, "$1: $4"); - // Look for a `[commandbody]` tag. If it exists, use all lines below it that + // Look for a `[commandbody]()` tag. If it exists, use all lines below it that // start with a `#` in the USAGE section. let mut text_lines: Vec<&str> = text.lines().collect(); let mut command_body = String::new(); - if let Some(line_index) = text_lines.iter().position(|line| *line == "[commandbody]") { + if let Some(line_index) = text_lines + .iter() + .position(|line| *line == "[commandbody]()") + { text_lines.remove(line_index); while text_lines From e8ac881b2f38a8de776f1638704ed91b05cdf18c Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Wed, 20 Dec 2023 15:29:09 -0800 Subject: [PATCH 010/129] add an engage file See for info. --- engage.toml | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 2 ++ 2 files changed, 66 insertions(+) create mode 100644 engage.toml diff --git a/engage.toml b/engage.toml new file mode 100644 index 00000000..3e8884eb --- /dev/null +++ b/engage.toml @@ -0,0 +1,64 @@ +interpreter = ["bash", "-euo", "pipefail", "-c"] + +[[task]] +name = "engage" +group = "versions" +script = "engage --version" + +[[task]] +name = "rustc" +group = "versions" +script = "rustc --version" + +[[task]] +name = "cargo" +group = "versions" +script = "cargo --version" + +[[task]] +name = "cargo-fmt" +group = "versions" +script = "cargo fmt --version" + +[[task]] +name = "rustdoc" +group = "versions" +script = "rustdoc --version" + +[[task]] +name = "cargo-clippy" +group = "versions" +script = "cargo clippy -- --version" + +[[task]] +name = "cargo-fmt" +group = "lints" +script = "cargo fmt --check -- --color=always" + +[[task]] +name = "cargo-doc" +group = "lints" +script = """ +RUSTDOCFLAGS="-D warnings" cargo doc \ + --workspace \ + --no-deps \ + --document-private-items \ + --color always +""" + +[[task]] +name = "cargo-clippy" +group = "lints" +script = "cargo clippy --workspace --all-targets --color=always -- -D warnings" + +[[task]] +name = "cargo" +group = "tests" +script = """ +cargo test \ + --workspace \ + --all-targets \ + --color=always \ + -- \ + --color=always +""" diff --git a/flake.nix b/flake.nix index eb3a31cb..c1eee4a6 100644 --- a/flake.nix +++ b/flake.nix @@ -82,6 +82,8 @@ rust-src rustc rustfmt + ]) ++ (with pkgs; [ + engage ]); }; From 6f052fff985c0cd559fff32c11fd32445b8110ed Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sat, 23 Dec 2023 21:12:42 -0800 Subject: [PATCH 011/129] improve nix flake Also fix the comment in `Cargo.toml` about the rust-version stuff. --- Cargo.toml | 8 +++---- flake.nix | 67 +++++++++++++++++++++++++++++++----------------------- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6cc66508..81661f0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,10 +9,10 @@ readme = "README.md" version = "0.7.0-alpha" edition = "2021" -# When changing this, make sure to update the `flake.lock` file by running -# `nix flake update`. If you don't have Nix installed or otherwise don't know -# how to do this, ping `@charles:computer.surgery` or `@dusk:gaze.systems` in -# the matrix room. +# When changing this, make sure to update the hash near the text "THE +# rust-version HASH" in `flake.nix`. If you don't have Nix installed or +# otherwise don't know how to do this, ping `@charles:computer.surgery` or +# `@dusk:gaze.systems` in the matrix room. rust-version = "1.70.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/flake.nix b/flake.nix index c1eee4a6..ed545d7c 100644 --- a/flake.nix +++ b/flake.nix @@ -43,53 +43,64 @@ sha256 = "sha256-gdYqng0y9iHYzYPAdkC/ka3DRny3La/S5G8ASj0Ayyc="; }; - # The system's RocksDB - ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb}/include"; - ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; + mkToolchain = fenix.packages.${system}.combine; + + buildToolchain = mkToolchain (with toolchain; [ + cargo + rustc + ]); + + devToolchain = mkToolchain (with toolchain; [ + cargo + clippy + rust-src + rustc + + # Always use nightly rustfmt because most of its options are unstable + fenix.packages.${system}.latest.rustfmt + ]); + + builder = + ((crane.mkLib pkgs).overrideToolchain buildToolchain).buildPackage; - # Shared between the package and the devShell nativeBuildInputs = (with pkgs.rustPlatform; [ bindgenHook ]); - builder = - ((crane.mkLib pkgs).overrideToolchain toolchain.toolchain).buildPackage; + env = { + ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb}/include"; + ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; + }; in { packages.default = builder { src = ./.; + # This is redundant with CI + doCheck = false; + inherit - stdenv + env nativeBuildInputs - ROCKSDB_INCLUDE_DIR - ROCKSDB_LIB_DIR; + stdenv; + + meta.mainProgram = cargoToml.package.name; }; devShells.default = (pkgs.mkShell.override { inherit stdenv; }) { - # Rust Analyzer needs to be able to find the path to default crate - # sources, and it can read this environment variable to do so - RUST_SRC_PATH = "${toolchain.rust-src}/lib/rustlib/src/rust/library"; - - inherit - ROCKSDB_INCLUDE_DIR - ROCKSDB_LIB_DIR; + env = env // { + # Rust Analyzer needs to be able to find the path to default crate + # sources, and it can read this environment variable to do so. The + # `rust-src` component is required in order for this to work. + RUST_SRC_PATH = "${devToolchain}/lib/rustlib/src/rust/library"; + }; # Development tools - nativeBuildInputs = nativeBuildInputs ++ (with toolchain; [ - cargo - clippy - rust-src - rustc - rustfmt - ]) ++ (with pkgs; [ + nativeBuildInputs = nativeBuildInputs ++ [ + devToolchain + ] ++ (with pkgs; [ engage ]); }; - - checks = { - packagesDefault = self.packages.${system}.default; - devShellsDefault = self.devShells.${system}.default; - }; }); } From 25ceb5ebd8e42f24020cac01ca5c29a1b1cb2b7a Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 18 Jan 2024 11:22:51 -0800 Subject: [PATCH 012/129] remove commented out ci step If you want it back, just look at the git history. --- .gitlab-ci.yml | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f5ab4246..bacc7fd8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,6 @@ stages: - build - build docker image - test - - upload artifacts variables: # Make GitLab CI go fast: @@ -208,31 +207,6 @@ test:dockerlint: - if: '$CI_COMMIT_REF_NAME == "master"' - if: '$CI_COMMIT_REF_NAME == "next"' -# --------------------------------------------------------------------- # -# Store binaries as package so they have download urls # -# --------------------------------------------------------------------- # - -# 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 workflow: From 9d592d60d2d0f62fea7eec9db0cfb044e6354c24 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 18 Jan 2024 11:23:41 -0800 Subject: [PATCH 013/129] remove dockerlint step because it does nothing It's configured to let the pipeline pass even if there are warnings or errors, i.e. it's pointless. --- .gitlab-ci.yml | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bacc7fd8..5393367a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -174,39 +174,6 @@ test:audit: reports: sast: gl-sast-report.json -test:dockerlint: - stage: "test" - needs: [] - image: "ghcr.io/hadolint/hadolint@sha256:6c4b7c23f96339489dd35f21a711996d7ce63047467a9a562287748a03ad5242" # 2.8.0-alpine - interruptible: true - script: - - hadolint --version - # First pass: Print for CI log: - - > - hadolint - --no-fail --verbose - ./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 > dockerlint.json - artifacts: - when: always - reports: - codequality: dockerlint.json - paths: - - dockerlint.json - rules: - - if: '$CI_COMMIT_REF_NAME != "master"' - changes: - - docker/*Dockerfile - - Dockerfile - - .gitlab-ci.yml - - if: '$CI_COMMIT_REF_NAME == "master"' - - if: '$CI_COMMIT_REF_NAME == "next"' - # Avoid duplicate pipelines # See: https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines workflow: From ffd03a256b3ff497957dd15729fe02ac4b79f0c8 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 18 Jan 2024 11:35:28 -0800 Subject: [PATCH 014/129] remove workflow rules I don't think these are actually necessary? At least in my own testing, I haven't seen duplicate pipelines for a single commit when converting from just a branch to a merge request. --- .gitlab-ci.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5393367a..0722c141 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -173,13 +173,3 @@ test:audit: when: always reports: sast: gl-sast-report.json - -# Avoid duplicate pipelines -# See: https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines -workflow: - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - - if: "$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS" - when: never - - if: "$CI_COMMIT_BRANCH" - - if: "$CI_COMMIT_TAG" From 7e66d2e2c062e28f2bf16668fb41e53699dee56c Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 18 Jan 2024 11:36:51 -0800 Subject: [PATCH 015/129] use nix and engage to manage ci --- .gitignore | 3 + .gitlab-ci.yml | 188 ++++++------------------------------------------- 2 files changed, 26 insertions(+), 165 deletions(-) diff --git a/.gitignore b/.gitignore index 1b5d37b8..a34d70ad 100644 --- a/.gitignore +++ b/.gitignore @@ -68,3 +68,6 @@ cached_target # Direnv cache /.direnv + +# Gitlab CI cache +/.gitlab-ci.d diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0722c141..889cf26a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,175 +1,33 @@ stages: - - build - - build docker image - - test + - ci variables: - # Make GitLab CI go fast: - GIT_SUBMODULE_STRATEGY: recursive - FF_USE_FASTZIP: 1 - CACHE_COMPRESSION_LEVEL: fastest + # Makes some things print in color + TERM: ansi -# --------------------------------------------------------------------- # -# Create and publish docker image # -# --------------------------------------------------------------------- # +before_script: + # Enable nix-command and flakes + - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf -.docker-shared-settings: - stage: "build docker image" - needs: [] - tags: [ "docker" ] - variables: - # Docker in Docker: - DOCKER_BUILDKIT: 1 - image: - name: docker.io/docker - services: - - name: docker.io/docker:dind - alias: docker - script: - - 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 - --platform "linux/arm/v7,linux/arm64,linux/amd64" - --pull - --tag "$CI_REGISTRY_IMAGE/temporary-ci-images:$CI_JOB_ID" - --push - --provenance=false - --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" - --provenance=false - --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" - --provenance=false - --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: - extends: .docker-shared-settings - rules: - - if: '$BUILD_SERVER_SSH_PRIVATE_KEY && $CI_COMMIT_BRANCH == "next"' - variables: - TAG: "matrix-conduit:next" - -docker:master: - extends: .docker-shared-settings - rules: - - if: '$BUILD_SERVER_SSH_PRIVATE_KEY && $CI_COMMIT_BRANCH == "master"' - variables: - TAG: "matrix-conduit:latest" - -docker:tags: - extends: .docker-shared-settings - rules: - - if: "$BUILD_SERVER_SSH_PRIVATE_KEY && $CI_COMMIT_TAG" - variables: - TAG: "matrix-conduit:$CI_COMMIT_TAG" - - -docker build debugging: - extends: .docker-shared-settings - rules: - - if: "$CI_MERGE_REQUEST_TITLE =~ /.*[Dd]ocker.*/" - variables: - TAG: "matrix-conduit-docker-tests:latest" - -# --------------------------------------------------------------------- # -# Run tests # -# --------------------------------------------------------------------- # + # Add nix-community binary cache + - echo "extra-substituters = https://nix-community.cachix.org" >> /etc/nix/nix.conf + - echo "extra-trusted-public-keys = nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" >> /etc/nix/nix.conf -cargo check: - stage: test - image: docker.io/rust:1.70.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: [] - image: "registry.gitlab.com/jfowl/conduit-containers/rust-with-tools:latest" - tags: ["docker"] - variables: - CARGO_INCREMENTAL: "false" # https://matklad.github.io/2021/09/04/fast-rust-builds.html#ci-workflow - interruptible: true - -test:cargo: - extends: .test-shared-settings - before_script: - - 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" + # Install direnv and nix-direnv + - nix-env -iA nixpkgs.direnv nixpkgs.nix-direnv -test:clippy: - extends: .test-shared-settings - allow_failure: true - before_script: - - rustup component add clippy - - 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" - artifacts: - when: always - reports: - codequality: gl-code-quality-report.json + # Allow .envrc + - direnv allow -test:format: - extends: .test-shared-settings - before_script: - - rustup component add rustfmt - script: - - cargo fmt --all -- --check + # Set CARGO_HOME to a cacheable path + - export CARGO_HOME="$(git rev-parse --show-toplevel)/.gitlab-ci.d/cargo" -test:audit: - extends: .test-shared-settings - allow_failure: true +ci: + stage: ci + image: nixos/nix:2.19.2 script: - - cargo audit --color always || true - - cargo audit --stale --json | gitlab-report -p audit > gl-sast-report.json - artifacts: - when: always - reports: - sast: gl-sast-report.json + - direnv exec . engage + cache: + paths: + - target + - .gitlab-ci.d From f8bdfd82b02dbbd46cdc19f2c862378b127b2b0d Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 18 Jan 2024 12:14:03 -0800 Subject: [PATCH 016/129] update flake.lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flake lock file updates: • Updated input 'crane': 'github:ipetkov/crane/8b08e96c9af8c6e3a2b69af5a7fa168750fcf88e' (2023-07-07) → 'github:ipetkov/crane/742170d82cd65c925dcddc5c3d6185699fbbad08' (2024-01-18) • Removed input 'crane/flake-compat' • Removed input 'crane/flake-utils' • Removed input 'crane/rust-overlay' • Removed input 'crane/rust-overlay/flake-utils' • Removed input 'crane/rust-overlay/nixpkgs' • Updated input 'fenix': 'github:nix-community/fenix/39096fe3f379036ff4a5fa198950b8e79defe939' (2023-07-16) → 'github:nix-community/fenix/e132ea0eb0c799a2109a91688e499d7bf4962801' (2024-01-18) • Updated input 'fenix/rust-analyzer-src': 'github:rust-lang/rust-analyzer/996e054f1eb1dbfc8455ecabff0f6ff22ba7f7c8' (2023-07-15) → 'github:rust-lang/rust-analyzer/9d9b34354d2f13e33568c9c55b226dd014a146a0' (2024-01-17) • Updated input 'flake-utils': 'github:numtide/flake-utils/919d646de7be200f3bf08cb76ae1f09402b6f9b4' (2023-07-11) → 'github:numtide/flake-utils/1ef2e671c3b0c19053962c07dbda38332dcebf26' (2024-01-15) • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/8acef304efe70152463a6399f73e636bcc363813' (2023-07-15) → 'github:NixOS/nixpkgs/842d9d80cfd4560648c785f8a4e6f3b096790e19' (2024-01-17) --- flake.lock | 78 +++++++++++------------------------------------------- flake.nix | 1 - 2 files changed, 16 insertions(+), 63 deletions(-) diff --git a/flake.lock b/flake.lock index 00655252..7f361dd5 100644 --- a/flake.lock +++ b/flake.lock @@ -2,21 +2,16 @@ "nodes": { "crane": { "inputs": { - "flake-compat": "flake-compat", - "flake-utils": [ - "flake-utils" - ], "nixpkgs": [ "nixpkgs" - ], - "rust-overlay": "rust-overlay" + ] }, "locked": { - "lastModified": 1688772518, - "narHash": "sha256-ol7gZxwvgLnxNSZwFTDJJ49xVY5teaSvF7lzlo3YQfM=", + "lastModified": 1705597458, + "narHash": "sha256-vJ8Ib9ruxbaBxGEcA0d7dHqxpc6Z+SGR2XIxVeSMuLM=", "owner": "ipetkov", "repo": "crane", - "rev": "8b08e96c9af8c6e3a2b69af5a7fa168750fcf88e", + "rev": "742170d82cd65c925dcddc5c3d6185699fbbad08", "type": "github" }, "original": { @@ -33,11 +28,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1689488573, - "narHash": "sha256-diVASflKCCryTYv0djvMnP2444mFsIG0ge5pa7ahauQ=", + "lastModified": 1705559032, + "narHash": "sha256-Cb+Jd1+Gz4Wi+8elPnUIHnqQmE1qjDRZ+PsJaPaAffY=", "owner": "nix-community", "repo": "fenix", - "rev": "39096fe3f379036ff4a5fa198950b8e79defe939", + "rev": "e132ea0eb0c799a2109a91688e499d7bf4962801", "type": "github" }, "original": { @@ -46,32 +41,16 @@ "type": "github" } }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1673956053, - "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", - "owner": "edolstra", - "repo": "flake-compat", - "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", - "type": "github" - }, - "original": { - "owner": "edolstra", - "repo": "flake-compat", - "type": "github" - } - }, "flake-utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1689068808, - "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", "owner": "numtide", "repo": "flake-utils", - "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", "type": "github" }, "original": { @@ -82,11 +61,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1689444953, - "narHash": "sha256-0o56bfb2LC38wrinPdCGLDScd77LVcr7CrH1zK7qvDg=", + "lastModified": 1705496572, + "narHash": "sha256-rPIe9G5EBLXdBdn9ilGc0nq082lzQd0xGGe092R/5QE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "8acef304efe70152463a6399f73e636bcc363813", + "rev": "842d9d80cfd4560648c785f8a4e6f3b096790e19", "type": "github" }, "original": { @@ -107,11 +86,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1689441253, - "narHash": "sha256-4MSDZaFI4DOfsLIZYPMBl0snzWhX1/OqR/QHir382CY=", + "lastModified": 1705523001, + "narHash": "sha256-TWq5vJ6m+9HGSDMsQAmz1TMegMi79R3TTyKjnPWsQp8=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "996e054f1eb1dbfc8455ecabff0f6ff22ba7f7c8", + "rev": "9d9b34354d2f13e33568c9c55b226dd014a146a0", "type": "github" }, "original": { @@ -121,31 +100,6 @@ "type": "github" } }, - "rust-overlay": { - "inputs": { - "flake-utils": [ - "crane", - "flake-utils" - ], - "nixpkgs": [ - "crane", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1688351637, - "narHash": "sha256-CLTufJ29VxNOIZ8UTg0lepsn3X03AmopmaLTTeHDCL4=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "f9b92316727af9e6c7fee4a761242f7f46880329", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, "systems": { "locked": { "lastModified": 1681028828, diff --git a/flake.nix b/flake.nix index ed545d7c..65cfc301 100644 --- a/flake.nix +++ b/flake.nix @@ -10,7 +10,6 @@ crane = { url = "github:ipetkov/crane"; inputs.nixpkgs.follows = "nixpkgs"; - inputs.flake-utils.follows = "flake-utils"; }; }; From 02781e4f9b494baf9cd238b6614f217c9474c3e2 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 18 Jan 2024 13:05:55 -0800 Subject: [PATCH 017/129] use nix-filter to filter sources This prevents nix from rebuilding conduit when files that don't actually effect the build are changed. --- flake.lock | 16 ++++++++++++++++ flake.nix | 11 ++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/flake.lock b/flake.lock index 7f361dd5..128539bb 100644 --- a/flake.lock +++ b/flake.lock @@ -59,6 +59,21 @@ "type": "github" } }, + "nix-filter": { + "locked": { + "lastModified": 1705332318, + "narHash": "sha256-kcw1yFeJe9N4PjQji9ZeX47jg0p9A0DuU4djKvg1a7I=", + "owner": "numtide", + "repo": "nix-filter", + "rev": "3449dc925982ad46246cfc36469baf66e1b64f17", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "nix-filter", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1705496572, @@ -80,6 +95,7 @@ "crane": "crane", "fenix": "fenix", "flake-utils": "flake-utils", + "nix-filter": "nix-filter", "nixpkgs": "nixpkgs" } }, diff --git a/flake.nix b/flake.nix index 65cfc301..62ba8289 100644 --- a/flake.nix +++ b/flake.nix @@ -2,6 +2,7 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; + nix-filter.url = "github:numtide/nix-filter"; fenix = { url = "github:nix-community/fenix"; @@ -17,6 +18,7 @@ { self , nixpkgs , flake-utils + , nix-filter , fenix , crane @@ -73,7 +75,14 @@ in { packages.default = builder { - src = ./.; + src = nix-filter { + root = ./.; + include = [ + "src" + "Cargo.toml" + "Cargo.lock" + ]; + }; # This is redundant with CI doCheck = false; From 4de54db3054c95a7931bb7be7f9f04578d06024f Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 18 Jan 2024 13:31:46 -0800 Subject: [PATCH 018/129] redo docker image and build it in ci --- .gitlab-ci.yml | 13 +++++ Dockerfile | 132 ------------------------------------------------- flake.nix | 20 ++++++++ 3 files changed, 33 insertions(+), 132 deletions(-) delete mode 100644 Dockerfile diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 889cf26a..ac1495fc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,6 @@ stages: - ci + - artifacts variables: # Makes some things print in color @@ -31,3 +32,15 @@ ci: paths: - target - .gitlab-ci.d + +docker: + stage: artifacts + image: nixos/nix:2.19.2 + script: + - nix build .#oci-image + + # Make the output less difficult to find + - cp result docker-image.tar.gz + artifacts: + paths: + - docker-image.tar.gz diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 943f6864..00000000 --- a/Dockerfile +++ /dev/null @@ -1,132 +0,0 @@ -# syntax=docker/dockerfile:1 -FROM docker.io/rust:1.70-bullseye AS base - -FROM base AS builder -WORKDIR /usr/src/conduit - -# Install required packages to build Conduit and it's dependencies -RUN apt-get update && \ - apt-get -y --no-install-recommends install libclang-dev=1:11.0-51+nmu5 - -# == Build dependencies without our own code separately for caching == -# -# Need a fake main.rs since Cargo refuses to build anything otherwise. -# -# See https://github.com/rust-lang/cargo/issues/2644 for a Cargo feature -# request that would allow just dependencies to be compiled, presumably -# regardless of whether source files are available. -RUN mkdir src && touch src/lib.rs && echo 'fn main() {}' > src/main.rs -COPY Cargo.toml Cargo.lock ./ -RUN cargo build --release && rm -r src - -# Copy over actual Conduit sources -COPY src src - -# main.rs and lib.rs need their timestamp updated for this to work correctly since -# otherwise the build with the fake main.rs from above is newer than the -# source files (COPY preserves timestamps). -# -# 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 base 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 ./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 -# --------------------------------------------------------------------------------------------------------------- -FROM docker.io/debian:bullseye-slim AS runner - -# Standard port on which Conduit launches. -# You still need to map the port when using the docker command or docker-compose. -EXPOSE 6167 - -ARG DEFAULT_DB_PATH=/var/lib/matrix-conduit - -ENV CONDUIT_PORT=6167 \ - CONDUIT_ADDRESS="0.0.0.0" \ - CONDUIT_DATABASE_PATH=${DEFAULT_DB_PATH} \ - CONDUIT_CONFIG='' -# └─> 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 \ - && rm -rf /var/lib/apt/lists/* - -# Test if Conduit is still alive, uses the same endpoint as Element -COPY ./docker/healthcheck.sh /srv/conduit/healthcheck.sh -HEALTHCHECK --start-period=5s --interval=5s CMD ./healthcheck.sh - -# 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. -ARG USER_ID=1000 -ARG GROUP_ID=1000 -RUN set -x ; \ - groupadd -r -g ${GROUP_ID} conduit ; \ - useradd -l -r -M -d /srv/conduit -o -u ${USER_ID} -g conduit conduit && exit 0 ; exit 1 - -# Create database directory, change ownership of Conduit files to conduit user and group and make the healthcheck executable: -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 -WORKDIR /srv/conduit - -# Run Conduit and print backtraces on panics -ENV RUST_BACKTRACE=1 -ENTRYPOINT [ "/usr/sbin/matrix-conduit" ] diff --git a/flake.nix b/flake.nix index 62ba8289..b4a32d0a 100644 --- a/flake.nix +++ b/flake.nix @@ -95,6 +95,26 @@ meta.mainProgram = cargoToml.package.name; }; + packages.oci-image = + let + package = self.packages.${system}.default; + in + pkgs.dockerTools.buildImage { + name = package.pname; + tag = "latest"; + config = { + # Use the `tini` init system so that signals (e.g. ctrl+c/SIGINT) are + # handled as expected + Entrypoint = [ + "${pkgs.lib.getExe' pkgs.tini "tini"}" + "--" + ]; + Cmd = [ + "${pkgs.lib.getExe package}" + ]; + }; + }; + devShells.default = (pkgs.mkShell.override { inherit stdenv; }) { env = env // { # Rust Analyzer needs to be able to find the path to default crate From 0b7ed5adc9ad17811eb8ef43b6b1e94c5a17d6b1 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Fri, 19 Jan 2024 12:10:23 -0800 Subject: [PATCH 019/129] add debian package building in ci This uses a separate step and docker image, which I'm not a huge fan of. At least I could get this to work for now, but I won't be shocked when it breaks later. I know, I know, fixing this kind of problem is the exact reason I bothered to do this, but I was really struggling to do better here. Maybe I can take a second pass at this later. Also, this explicitly names the caches, because without this, various things related to linking will break. --- .gitlab-ci.yml | 30 +++++++++++++++++++++++++----- Cargo.toml | 2 ++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ac1495fc..48fe6244 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,17 +8,17 @@ variables: before_script: # Enable nix-command and flakes - - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf + - if command -v nix > /dev/null; then echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf; fi # Add nix-community binary cache - - echo "extra-substituters = https://nix-community.cachix.org" >> /etc/nix/nix.conf - - echo "extra-trusted-public-keys = nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" >> /etc/nix/nix.conf + - if command -v nix > /dev/null; then echo "extra-substituters = https://nix-community.cachix.org" >> /etc/nix/nix.conf; fi + - if command -v nix > /dev/null; then echo "extra-trusted-public-keys = nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" >> /etc/nix/nix.conf; fi # Install direnv and nix-direnv - - nix-env -iA nixpkgs.direnv nixpkgs.nix-direnv + - if command -v nix > /dev/null; then nix-env -iA nixpkgs.direnv nixpkgs.nix-direnv; fi # Allow .envrc - - direnv allow + - if command -v nix > /dev/null; then direnv allow; fi # Set CARGO_HOME to a cacheable path - export CARGO_HOME="$(git rev-parse --show-toplevel)/.gitlab-ci.d/cargo" @@ -29,6 +29,7 @@ ci: script: - direnv exec . engage cache: + key: nix paths: - target - .gitlab-ci.d @@ -44,3 +45,22 @@ docker: artifacts: paths: - docker-image.tar.gz + +debian: + stage: artifacts + image: rust:1.70.0 + script: + - apt-get update && apt-get install -y --no-install-recommends libclang-dev + - cargo install cargo-deb + - cargo deb + + # Make the output less difficult to find + - mv target/debian/*.deb . + artifacts: + paths: + - "*.deb" + cache: + key: debian + paths: + - target + - .gitlab-ci.d diff --git a/Cargo.toml b/Cargo.toml index 81661f0b..8c139156 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,8 @@ edition = "2021" # rust-version HASH" in `flake.nix`. If you don't have Nix installed or # otherwise don't know how to do this, ping `@charles:computer.surgery` or # `@dusk:gaze.systems` in the matrix room. +# +# Also make sure to update the docker image tags in `.gitlab-ci.yml`. rust-version = "1.70.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 69d0003222e6fcf7abe6305a08aff6a8eba74659 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Wed, 2 Aug 2023 01:00:06 +0200 Subject: [PATCH 020/129] Use upstream `reqwest` instead of vendored one This uses the `ClientBuilder::dns_resolver` function that was added in reqwest 0.11.13, instead of the homebrew `ClientBuilder::resolve_fn`. --- Cargo.lock | 84 +++++++++++--------------------------- Cargo.toml | 3 +- src/service/globals/mod.rs | 45 ++++++++++++++++++-- 3 files changed, 66 insertions(+), 66 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b4bcdc0a..d5e1d161 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,10 +155,10 @@ dependencies = [ "http-body", "hyper", "pin-project-lite", - "rustls 0.21.2", - "rustls-pemfile 1.0.2", + "rustls", + "rustls-pemfile", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls", "tower-service", ] @@ -364,6 +364,7 @@ dependencies = [ "futures-util", "hmac", "http", + "hyper", "image", "jsonwebtoken", "lazy_static", @@ -1022,15 +1023,16 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ + "futures-util", "http", "hyper", - "rustls 0.20.8", + "rustls", "tokio", - "tokio-rustls 0.23.4", + "tokio-rustls", ] [[package]] @@ -1898,10 +1900,11 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "reqwest" -version = "0.11.9" -source = "git+https://github.com/timokoesters/reqwest?rev=57b7cf4feb921573dfafad7d34b9ac6e44ead0bd#57b7cf4feb921573dfafad7d34b9ac6e44ead0bd" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "base64 0.13.1", + "base64 0.21.2", "bytes", "encoding_rs", "futures-core", @@ -1913,25 +1916,26 @@ dependencies = [ "hyper-rustls", "ipnet", "js-sys", - "lazy_static", "log", "mime", + "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.20.8", + "rustls", "rustls-native-certs", - "rustls-pemfile 0.2.1", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", "tokio", - "tokio-rustls 0.23.4", + "tokio-rustls", "tokio-socks", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.7.0", + "winreg 0.10.1", ] [[package]] @@ -2198,18 +2202,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustls" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" -dependencies = [ - "log", - "ring", - "sct", - "webpki", -] - [[package]] name = "rustls" version = "0.21.2" @@ -2229,20 +2221,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.2", + "rustls-pemfile", "schannel", "security-framework", ] -[[package]] -name = "rustls-pemfile" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" -dependencies = [ - "base64 0.13.1", -] - [[package]] name = "rustls-pemfile" version = "1.0.2" @@ -2756,24 +2739,13 @@ dependencies = [ "syn 2.0.21", ] -[[package]] -name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" -dependencies = [ - "rustls 0.20.8", - "tokio", - "webpki", -] - [[package]] name = "tokio-rustls" version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.2", + "rustls", "tokio", ] @@ -3223,16 +3195,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "weezl" version = "0.1.7" @@ -3407,9 +3369,9 @@ dependencies = [ [[package]] name = "winreg" -version = "0.7.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ "winapi", ] diff --git a/Cargo.toml b/Cargo.toml index 8c139156..a35cf233 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,8 @@ rand = "0.8.5" # Used to hash passwords rust-argon2 = "1.0.0" # Used to send requests -reqwest = { default-features = false, features = ["rustls-tls-native-roots", "socks"], git = "https://github.com/timokoesters/reqwest", rev = "57b7cf4feb921573dfafad7d34b9ac6e44ead0bd" } +hyper = "0.14.26" +reqwest = { version = "0.11.18", default-features = false, features = ["rustls-tls-native-roots", "socks"] } # Used for conduit::Error type thiserror = "1.0.40" # Used to generate thumbnails for images diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index 9bce8a2c..96b2954f 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -8,6 +8,12 @@ use ruma::{ use crate::api::server_server::FedDest; use crate::{services, Config, Error, Result}; +use futures_util::FutureExt; +use hyper::{ + client::connect::dns::{GaiResolver, Name}, + service::Service as HyperService, +}; +use reqwest::dns::{Addrs, Resolve, Resolving}; use ruma::{ api::{ client::sync::sync_events, @@ -17,8 +23,10 @@ use ruma::{ }; use std::{ collections::{BTreeMap, HashMap}, + error::Error as StdError, fs, - future::Future, + future::{self, Future}, + iter, net::{IpAddr, SocketAddr}, path::PathBuf, sync::{ @@ -99,6 +107,35 @@ impl Default for RotationHandler { } } +pub struct Resolver { + inner: GaiResolver, + overrides: Box Option + Send + Sync>, +} + +impl Resolver { + pub fn new(overrides: Box Option + Send + Sync>) -> Resolver { + Resolver { + inner: GaiResolver::new(), + overrides, + } + } +} + +impl Resolve for Resolver { + fn resolve(&self, name: Name) -> Resolving { + if let Some(addr) = (self.overrides)(name.as_str()) { + let once: Box + Send> = Box::new(iter::once(addr)); + return Box::pin(future::ready(Ok(once))); + } + let this = &mut self.inner.clone(); + Box::pin(HyperService::::call(this, name).map(|result| { + result + .map(|addrs| -> Addrs { Box::new(addrs) }) + .map_err(|err| -> Box { Box::new(err) }) + })) + } +} + impl Service { pub fn load(db: &'static dyn Data, config: Config) -> Result { let keypair = db.load_keypair(); @@ -122,12 +159,12 @@ impl Service { let default_client = reqwest_client_builder(&config)?.build()?; let name_override = Arc::clone(&tls_name_override); let federation_client = reqwest_client_builder(&config)? - .resolve_fn(move |domain| { + .dns_resolver(Arc::new(Resolver::new(Box::new(move |domain| { let read_guard = name_override.read().unwrap(); - let (override_name, port) = read_guard.get(&domain)?; + let (override_name, port) = read_guard.get(domain)?; let first_name = override_name.get(0)?; Some(SocketAddr::new(*first_name, *port)) - }) + })))) .build()?; // Supported and stable room versions From fe86d28428a0cae53ac9ca5f5efe7783cb00022c Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Wed, 24 Jan 2024 15:11:17 -0800 Subject: [PATCH 021/129] move resolver logic into the resolver Honestly not sure why it wasn't done like this before. This code is much less awkward to follow and more compartmentalized. These changes were mainly motivated by a clippy lint triggering on the original code, which then made me wonder if I could get rid of some of the `Box`ing. Turns out I could, and this is the result of that. --- src/service/globals/mod.rs | 42 +++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index 96b2954f..f034415e 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -109,11 +109,11 @@ impl Default for RotationHandler { pub struct Resolver { inner: GaiResolver, - overrides: Box Option + Send + Sync>, + overrides: Arc>, } impl Resolver { - pub fn new(overrides: Box Option + Send + Sync>) -> Resolver { + pub fn new(overrides: Arc>) -> Self { Resolver { inner: GaiResolver::new(), overrides, @@ -123,16 +123,26 @@ impl Resolver { impl Resolve for Resolver { fn resolve(&self, name: Name) -> Resolving { - if let Some(addr) = (self.overrides)(name.as_str()) { - let once: Box + Send> = Box::new(iter::once(addr)); - return Box::pin(future::ready(Ok(once))); - } - let this = &mut self.inner.clone(); - Box::pin(HyperService::::call(this, name).map(|result| { - result - .map(|addrs| -> Addrs { Box::new(addrs) }) - .map_err(|err| -> Box { Box::new(err) }) - })) + self.overrides + .read() + .expect("lock should not be poisoned") + .get(name.as_str()) + .and_then(|(override_name, port)| { + override_name.get(0).map(|first_name| { + let x: Box + Send> = + Box::new(iter::once(SocketAddr::new(*first_name, *port))); + let x: Resolving = Box::pin(future::ready(Ok(x))); + x + }) + }) + .unwrap_or_else(|| { + let this = &mut self.inner.clone(); + Box::pin(HyperService::::call(this, name).map(|result| { + result + .map(|addrs| -> Addrs { Box::new(addrs) }) + .map_err(|err| -> Box { Box::new(err) }) + })) + }) } } @@ -157,14 +167,8 @@ impl Service { .map(|secret| jsonwebtoken::DecodingKey::from_secret(secret.as_bytes())); let default_client = reqwest_client_builder(&config)?.build()?; - let name_override = Arc::clone(&tls_name_override); let federation_client = reqwest_client_builder(&config)? - .dns_resolver(Arc::new(Resolver::new(Box::new(move |domain| { - let read_guard = name_override.read().unwrap(); - let (override_name, port) = read_guard.get(domain)?; - let first_name = override_name.get(0)?; - Some(SocketAddr::new(*first_name, *port)) - })))) + .dns_resolver(Arc::new(Resolver::new(tls_name_override.clone()))) .build()?; // Supported and stable room versions From f7cc4fb3bb8ec1bfc39ccb89e770c809d5708343 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Wed, 24 Jan 2024 22:24:34 -0800 Subject: [PATCH 022/129] state artifacts' targets and rename artifacts This will make it more obvious what's what and be more internally consistent. --- .gitlab-ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 48fe6244..53fd73f9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,19 +34,19 @@ ci: - target - .gitlab-ci.d -docker: +oci-image:x86_64-unknown-linux-gnu: stage: artifacts image: nixos/nix:2.19.2 script: - nix build .#oci-image # Make the output less difficult to find - - cp result docker-image.tar.gz + - cp result oci-image.tar.gz artifacts: paths: - - docker-image.tar.gz + - oci-image.tar.gz -debian: +debian:x86_64-unknown-linux-gnu: stage: artifacts image: rust:1.70.0 script: @@ -55,10 +55,10 @@ debian: - cargo deb # Make the output less difficult to find - - mv target/debian/*.deb . + - mv target/debian/*.deb conduit.deb artifacts: paths: - - "*.deb" + - conduit.deb cache: key: debian paths: From bd2b146d5da633eb3ec80033a317feea87d23c64 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Wed, 24 Jan 2024 22:16:29 -0800 Subject: [PATCH 023/129] add crane binary cache This way we don't need to build e.g. crane-utils every time. --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 53fd73f9..deacb811 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,10 @@ before_script: # Enable nix-command and flakes - if command -v nix > /dev/null; then echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf; fi + # Add crane binary cache + - if command -v nix > /dev/null; then echo "extra-substituters = https://crane.cachix.org" >> /etc/nix/nix.conf; fi + - if command -v nix > /dev/null; then echo "extra-trusted-public-keys = crane.cachix.org-1:8Scfpmn9w+hGdXH/Q9tTLiYAE/2dnJYRJP7kl80GuRk=" >> /etc/nix/nix.conf; fi + # Add nix-community binary cache - if command -v nix > /dev/null; then echo "extra-substituters = https://nix-community.cachix.org" >> /etc/nix/nix.conf; fi - if command -v nix > /dev/null; then echo "extra-trusted-public-keys = nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" >> /etc/nix/nix.conf; fi From 6ae776218cc2da4e46fb587bd08b5164b24c41ce Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Wed, 24 Jan 2024 22:20:48 -0800 Subject: [PATCH 024/129] add our own binary cache The machine I'm hosting this on doesn't have incredible upload speeds but it should be good enough? --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index deacb811..746641c8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,10 @@ before_script: # Enable nix-command and flakes - if command -v nix > /dev/null; then echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf; fi + # Add our own binary cache + - if command -v nix > /dev/null; then echo "extra-substituters = https://nix.computer.surgery/conduit" >> /etc/nix/nix.conf; fi + - if command -v nix > /dev/null; then echo "extra-trusted-public-keys = conduit:ZGAf6P6LhNvnoJJ3Me3PRg7tlLSrPxcQ2RiE5LIppjo=" >> /etc/nix/nix.conf; fi + # Add crane binary cache - if command -v nix > /dev/null; then echo "extra-substituters = https://crane.cachix.org" >> /etc/nix/nix.conf; fi - if command -v nix > /dev/null; then echo "extra-trusted-public-keys = crane.cachix.org-1:8Scfpmn9w+hGdXH/Q9tTLiYAE/2dnJYRJP7kl80GuRk=" >> /etc/nix/nix.conf; fi From bdc46f63929f19ddc124f0ed4a78885b1514343c Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 25 Jan 2024 11:34:46 -0800 Subject: [PATCH 025/129] add script to build and push to binary cache This is even useful for local development, as you can pre-populate the binary cache before running CI (assuming you have the token). Also, it being in a script makes it easier to test. We've added attic as a flake input even though the flake itself doesn't use it so that we can use `--inputs-from .` in Nix commands to reference a locked version of attic. This helps with reproducibility and caching, and to makes it easy to update attic because it's part of the normal flake lifecycle. --- .envrc | 2 + flake.lock | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++-- flake.nix | 2 + 3 files changed, 115 insertions(+), 3 deletions(-) diff --git a/.envrc b/.envrc index b9238c3b..403a9bdf 100644 --- a/.envrc +++ b/.envrc @@ -1,3 +1,5 @@ #!/usr/bin/env bash use flake + +PATH_add bin diff --git a/flake.lock b/flake.lock index 128539bb..acad901c 100644 --- a/flake.lock +++ b/flake.lock @@ -1,6 +1,50 @@ { "nodes": { + "attic": { + "inputs": { + "crane": "crane", + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "nixpkgs-stable": "nixpkgs-stable" + }, + "locked": { + "lastModified": 1705617092, + "narHash": "sha256-n9PK4O4X4S1JkwpkMuYm1wHZYJzRqif8g3RuVIPD+rY=", + "owner": "zhaofengli", + "repo": "attic", + "rev": "fbe252a5c21febbe920c025560cbd63b20e24f3b", + "type": "github" + }, + "original": { + "owner": "zhaofengli", + "ref": "main", + "repo": "attic", + "type": "github" + } + }, "crane": { + "inputs": { + "nixpkgs": [ + "attic", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1702918879, + "narHash": "sha256-tWJqzajIvYcaRWxn+cLUB9L9Pv4dQ3Bfit/YjU5ze3g=", + "owner": "ipetkov", + "repo": "crane", + "rev": "7195c00c272fdd92fc74e7d5a0a2844b9fadb2fb", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "crane_2": { "inputs": { "nixpkgs": [ "nixpkgs" @@ -41,7 +85,38 @@ "type": "github" } }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { "inputs": { "systems": "systems" }, @@ -75,6 +150,38 @@ } }, "nixpkgs": { + "locked": { + "lastModified": 1702539185, + "narHash": "sha256-KnIRG5NMdLIpEkZTnN5zovNYc0hhXjAgv6pfd5Z4c7U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "aa9d4729cbc99dabacb50e3994dcefb3ea0f7447", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1702780907, + "narHash": "sha256-blbrBBXjjZt6OKTcYX1jpe9SRof2P9ZYWPzq22tzXAA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1e2e384c5b7c50dbf8e9c441a9e58d85f408b01f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1705496572, "narHash": "sha256-rPIe9G5EBLXdBdn9ilGc0nq082lzQd0xGGe092R/5QE=", @@ -92,11 +199,12 @@ }, "root": { "inputs": { - "crane": "crane", + "attic": "attic", + "crane": "crane_2", "fenix": "fenix", - "flake-utils": "flake-utils", + "flake-utils": "flake-utils_2", "nix-filter": "nix-filter", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs_2" } }, "rust-analyzer-src": { diff --git a/flake.nix b/flake.nix index b4a32d0a..51148bad 100644 --- a/flake.nix +++ b/flake.nix @@ -12,6 +12,7 @@ url = "github:ipetkov/crane"; inputs.nixpkgs.follows = "nixpkgs"; }; + attic.url = "github:zhaofengli/attic?ref=main"; }; outputs = @@ -22,6 +23,7 @@ , fenix , crane + , ... }: flake-utils.lib.eachDefaultSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; From 5cc53c9e14ef5319f2dd8f88aa58d6e966cfdb20 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 25 Jan 2024 11:37:35 -0800 Subject: [PATCH 026/129] push oci image and x86_64-*-gnu build to bin cache This will allow most Nix users to use the `default` package and without having to build from source. And also allows any weirdos to get the OCI image from the Nix binary cache if they want. No idea why that would be desireable though lol --- .gitlab-ci.yml | 8 +++++++- bin/nix-build-and-cache | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100755 bin/nix-build-and-cache diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 746641c8..199429a5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -46,7 +46,13 @@ oci-image:x86_64-unknown-linux-gnu: stage: artifacts image: nixos/nix:2.19.2 script: - - nix build .#oci-image + # Push artifacts and build requirements to binary cache + # + # Since the OCI image package is based on the binary package, this has the + # fun side effect of uploading the normal binary too. Conduit users who are + # deploying with Nix can leverage this fact by adding our binary cache to + # their systems. + - ./bin/nix-build-and-cache .#oci-image # Make the output less difficult to find - cp result oci-image.tar.gz diff --git a/bin/nix-build-and-cache b/bin/nix-build-and-cache new file mode 100755 index 00000000..b37ebd85 --- /dev/null +++ b/bin/nix-build-and-cache @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# The first argument must be the desired installable +INSTALLABLE="$1" + +# Build the installable and forward any other arguments too +nix build "$@" + +if [ ! -z ${ATTIC_TOKEN+x} ]; then + +nix run --inputs-from . attic -- login \ + conduit \ + https://nix.computer.surgery/conduit \ + "$ATTIC_TOKEN" + + push_args=( + # Attic and its build dependencies + "$(nix path-info --inputs-from . attic)" + "$(nix path-info --inputs-from . attic --derivation)" + + # The target installable and its build dependencies + "$(nix path-info "$INSTALLABLE" --derivation)" + "$(nix path-info "$INSTALLABLE")" + ) + + nix run --inputs-from . attic -- push conduit "${push_args[@]}" +else + echo "\$ATTIC_TOKEN is unset, skipping uploading to the binary cache" +fi From 249fc7769d14e4b4eb9d7f6abc645972c4fc27b8 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 22 Jan 2024 22:24:04 -0800 Subject: [PATCH 027/129] don't bother with mold For now, at least. I suspect it will make cross compilation more difficult. --- flake.nix | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/flake.nix b/flake.nix index 51148bad..d4be7d9e 100644 --- a/flake.nix +++ b/flake.nix @@ -28,12 +28,6 @@ let pkgs = nixpkgs.legacyPackages.${system}; - # Use mold on Linux - stdenv = if pkgs.stdenv.isLinux then - pkgs.stdenvAdapters.useMoldLinker pkgs.stdenv - else - pkgs.stdenv; - # Nix-accessible `Cargo.toml` cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); @@ -91,8 +85,7 @@ inherit env - nativeBuildInputs - stdenv; + nativeBuildInputs; meta.mainProgram = cargoToml.package.name; }; @@ -117,7 +110,7 @@ }; }; - devShells.default = (pkgs.mkShell.override { inherit stdenv; }) { + devShells.default = pkgs.mkShell { env = env // { # Rust Analyzer needs to be able to find the path to default crate # sources, and it can read this environment variable to do so. The From 9cef03127bcc0e076286721f6f7d5564e0af36c8 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Tue, 23 Jan 2024 10:45:02 -0800 Subject: [PATCH 028/129] remove `with` for `nativeBuildInputs` It's going to get more involved and that `with` was too specific. --- flake.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index d4be7d9e..15538efd 100644 --- a/flake.nix +++ b/flake.nix @@ -60,9 +60,9 @@ builder = ((crane.mkLib pkgs).overrideToolchain buildToolchain).buildPackage; - nativeBuildInputs = (with pkgs.rustPlatform; [ - bindgenHook - ]); + nativeBuildInputs = [ + pkgs.rustPlatform.bindgenHook + ]; env = { ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb}/include"; From cf4015b8307249ccf3f7c036306a1dc69f0af795 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 22 Jan 2024 22:25:08 -0800 Subject: [PATCH 029/129] rename pkgs to pkgsHost This will make organizing cross compilation easier. --- flake.nix | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/flake.nix b/flake.nix index 15538efd..039bf0b5 100644 --- a/flake.nix +++ b/flake.nix @@ -26,7 +26,7 @@ , ... }: flake-utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages.${system}; + pkgsHost = nixpkgs.legacyPackages.${system}; # Nix-accessible `Cargo.toml` cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); @@ -58,15 +58,15 @@ ]); builder = - ((crane.mkLib pkgs).overrideToolchain buildToolchain).buildPackage; + ((crane.mkLib pkgsHost).overrideToolchain buildToolchain).buildPackage; nativeBuildInputs = [ - pkgs.rustPlatform.bindgenHook + pkgsHost.rustPlatform.bindgenHook ]; env = { - ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb}/include"; - ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; + ROCKSDB_INCLUDE_DIR = "${pkgsHost.rocksdb}/include"; + ROCKSDB_LIB_DIR = "${pkgsHost.rocksdb}/lib"; }; in { @@ -94,23 +94,23 @@ let package = self.packages.${system}.default; in - pkgs.dockerTools.buildImage { + pkgsHost.dockerTools.buildImage { name = package.pname; tag = "latest"; config = { # Use the `tini` init system so that signals (e.g. ctrl+c/SIGINT) are # handled as expected Entrypoint = [ - "${pkgs.lib.getExe' pkgs.tini "tini"}" + "${pkgsHost.lib.getExe' pkgsHost.tini "tini"}" "--" ]; Cmd = [ - "${pkgs.lib.getExe package}" + "${pkgsHost.lib.getExe package}" ]; }; }; - devShells.default = pkgs.mkShell { + devShells.default = pkgsHost.mkShell { env = env // { # Rust Analyzer needs to be able to find the path to default crate # sources, and it can read this environment variable to do so. The @@ -121,7 +121,7 @@ # Development tools nativeBuildInputs = nativeBuildInputs ++ [ devToolchain - ] ++ (with pkgs; [ + ] ++ (with pkgsHost; [ engage ]); }; From 692a31620d747a9a640cb3464221c3024c546e09 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 22 Jan 2024 22:26:16 -0800 Subject: [PATCH 030/129] make let bindings take pkgs as an argument Again, will make cross compilation easier to set up. --- flake.nix | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/flake.nix b/flake.nix index 039bf0b5..76f8bb25 100644 --- a/flake.nix +++ b/flake.nix @@ -57,20 +57,20 @@ fenix.packages.${system}.latest.rustfmt ]); - builder = - ((crane.mkLib pkgsHost).overrideToolchain buildToolchain).buildPackage; + builder = pkgs: + ((crane.mkLib pkgs).overrideToolchain buildToolchain).buildPackage; - nativeBuildInputs = [ - pkgsHost.rustPlatform.bindgenHook + nativeBuildInputs = pkgs: [ + pkgs.rustPlatform.bindgenHook ]; - env = { - ROCKSDB_INCLUDE_DIR = "${pkgsHost.rocksdb}/include"; - ROCKSDB_LIB_DIR = "${pkgsHost.rocksdb}/lib"; + env = pkgs: { + ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb}/include"; + ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; }; in { - packages.default = builder { + packages.default = builder pkgsHost { src = nix-filter { root = ./.; include = [ @@ -83,9 +83,8 @@ # This is redundant with CI doCheck = false; - inherit - env - nativeBuildInputs; + env = env pkgsHost; + nativeBuildInputs = nativeBuildInputs pkgsHost; meta.mainProgram = cargoToml.package.name; }; @@ -111,7 +110,7 @@ }; devShells.default = pkgsHost.mkShell { - env = env // { + env = env pkgsHost // { # Rust Analyzer needs to be able to find the path to default crate # sources, and it can read this environment variable to do so. The # `rust-src` component is required in order for this to work. @@ -119,7 +118,7 @@ }; # Development tools - nativeBuildInputs = nativeBuildInputs ++ [ + nativeBuildInputs = nativeBuildInputs pkgsHost ++ [ devToolchain ] ++ (with pkgsHost; [ engage From 52954f7a11e795211bbecc54df456724773251b6 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 22 Jan 2024 22:48:58 -0800 Subject: [PATCH 031/129] use fromToolchainFile I *think* this will make it easier to pull in extra rustc targets. --- .gitlab-ci.yml | 1 + Cargo.toml | 7 +------ flake.nix | 36 ++++++++++++------------------------ rust-toolchain.toml | 17 +++++++++++++++++ 4 files changed, 31 insertions(+), 30 deletions(-) create mode 100644 rust-toolchain.toml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 199429a5..1f6dab3a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -62,6 +62,7 @@ oci-image:x86_64-unknown-linux-gnu: debian:x86_64-unknown-linux-gnu: stage: artifacts + # See also `rust-toolchain.toml` image: rust:1.70.0 script: - apt-get update && apt-get install -y --no-install-recommends libclang-dev diff --git a/Cargo.toml b/Cargo.toml index a35cf233..40919599 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,12 +9,7 @@ readme = "README.md" version = "0.7.0-alpha" edition = "2021" -# When changing this, make sure to update the hash near the text "THE -# rust-version HASH" in `flake.nix`. If you don't have Nix installed or -# otherwise don't know how to do this, ping `@charles:computer.surgery` or -# `@dusk:gaze.systems` in the matrix room. -# -# Also make sure to update the docker image tags in `.gitlab-ci.yml`. +# See also `rust-toolchain.toml` rust-version = "1.70.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/flake.nix b/flake.nix index 76f8bb25..89a4eb43 100644 --- a/flake.nix +++ b/flake.nix @@ -32,33 +32,15 @@ cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); # The Rust toolchain to use - toolchain = fenix.packages.${system}.toolchainOf { - # Use the Rust version defined in `Cargo.toml` - channel = cargoToml.package.rust-version; + toolchain = fenix.packages.${system}.fromToolchainFile { + file = ./rust-toolchain.toml; - # THE rust-version HASH + # See also `rust-toolchain.toml` sha256 = "sha256-gdYqng0y9iHYzYPAdkC/ka3DRny3La/S5G8ASj0Ayyc="; }; - mkToolchain = fenix.packages.${system}.combine; - - buildToolchain = mkToolchain (with toolchain; [ - cargo - rustc - ]); - - devToolchain = mkToolchain (with toolchain; [ - cargo - clippy - rust-src - rustc - - # Always use nightly rustfmt because most of its options are unstable - fenix.packages.${system}.latest.rustfmt - ]); - builder = pkgs: - ((crane.mkLib pkgs).overrideToolchain buildToolchain).buildPackage; + ((crane.mkLib pkgs).overrideToolchain toolchain).buildPackage; nativeBuildInputs = pkgs: [ pkgs.rustPlatform.bindgenHook @@ -114,12 +96,18 @@ # Rust Analyzer needs to be able to find the path to default crate # sources, and it can read this environment variable to do so. The # `rust-src` component is required in order for this to work. - RUST_SRC_PATH = "${devToolchain}/lib/rustlib/src/rust/library"; + RUST_SRC_PATH = "${toolchain}/lib/rustlib/src/rust/library"; }; # Development tools nativeBuildInputs = nativeBuildInputs pkgsHost ++ [ - devToolchain + # Always use nightly rustfmt because most of its options are unstable + # + # This needs to come before `toolchain` in this list, otherwise + # `$PATH` will have stable rustfmt instead. + fenix.packages.${system}.latest.rustfmt + + toolchain ] ++ (with pkgsHost; [ engage ]); diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..cc3e2545 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,17 @@ +# This is the authoritiative configuration of this project's Rust toolchain. +# +# Other files that need upkeep when this changes: +# +# * `.gitlab-ci.yml` +# * `Cargo.toml` +# * `flake.nix` +# +# Search in those files for `rust-toolchain.toml` to find the relevant places. +# If you're having trouble making the relevant changes, bug a maintainer. + +[toolchain] +channel = "1.70.0" +components = [ + # For rust-analyzer + "rust-src", +] From 3ac9be5a789f34cd980ad68b6a3824fc3ba3c7a0 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Tue, 23 Jan 2024 11:10:23 -0800 Subject: [PATCH 032/129] add x86_64-unknown-linux-gnu This is probably the most common target and usually doesn't involve cross compilation. --- rust-toolchain.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index cc3e2545..8d153e8b 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -15,3 +15,6 @@ components = [ # For rust-analyzer "rust-src", ] +targets = [ + "x86_64-unknown-linux-gnu", +] From 67d280dd2e71dca6e412b94ce63d328f408f3490 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 22 Jan 2024 22:56:00 -0800 Subject: [PATCH 033/129] factor package expression into a function We'll need to call it repeatedly to make packages for cross. --- flake.nix | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/flake.nix b/flake.nix index 89a4eb43..a86422c3 100644 --- a/flake.nix +++ b/flake.nix @@ -50,9 +50,8 @@ ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb}/include"; ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; }; - in - { - packages.default = builder pkgsHost { + + package = pkgs: builder pkgs { src = nix-filter { root = ./.; include = [ @@ -65,11 +64,14 @@ # This is redundant with CI doCheck = false; - env = env pkgsHost; - nativeBuildInputs = nativeBuildInputs pkgsHost; + env = env pkgs; + nativeBuildInputs = nativeBuildInputs pkgs; meta.mainProgram = cargoToml.package.name; }; + in + { + packages.default = package pkgsHost; packages.oci-image = let From d29591d47d6de9c82539f18994a268f5215a4ee6 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 22 Jan 2024 23:07:30 -0800 Subject: [PATCH 034/129] group packages in attrset literal This will make generating packages for cross possible. --- flake.nix | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/flake.nix b/flake.nix index a86422c3..9d73ba9b 100644 --- a/flake.nix +++ b/flake.nix @@ -71,25 +71,27 @@ }; in { - packages.default = package pkgsHost; - - packages.oci-image = - let - package = self.packages.${system}.default; - in - pkgsHost.dockerTools.buildImage { - name = package.pname; - tag = "latest"; - config = { - # Use the `tini` init system so that signals (e.g. ctrl+c/SIGINT) are - # handled as expected - Entrypoint = [ - "${pkgsHost.lib.getExe' pkgsHost.tini "tini"}" - "--" - ]; - Cmd = [ - "${pkgsHost.lib.getExe package}" - ]; + packages = { + default = package pkgsHost; + + oci-image = + let + package = self.packages.${system}.default; + in + pkgsHost.dockerTools.buildImage { + name = package.pname; + tag = "latest"; + config = { + # Use the `tini` init system so that signals (e.g. ctrl+c/SIGINT) + # are handled as expected + Entrypoint = [ + "${pkgsHost.lib.getExe' pkgsHost.tini "tini"}" + "--" + ]; + Cmd = [ + "${pkgsHost.lib.getExe package}" + ]; + }; }; }; From 3a3cafe912b16d4ce786bedd37247ea200f125b9 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Tue, 23 Jan 2024 21:29:03 -0800 Subject: [PATCH 035/129] preempt cross problems by using my crane fork I imagine this will get fixed/merged upstream in the near future. --- flake.lock | 11 ++++++----- flake.nix | 5 ++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/flake.lock b/flake.lock index acad901c..4508f7ce 100644 --- a/flake.lock +++ b/flake.lock @@ -51,15 +51,16 @@ ] }, "locked": { - "lastModified": 1705597458, - "narHash": "sha256-vJ8Ib9ruxbaBxGEcA0d7dHqxpc6Z+SGR2XIxVeSMuLM=", - "owner": "ipetkov", + "lastModified": 1706070683, + "narHash": "sha256-iQoXIFviH5QbSKDkWyFJKKUtTcSiCvl1tW18ax+pKfI=", + "owner": "CobaltCause", "repo": "crane", - "rev": "742170d82cd65c925dcddc5c3d6185699fbbad08", + "rev": "8060686afabc5b042e8982200cb2cc3fd22cf416", "type": "github" }, "original": { - "owner": "ipetkov", + "owner": "CobaltCause", + "ref": "crimes-for-cross", "repo": "crane", "type": "github" } diff --git a/flake.nix b/flake.nix index 9d73ba9b..ba577123 100644 --- a/flake.nix +++ b/flake.nix @@ -9,7 +9,10 @@ inputs.nixpkgs.follows = "nixpkgs"; }; crane = { - url = "github:ipetkov/crane"; + # TODO: Switch back to upstream after [this issue][0] is fixed + # + # [0]: https://github.com/ipetkov/crane/issues/497 + url = "github:CobaltCause/crane?ref=crimes-for-cross"; inputs.nixpkgs.follows = "nixpkgs"; }; attic.url = "github:zhaofengli/attic?ref=main"; From 81ae579b2546e9fe6d9eda4ed33507f4f159c67c Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Tue, 23 Jan 2024 11:22:18 -0800 Subject: [PATCH 036/129] add static cross to x86_64-unknown-linux-musl --- .gitlab-ci.yml | 13 +++++++ flake.nix | 89 +++++++++++++++++++++++++++++++++++++++++++-- rust-toolchain.toml | 1 + 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1f6dab3a..95953e20 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,6 +42,19 @@ ci: - target - .gitlab-ci.d +static:x86_64-unknown-linux-musl: + stage: artifacts + image: nixos/nix:2.19.2 + script: + # Push artifacts and build requirements to binary cache + - ./bin/nix-build-and-cache .#static-x86_64-unknown-linux-musl + + # Make the output less difficult to find + - cp result/bin/conduit conduit + artifacts: + paths: + - conduit + oci-image:x86_64-unknown-linux-gnu: stage: artifacts image: nixos/nix:2.19.2 diff --git a/flake.nix b/flake.nix index ba577123..c30c9483 100644 --- a/flake.nix +++ b/flake.nix @@ -46,13 +46,82 @@ ((crane.mkLib pkgs).overrideToolchain toolchain).buildPackage; nativeBuildInputs = pkgs: [ - pkgs.rustPlatform.bindgenHook + # bindgen needs the build platform's libclang. Apparently due to + # "splicing weirdness", pkgs.rustPlatform.bindgenHook on its own doesn't + # quite do the right thing here. + pkgs.buildPackages.rustPlatform.bindgenHook ]; env = pkgs: { ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb}/include"; ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; - }; + } + // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isStatic { + ROCKSDB_STATIC = ""; + } + // { + CARGO_BUILD_RUSTFLAGS = let inherit (pkgs) lib stdenv; in + lib.concatStringsSep " " ([] + ++ lib.optionals + # This disables PIE for static builds, which isn't great in terms + # of security. Unfortunately, my hand is forced because nixpkgs' + # `libstdc++.a` is built without `-fPIE`, which precludes us from + # leaving PIE enabled. + stdenv.hostPlatform.isStatic + ["-C" "relocation-model=static"] + ++ lib.optionals + (stdenv.buildPlatform.config != pkgs.stdenv.hostPlatform.config) + ["-l" "c"] + ); + } + + # What follows is stolen from [here][0]. Its purpose is to properly + # configure compilers and linkers for various stages of the build, and + # even covers the case of build scripts that need native code compiled and + # run on the build platform (I think). + # + # [0]: https://github.com/NixOS/nixpkgs/blob/612f97239e2cc474c13c9dafa0df378058c5ad8d/pkgs/build-support/rust/lib/default.nix#L64-L78 + // ( + let + inherit (pkgs.rust.lib) envVars; + in + pkgs.lib.optionalAttrs + (pkgs.stdenv.targetPlatform.rust.rustcTarget + != pkgs.stdenv.hostPlatform.rust.rustcTarget) + ( + let + inherit (pkgs.stdenv.targetPlatform.rust) cargoEnvVarTarget; + in + { + "CC_${cargoEnvVarTarget}" = envVars.ccForTarget; + "CXX_${cargoEnvVarTarget}" = envVars.cxxForTarget; + "CARGO_TARGET_${cargoEnvVarTarget}_LINKER" = + envVars.linkerForTarget; + } + ) + // ( + let + inherit (pkgs.stdenv.hostPlatform.rust) cargoEnvVarTarget rustcTarget; + in + { + "CC_${cargoEnvVarTarget}" = envVars.ccForHost; + "CXX_${cargoEnvVarTarget}" = envVars.cxxForHost; + "CARGO_TARGET_${cargoEnvVarTarget}_LINKER" = envVars.linkerForHost; + CARGO_BUILD_TARGET = rustcTarget; + } + ) + // ( + let + inherit (pkgs.stdenv.buildPlatform.rust) cargoEnvVarTarget; + in + { + "CC_${cargoEnvVarTarget}" = envVars.ccForBuild; + "CXX_${cargoEnvVarTarget}" = envVars.cxxForBuild; + "CARGO_TARGET_${cargoEnvVarTarget}_LINKER" = envVars.linkerForBuild; + HOST_CC = "${pkgs.buildPackages.stdenv.cc}/bin/cc"; + HOST_CXX = "${pkgs.buildPackages.stdenv.cc}/bin/c++"; + } + )); package = pkgs: builder pkgs { src = nix-filter { @@ -96,7 +165,21 @@ ]; }; }; - }; + } // builtins.listToAttrs ( + builtins.map + (crossSystem: { + name = "static-${crossSystem}"; + value = package (import nixpkgs { + inherit system; + crossSystem = { + config = crossSystem; + }; + }).pkgsStatic; + }) + [ + "x86_64-unknown-linux-musl" + ] + ); devShells.default = pkgsHost.mkShell { env = env pkgsHost // { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 8d153e8b..9a21cdb4 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -17,4 +17,5 @@ components = [ ] targets = [ "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", ] From 0e8e4f10833aa4ee7104a599e5fe56f2fa027a9b Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Tue, 23 Jan 2024 11:49:52 -0800 Subject: [PATCH 037/129] add static cross to aarch64-unknown-linux-musl --- .gitlab-ci.yml | 13 +++++++++++++ flake.nix | 19 +++++++++++++++++++ rust-toolchain.toml | 1 + 3 files changed, 33 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 95953e20..6695e431 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -55,6 +55,19 @@ static:x86_64-unknown-linux-musl: paths: - conduit +static:aarch64-unknown-linux-musl: + stage: artifacts + image: nixos/nix:2.19.2 + script: + # Push artifacts and build requirements to binary cache + - ./bin/nix-build-and-cache .#static-aarch64-unknown-linux-musl + + # Make the output less difficult to find + - cp result/bin/conduit conduit + artifacts: + paths: + - conduit + oci-image:x86_64-unknown-linux-gnu: stage: artifacts image: nixos/nix:2.19.2 diff --git a/flake.nix b/flake.nix index c30c9483..e7b8cdbf 100644 --- a/flake.nix +++ b/flake.nix @@ -72,6 +72,24 @@ ++ lib.optionals (stdenv.buildPlatform.config != pkgs.stdenv.hostPlatform.config) ["-l" "c"] + ++ lib.optionals + # This check has to match the one [here][0]. We only need to set + # these flags when using a different linker. Don't ask me why, + # though, because I don't know. All I know is it breaks otherwise. + # + # [0]: https://github.com/NixOS/nixpkgs/blob/612f97239e2cc474c13c9dafa0df378058c5ad8d/pkgs/build-support/rust/lib/default.nix#L36-L39 + ( + pkgs.stdenv.hostPlatform.isAarch64 + && pkgs.stdenv.hostPlatform.isStatic + && !pkgs.stdenv.isDarwin + && !pkgs.stdenv.cc.bintools.isLLVM + ) + [ + "-l" + "stdc++" + "-L" + "${stdenv.cc.cc.lib}/${stdenv.hostPlatform.config}/lib" + ] ); } @@ -178,6 +196,7 @@ }) [ "x86_64-unknown-linux-musl" + "aarch64-unknown-linux-musl" ] ); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 9a21cdb4..8ef64c92 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -18,4 +18,5 @@ components = [ targets = [ "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", + "aarch64-unknown-linux-musl", ] From 2a04a361e090bcd44939b5c7680ee4c445516790 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 25 Jan 2024 19:36:17 -0800 Subject: [PATCH 038/129] break oci image builder into a function Now it can be reused for different `pkgs` and `package`s. --- flake.nix | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/flake.nix b/flake.nix index e7b8cdbf..5f4df1e1 100644 --- a/flake.nix +++ b/flake.nix @@ -159,30 +159,29 @@ meta.mainProgram = cargoToml.package.name; }; - in - { - packages = { - default = package pkgsHost; - oci-image = - let - package = self.packages.${system}.default; - in - pkgsHost.dockerTools.buildImage { + mkOciImage = pkgs: package: + pkgs.dockerTools.buildImage { name = package.pname; tag = "latest"; config = { # Use the `tini` init system so that signals (e.g. ctrl+c/SIGINT) # are handled as expected Entrypoint = [ - "${pkgsHost.lib.getExe' pkgsHost.tini "tini"}" + "${pkgs.lib.getExe' pkgs.tini "tini"}" "--" ]; Cmd = [ - "${pkgsHost.lib.getExe package}" + "${pkgs.lib.getExe package}" ]; }; }; + in + { + packages = { + default = package pkgsHost; + + oci-image = mkOciImage pkgsHost self.packages.${system}.default; } // builtins.listToAttrs ( builtins.map (crossSystem: { From 7c1a3e41d94dbc4d5b395dae300bd3d42b937c50 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 25 Jan 2024 19:38:25 -0800 Subject: [PATCH 039/129] add package to build an aarch64 oci image And build it as an artifact in CI. --- .gitlab-ci.yml | 17 +++++++++++++++++ flake.nix | 10 ++++++++++ 2 files changed, 27 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6695e431..a28db4d5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -86,6 +86,23 @@ oci-image:x86_64-unknown-linux-gnu: paths: - oci-image.tar.gz +oci-image:aarch64-unknown-linux-musl: + stage: artifacts + needs: + # Wait for the static binary job to finish before starting so we don't have + # to build that twice for no reason + - static:aarch64-unknown-linux-musl + image: nixos/nix:2.19.2 + script: + # Push artifacts and build requirements to binary cache + - ./bin/nix-build-and-cache .#oci-image-aarch64-unknown-linux-musl + + # Make the output less difficult to find + - cp result oci-image.tar.gz + artifacts: + paths: + - oci-image.tar.gz + debian:x86_64-unknown-linux-gnu: stage: artifacts # See also `rust-toolchain.toml` diff --git a/flake.nix b/flake.nix index 5f4df1e1..1bc5c148 100644 --- a/flake.nix +++ b/flake.nix @@ -182,6 +182,16 @@ default = package pkgsHost; oci-image = mkOciImage pkgsHost self.packages.${system}.default; + + # Build an OCI image from the musl aarch64 build so we don't have to + # build for aarch64 twice (to make a gnu version specifically for the + # OCI image) + oci-image-aarch64-unknown-linux-musl = mkOciImage + pkgsHost + self.packages.${system}.static-aarch64-unknown-linux-musl; + + # Don't build a musl x86_64 OCI image because that would be pointless. + # Just use the gnu one (i.e. `self.packages."x86_64-linux".oci-image`). } // builtins.listToAttrs ( builtins.map (crossSystem: { From 9453dbc7408c2ad043c5801bd0f25edd2f1769b7 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 25 Jan 2024 20:33:15 -0800 Subject: [PATCH 040/129] update rust toolchain It comes with a bunch of new lints (yay!) so I fixed them all so CI will keep working. Also apparently something about linking changed because I had to change the checks for deciding the linker flags for static x86_64 builds to keep working. --- .gitlab-ci.yml | 2 +- Cargo.toml | 2 +- flake.nix | 8 ++++++-- rust-toolchain.toml | 2 +- src/api/client_server/media.rs | 2 +- src/database/abstraction/persy.rs | 6 +++--- src/database/abstraction/sqlite.rs | 2 +- src/database/key_value/account_data.rs | 5 ++--- src/database/key_value/globals.rs | 4 ++-- src/database/key_value/rooms/short.rs | 5 ++--- src/database/key_value/users.rs | 5 ++--- src/service/globals/mod.rs | 2 +- src/service/pdu.rs | 2 +- src/service/rooms/timeline/mod.rs | 25 +++++++++++++------------ src/service/sending/mod.rs | 2 +- src/service/users/mod.rs | 18 ++++++++++++------ 16 files changed, 50 insertions(+), 42 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a28db4d5..f2438c8e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -106,7 +106,7 @@ oci-image:aarch64-unknown-linux-musl: debian:x86_64-unknown-linux-gnu: stage: artifacts # See also `rust-toolchain.toml` - image: rust:1.70.0 + image: rust:1.75.0 script: - apt-get update && apt-get install -y --no-install-recommends libclang-dev - cargo install cargo-deb diff --git a/Cargo.toml b/Cargo.toml index 40919599..156de3c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ version = "0.7.0-alpha" edition = "2021" # See also `rust-toolchain.toml` -rust-version = "1.70.0" +rust-version = "1.75.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/flake.nix b/flake.nix index 1bc5c148..e10ea4ee 100644 --- a/flake.nix +++ b/flake.nix @@ -39,7 +39,7 @@ file = ./rust-toolchain.toml; # See also `rust-toolchain.toml` - sha256 = "sha256-gdYqng0y9iHYzYPAdkC/ka3DRny3La/S5G8ASj0Ayyc="; + sha256 = "sha256-SXRtAuO4IqNOQq+nLbrsDFbVk+3aVA8NNpSZsKlVH/8="; }; builder = pkgs: @@ -79,7 +79,11 @@ # # [0]: https://github.com/NixOS/nixpkgs/blob/612f97239e2cc474c13c9dafa0df378058c5ad8d/pkgs/build-support/rust/lib/default.nix#L36-L39 ( - pkgs.stdenv.hostPlatform.isAarch64 + (pkgs.stdenv.hostPlatform.isAarch64 + # Nixpkgs doesn't check for x86_64 here but we do, because I + # observed a failure building statically for x86_64 without + # including it here. Linkers are weird. + || pkgs.stdenv.hostPlatform.isx86_64) && pkgs.stdenv.hostPlatform.isStatic && !pkgs.stdenv.isDarwin && !pkgs.stdenv.cc.bintools.isLLVM diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 8ef64c92..f7a94340 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -10,7 +10,7 @@ # If you're having trouble making the relevant changes, bug a maintainer. [toolchain] -channel = "1.70.0" +channel = "1.75.0" components = [ # For rust-analyzer "rust-src", diff --git a/src/api/client_server/media.rs b/src/api/client_server/media.rs index 75f8e156..7fc65c26 100644 --- a/src/api/client_server/media.rs +++ b/src/api/client_server/media.rs @@ -51,7 +51,7 @@ pub async fn create_content_route( .await?; Ok(create_content::v3::Response { - content_uri: mxc.try_into().expect("Invalid mxc:// URI"), + content_uri: mxc.into(), blurhash: None, }) } diff --git a/src/database/abstraction/persy.rs b/src/database/abstraction/persy.rs index 1fa7a0df..da7d4cf0 100644 --- a/src/database/abstraction/persy.rs +++ b/src/database/abstraction/persy.rs @@ -116,7 +116,7 @@ impl KvTree for PersyTree { match iter { Ok(iter) => Box::new(iter.filter_map(|(k, v)| { v.into_iter() - .map(|val| ((*k).to_owned().into(), (*val).to_owned().into())) + .map(|val| ((*k).to_owned(), (*val).to_owned())) .next() })), Err(e) => { @@ -142,7 +142,7 @@ impl KvTree for PersyTree { Ok(iter) => { let map = iter.filter_map(|(k, v)| { v.into_iter() - .map(|val| ((*k).to_owned().into(), (*val).to_owned().into())) + .map(|val| ((*k).to_owned(), (*val).to_owned())) .next() }); if backwards { @@ -179,7 +179,7 @@ impl KvTree for PersyTree { iter.take_while(move |(k, _)| (*k).starts_with(&owned_prefix)) .filter_map(|(k, v)| { v.into_iter() - .map(|val| ((*k).to_owned().into(), (*val).to_owned().into())) + .map(|val| ((*k).to_owned(), (*val).to_owned())) .next() }), ) diff --git a/src/database/abstraction/sqlite.rs b/src/database/abstraction/sqlite.rs index b69efb61..222a8433 100644 --- a/src/database/abstraction/sqlite.rs +++ b/src/database/abstraction/sqlite.rs @@ -33,7 +33,7 @@ impl Iterator for PreparedStatementIterator<'_> { struct NonAliasingBox(*mut T); impl Drop for NonAliasingBox { fn drop(&mut self) { - unsafe { Box::from_raw(self.0) }; + drop(unsafe { Box::from_raw(self.0) }); } } diff --git a/src/database/key_value/account_data.rs b/src/database/key_value/account_data.rs index e1eef966..970b36b5 100644 --- a/src/database/key_value/account_data.rs +++ b/src/database/key_value/account_data.rs @@ -123,13 +123,12 @@ impl service::account_data::Data for KeyValueDatabase { .take_while(move |(k, _)| k.starts_with(&prefix)) .map(|(k, v)| { Ok::<_, Error>(( - RoomAccountDataEventType::try_from( + RoomAccountDataEventType::from( utils::string_from_bytes(k.rsplit(|&b| b == 0xff).next().ok_or_else( || Error::bad_database("RoomUserData ID in db is invalid."), )?) .map_err(|_| Error::bad_database("RoomUserData ID in db is invalid."))?, - ) - .map_err(|_| Error::bad_database("RoomUserData ID in db is invalid."))?, + ), serde_json::from_slice::>(&v).map_err(|_| { Error::bad_database("Database contains invalid account data.") })?, diff --git a/src/database/key_value/globals.rs b/src/database/key_value/globals.rs index 11aa0641..7a70af18 100644 --- a/src/database/key_value/globals.rs +++ b/src/database/key_value/globals.rs @@ -256,8 +256,8 @@ lasttimelinecount_cache: {lasttimelinecount_cache}\n" .. } = new_keys; - keys.verify_keys.extend(verify_keys.into_iter()); - keys.old_verify_keys.extend(old_verify_keys.into_iter()); + keys.verify_keys.extend(verify_keys); + keys.old_verify_keys.extend(old_verify_keys); self.server_signingkeys.insert( origin.as_bytes(), diff --git a/src/database/key_value/rooms/short.rs b/src/database/key_value/rooms/short.rs index c0223170..98cfa48a 100644 --- a/src/database/key_value/rooms/short.rs +++ b/src/database/key_value/rooms/short.rs @@ -157,10 +157,9 @@ impl service::rooms::short::Data for KeyValueDatabase { .ok_or_else(|| Error::bad_database("Invalid statekey in shortstatekey_statekey."))?; let event_type = - StateEventType::try_from(utils::string_from_bytes(eventtype_bytes).map_err(|_| { + StateEventType::from(utils::string_from_bytes(eventtype_bytes).map_err(|_| { Error::bad_database("Event type in shortstatekey_statekey is invalid unicode.") - })?) - .map_err(|_| Error::bad_database("Event type in shortstatekey_statekey is invalid."))?; + })?); let state_key = utils::string_from_bytes(statekey_bytes).map_err(|_| { Error::bad_database("Statekey in shortstatekey_statekey is invalid unicode.") diff --git a/src/database/key_value/users.rs b/src/database/key_value/users.rs index 2b09d684..0e6db83a 100644 --- a/src/database/key_value/users.rs +++ b/src/database/key_value/users.rs @@ -146,10 +146,9 @@ impl service::users::Data for KeyValueDatabase { self.userid_avatarurl .get(user_id.as_bytes())? .map(|bytes| { - let s = utils::string_from_bytes(&bytes) - .map_err(|_| Error::bad_database("Avatar URL in db is invalid."))?; - s.try_into() + utils::string_from_bytes(&bytes) .map_err(|_| Error::bad_database("Avatar URL in db is invalid.")) + .map(Into::into) }) .transpose() } diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index f034415e..f7822940 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -128,7 +128,7 @@ impl Resolve for Resolver { .expect("lock should not be poisoned") .get(name.as_str()) .and_then(|(override_name, port)| { - override_name.get(0).map(|first_name| { + override_name.first().map(|first_name| { let x: Box + Send> = Box::new(iter::once(SocketAddr::new(*first_name, *port))); let x: Resolving = Box::pin(future::ready(Ok(x))); diff --git a/src/service/pdu.rs b/src/service/pdu.rs index 4a170bc2..c8d78604 100644 --- a/src/service/pdu.rs +++ b/src/service/pdu.rs @@ -385,7 +385,7 @@ impl PartialEq for PduEvent { } impl PartialOrd for PduEvent { fn partial_cmp(&self, other: &Self) -> Option { - self.event_id.partial_cmp(&other.event_id) + Some(self.cmp(other)) } } impl Ord for PduEvent { diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 06a076e8..ef09d061 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -90,18 +90,6 @@ impl Ord for PduCount { } } } -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn comparisons() { - assert!(PduCount::Normal(1) < PduCount::Normal(2)); - assert!(PduCount::Backfilled(2) < PduCount::Backfilled(1)); - assert!(PduCount::Normal(1) > PduCount::Backfilled(1)); - assert!(PduCount::Backfilled(1) < PduCount::Normal(1)); - } -} pub struct Service { pub db: &'static dyn Data, @@ -1208,3 +1196,16 @@ impl Service { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn comparisons() { + assert!(PduCount::Normal(1) < PduCount::Normal(2)); + assert!(PduCount::Backfilled(2) < PduCount::Backfilled(1)); + assert!(PduCount::Normal(1) > PduCount::Backfilled(1)); + assert!(PduCount::Backfilled(1) < PduCount::Normal(1)); + } +} diff --git a/src/service/sending/mod.rs b/src/service/sending/mod.rs index b4411444..f80c4f0a 100644 --- a/src/service/sending/mod.rs +++ b/src/service/sending/mod.rs @@ -131,7 +131,7 @@ impl Service { for (key, outgoing_kind, event) in self.db.active_requests().filter_map(|r| r.ok()) { let entry = initial_transactions .entry(outgoing_kind.clone()) - .or_insert_with(Vec::new); + .or_default(); if entry.len() > 30 { warn!( diff --git a/src/service/users/mod.rs b/src/service/users/mod.rs index dc34d533..fb983a41 100644 --- a/src/service/users/mod.rs +++ b/src/service/users/mod.rs @@ -138,12 +138,18 @@ impl Service { cached.lists.insert(list_id.clone(), list.clone()); } - cached - .subscriptions - .extend(request.room_subscriptions.clone().into_iter()); - request - .room_subscriptions - .extend(cached.subscriptions.clone().into_iter()); + cached.subscriptions.extend( + request + .room_subscriptions + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); + request.room_subscriptions.extend( + cached + .subscriptions + .iter() + .map(|(k, v)| (k.clone(), v.clone())), + ); request.extensions.e2ee.enabled = request .extensions From a7892a28ec9395fbd5fd99aa09ed8de1206434be Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 25 Jan 2024 22:00:32 -0800 Subject: [PATCH 041/129] refer directly to stdenv since it's in scope --- flake.nix | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/flake.nix b/flake.nix index e10ea4ee..c9ef7914 100644 --- a/flake.nix +++ b/flake.nix @@ -70,7 +70,7 @@ stdenv.hostPlatform.isStatic ["-C" "relocation-model=static"] ++ lib.optionals - (stdenv.buildPlatform.config != pkgs.stdenv.hostPlatform.config) + (stdenv.buildPlatform.config != stdenv.hostPlatform.config) ["-l" "c"] ++ lib.optionals # This check has to match the one [here][0]. We only need to set @@ -79,14 +79,13 @@ # # [0]: https://github.com/NixOS/nixpkgs/blob/612f97239e2cc474c13c9dafa0df378058c5ad8d/pkgs/build-support/rust/lib/default.nix#L36-L39 ( - (pkgs.stdenv.hostPlatform.isAarch64 - # Nixpkgs doesn't check for x86_64 here but we do, because I - # observed a failure building statically for x86_64 without - # including it here. Linkers are weird. - || pkgs.stdenv.hostPlatform.isx86_64) - && pkgs.stdenv.hostPlatform.isStatic - && !pkgs.stdenv.isDarwin - && !pkgs.stdenv.cc.bintools.isLLVM + # Nixpkgs doesn't check for x86_64 here but we do, because I + # observed a failure building statically for x86_64 without + # including it here. Linkers are weird. + (stdenv.hostPlatform.isAarch64 || stdenv.hostPlatform.isx86_64) + && stdenv.hostPlatform.isStatic + && !stdenv.isDarwin + && !stdenv.cc.bintools.isLLVM ) [ "-l" From 3e389256f5f191d6a26eecc622ec0e70661745c0 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Fri, 26 Jan 2024 00:11:14 -0800 Subject: [PATCH 042/129] switch lint config to `manifest-lint` feature I removed some lint configuration in the process: * `#[allow(clippy::suspicious_else_formatting)]` because nothing is currently triggering it. * `#[warn(clippy::future_not_send)]` because some stuff under `src/lib.rs` is. And also like, auto-trait leakage generally means this isn't a problem, and if things really need to be `Send`, then you'll probably know to mark it manually. * `#[warn(rust_2018_idioms)]` and replaced it with `explicit-outlives-requirements = "warn"` which is the most useful lint in that group that isn't enabled by default. --- Cargo.toml | 14 ++++++++++++++ src/lib.rs | 9 --------- src/main.rs | 10 ---------- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 156de3c2..5292399a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,14 @@ +# Keep alphabetically sorted +[workspace.lints.rust] +explicit_outlives_requirements = "warn" +unused_qualifications = "warn" + +# Keep alphabetically sorted +[workspace.lints.clippy] +cloned_instead_of_copied = "warn" +dbg_macro = "warn" +str_to_string = "warn" + [package] name = "conduit" description = "A Matrix homeserver written in Rust" @@ -14,6 +25,9 @@ rust-version = "1.75.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lints] +workspace = true + [dependencies] # Web framework axum = { version = "0.6.18", default-features = false, features = ["form", "headers", "http1", "http2", "json", "matched-path"], optional = true } diff --git a/src/lib.rs b/src/lib.rs index dc6a9d2f..66d0c57c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,3 @@ -#![warn( - rust_2018_idioms, - unused_qualifications, - clippy::cloned_instead_of_copied, - clippy::str_to_string -)] -#![allow(clippy::suspicious_else_formatting)] -#![deny(clippy::dbg_macro)] - pub mod api; mod config; mod database; diff --git a/src/main.rs b/src/main.rs index 683e0914..524f6886 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,3 @@ -#![warn( - rust_2018_idioms, - unused_qualifications, - clippy::cloned_instead_of_copied, - clippy::str_to_string, - clippy::future_not_send -)] -#![allow(clippy::suspicious_else_formatting)] -#![deny(clippy::dbg_macro)] - use std::{future::Future, io, net::SocketAddr, sync::atomic, time::Duration}; use axum::{ From 0df5d18fd6eb08b8398453b287b17c8bc2bae621 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Fri, 26 Jan 2024 21:38:13 -0800 Subject: [PATCH 043/129] change docker tag back to `next` I misunderstood what the general meaning of the `latest` tag was. --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index c9ef7914..a16ea58c 100644 --- a/flake.nix +++ b/flake.nix @@ -166,7 +166,7 @@ mkOciImage = pkgs: package: pkgs.dockerTools.buildImage { name = package.pname; - tag = "latest"; + tag = "next"; config = { # Use the `tini` init system so that signals (e.g. ctrl+c/SIGINT) # are handled as expected From dffd771e7c9f48a0a63f9bc945ce1ee3c9afaa69 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sat, 27 Jan 2024 12:23:57 -0800 Subject: [PATCH 044/129] add ca certificates to the OCI image Without this, checking the authority of TLS certificates fails, making Conduit (rightly) refuse to connect to anything. --- flake.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flake.nix b/flake.nix index a16ea58c..31a84131 100644 --- a/flake.nix +++ b/flake.nix @@ -167,6 +167,9 @@ pkgs.dockerTools.buildImage { name = package.pname; tag = "next"; + copyToRoot = [ + pkgs.dockerTools.caCertificates + ]; config = { # Use the `tini` init system so that signals (e.g. ctrl+c/SIGINT) # are handled as expected From cf8f1f25467c02f86433a5b0ef49e639e9b1eb45 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 24 Dec 2023 00:51:26 -0800 Subject: [PATCH 045/129] make a bunch of changes so complement works again Well, kinda. It crashed on me after 10 minutes because the tests timed out like in . Sounds like this means it's a them problem though. I want to use Nix to build this image instead in the future but this will at least make it work for now and give me a reference for while I'm porting it. I also want to make Conduit natively understand Complement's requirements instead of `sed`ing a bunch of stuff and needing a reverse proxy in the container. Should be more reliable that way. I'm not making this run in CI until the above stuff is addressed and until I can decide on a way to pin the revision of Complement being tested against. --- bin/complement | 37 +++++++++++++++++++++++++++++++++++ complement/Dockerfile | 45 ++++++++++++++++++++----------------------- complement/README.md | 16 +++++++-------- flake.nix | 7 +++++++ 4 files changed, 72 insertions(+), 33 deletions(-) create mode 100755 bin/complement diff --git a/bin/complement b/bin/complement new file mode 100755 index 00000000..291953dd --- /dev/null +++ b/bin/complement @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# Path to Complement's source code +COMPLEMENT_SRC="$1" + +# A `.jsonl` file to write test logs to +LOG_FILE="$2" + +# A `.jsonl` file to write test results to +RESULTS_FILE="$3" + +OCI_IMAGE="complement-conduit:dev" + +env \ + -C "$(git rev-parse --show-toplevel)" \ + docker build \ + --tag "$OCI_IMAGE" \ + --file complement/Dockerfile \ + . + +# It's okay (likely, even) that `go test` exits nonzero +set +o pipefail +env \ + -C "$COMPLEMENT_SRC" \ + COMPLEMENT_BASE_IMAGE="$OCI_IMAGE" \ + go test -json ./tests | tee "$LOG_FILE" +set -o pipefail + +# Post-process the results into an easy-to-compare format +cat "$LOG_FILE" | jq -c ' + select( + (.Action == "pass" or .Action == "fail" or .Action == "skip") + and .Test != null + ) | {Action: .Action, Test: .Test} + ' | sort > "$RESULTS_FILE" diff --git a/complement/Dockerfile b/complement/Dockerfile index 50173a1c..813af10e 100644 --- a/complement/Dockerfile +++ b/complement/Dockerfile @@ -1,26 +1,30 @@ -# For use in our CI only. This requires a build artifact created by a previous run pipline stage to be placed in cached_target/release/conduit -FROM registry.gitlab.com/jfowl/conduit-containers/rust-with-tools:commit-16a08e9b as builder -#FROM rust:latest as builder +FROM rust:1.75.0 WORKDIR /workdir -ARG RUSTC_WRAPPER -ARG AWS_ACCESS_KEY_ID -ARG AWS_SECRET_ACCESS_KEY -ARG SCCACHE_BUCKET -ARG SCCACHE_ENDPOINT -ARG SCCACHE_S3_USE_SSL +RUN apt-get update && apt-get install -y --no-install-recommends \ + libclang-dev -COPY . . -RUN mkdir -p target/release -RUN test -e cached_target/release/conduit && cp cached_target/release/conduit target/release/conduit || cargo build --release - -## Actual image -FROM debian:bullseye -WORKDIR /workdir +COPY Cargo.toml Cargo.toml +COPY Cargo.lock Cargo.lock +COPY src src +RUN cargo build --release \ + && mv target/release/conduit conduit \ + && rm -rf target # Install caddy -RUN apt-get update && apt-get install -y debian-keyring debian-archive-keyring apt-transport-https curl && curl -1sLf 'https://dl.cloudsmith.io/public/caddy/testing/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-testing-archive-keyring.gpg && curl -1sLf 'https://dl.cloudsmith.io/public/caddy/testing/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-testing.list && apt-get update && apt-get install -y caddy +RUN apt-get update \ + && apt-get install -y \ + debian-keyring \ + debian-archive-keyring \ + apt-transport-https \ + curl \ + && curl -1sLf 'https://dl.cloudsmith.io/public/caddy/testing/gpg.key' \ + | gpg --dearmor -o /usr/share/keyrings/caddy-testing-archive-keyring.gpg \ + && curl -1sLf 'https://dl.cloudsmith.io/public/caddy/testing/debian.deb.txt' \ + | tee /etc/apt/sources.list.d/caddy-testing.list \ + && apt-get update \ + && apt-get install -y caddy COPY conduit-example.toml conduit.toml COPY complement/caddy.json caddy.json @@ -29,16 +33,9 @@ ENV SERVER_NAME=localhost ENV CONDUIT_CONFIG=/workdir/conduit.toml RUN sed -i "s/port = 6167/port = 8008/g" conduit.toml -RUN echo "allow_federation = true" >> conduit.toml -RUN echo "allow_check_for_updates = true" >> conduit.toml -RUN echo "allow_encryption = true" >> conduit.toml -RUN echo "allow_registration = true" >> conduit.toml RUN echo "log = \"warn,_=off,sled=off\"" >> conduit.toml RUN sed -i "s/address = \"127.0.0.1\"/address = \"0.0.0.0\"/g" conduit.toml -COPY --from=builder /workdir/target/release/conduit /workdir/conduit -RUN chmod +x /workdir/conduit - EXPOSE 8008 8448 CMD uname -a && \ diff --git a/complement/README.md b/complement/README.md index b86aab38..185b251a 100644 --- a/complement/README.md +++ b/complement/README.md @@ -1,13 +1,11 @@ -# Running Conduit on Complement +# Complement -This assumes that you're familiar with complement, if not, please readme -[their readme](https://github.com/matrix-org/complement#running). +## What's that? -Complement works with "base images", this directory (and Dockerfile) helps build the conduit complement-ready docker -image. +Have a look at [its repository](https://github.com/matrix-org/complement). -To build, `cd` to the base directory of the workspace, and run this: +## How do I use it with Conduit? -`docker build -t complement-conduit:dev -f complement/Dockerfile .` - -Then use `complement-conduit:dev` as a base image for running complement tests. +The script at [`../bin/complement`](../bin/complement) has automation for this. +It takes a few command line arguments, you can read the script to find out what +those are. diff --git a/flake.nix b/flake.nix index 31a84131..bf50e584 100644 --- a/flake.nix +++ b/flake.nix @@ -234,6 +234,13 @@ toolchain ] ++ (with pkgsHost; [ engage + + # Needed for Complement + go + olm + + # Needed for our script for Complement + jq ]); }; }); From c167f7a6ad32d27a390ea5017572f7461a4271c4 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 28 Jan 2024 13:31:03 -0800 Subject: [PATCH 046/129] switch crane input back to upstream Thanks to the crane maintainer to fixing my issue in a way that doesn't suck, unlike my attempt in the fork we were briefly using. --- flake.lock | 12 ++++++------ flake.nix | 5 +---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/flake.lock b/flake.lock index 4508f7ce..85b0ab53 100644 --- a/flake.lock +++ b/flake.lock @@ -51,16 +51,16 @@ ] }, "locked": { - "lastModified": 1706070683, - "narHash": "sha256-iQoXIFviH5QbSKDkWyFJKKUtTcSiCvl1tW18ax+pKfI=", - "owner": "CobaltCause", + "lastModified": 1706473964, + "narHash": "sha256-Fq6xleee/TsX6NbtoRuI96bBuDHMU57PrcK9z1QEKbk=", + "owner": "ipetkov", "repo": "crane", - "rev": "8060686afabc5b042e8982200cb2cc3fd22cf416", + "rev": "c798790eabec3e3da48190ae3698ac227aab770c", "type": "github" }, "original": { - "owner": "CobaltCause", - "ref": "crimes-for-cross", + "owner": "ipetkov", + "ref": "master", "repo": "crane", "type": "github" } diff --git a/flake.nix b/flake.nix index bf50e584..94259685 100644 --- a/flake.nix +++ b/flake.nix @@ -9,10 +9,7 @@ inputs.nixpkgs.follows = "nixpkgs"; }; crane = { - # TODO: Switch back to upstream after [this issue][0] is fixed - # - # [0]: https://github.com/ipetkov/crane/issues/497 - url = "github:CobaltCause/crane?ref=crimes-for-cross"; + url = "github:ipetkov/crane?ref=master"; inputs.nixpkgs.follows = "nixpkgs"; }; attic.url = "github:zhaofengli/attic?ref=main"; From 2d47710b551616786dfa935d6a769f34c30b4161 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 29 Jan 2024 14:50:30 -0800 Subject: [PATCH 047/129] update DEPLOY.md with new build links --- DEPLOY.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/DEPLOY.md b/DEPLOY.md index cb318eee..dcb1777d 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -12,11 +12,13 @@ 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 appropriate url: -| 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] | +**Stable versions:** + +| CPU Architecture | Download stable version | +| ------------------------------------------- | --------------------------------------------------------------- | +| x84_64 / amd64 (Most servers and computers) | [Binary][x84_64-glibc-master] / [.deb][x84_64-glibc-master-deb] | +| armv7 (e.g. Raspberry Pi by default) | [Binary][armv7-glibc-master] / [.deb][armv7-glibc-master-deb] | +| armv8 / aarch64 | [Binary][armv8-glibc-master] / [.deb][armv8-glibc-master-deb] | 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 (e.g. RHEL8), you might need to compile Conduit yourself. @@ -24,15 +26,19 @@ If you use a system with an older glibc version (e.g. RHEL8), you might need to [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 + +**Latest versions:** + +| Target | Type | Download | +|-|-|-| +| `x86_64-unknown-linux-gnu` | Dynamically linked Debian package | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit.deb?job=debian:x86_64-unknown-linux-gnu) | +| `x86_64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit?job=static:x86_64-unknown-linux-musl) | +| `aarch64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit?job=static:aarch64-unknown-linux-musl) | +| `x86_64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image.tar.gz?job=oci-image:x86_64-unknown-linux-musl) | +| `aarch64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image.tar.gz?job=oci-image:aarch64-unknown-linux-musl) | ```bash $ sudo wget -O /usr/local/bin/matrix-conduit From a43bde69fa6ae1517e5475f9bd4d228bad3b0fea Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 29 Jan 2024 15:34:16 -0800 Subject: [PATCH 048/129] pass pkgsCrossStatic to mkOciImage, not pkgsHost This fixes a bug where the aarch64 OCI image had metadata saying it was an x86_64 OCI image. On top of that, I think the metadata was actually right (aside from Conduit's binary): since all other packages were being pulled from `pkgsHost`, an OCI image cross compiled for aarch64 from a different architecture would result in unexecutable binaries (e.g. tini) since they were compiled for the completely wrong architecture. --- .gitlab-ci.yml | 3 +++ flake.nix | 65 +++++++++++++++++++++++++++++--------------------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f2438c8e..d4e49ce4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -68,6 +68,9 @@ static:aarch64-unknown-linux-musl: paths: - conduit +# Note that although we have an `oci-image-x86_64-unknown-linux-musl` output, +# we don't build it because it would be largely redundant to this one since it's +# all containerized anyway. oci-image:x86_64-unknown-linux-gnu: stage: artifacts image: nixos/nix:2.19.2 diff --git a/flake.nix b/flake.nix index 94259685..e0bc6fbb 100644 --- a/flake.nix +++ b/flake.nix @@ -183,34 +183,45 @@ { packages = { default = package pkgsHost; - oci-image = mkOciImage pkgsHost self.packages.${system}.default; - - # Build an OCI image from the musl aarch64 build so we don't have to - # build for aarch64 twice (to make a gnu version specifically for the - # OCI image) - oci-image-aarch64-unknown-linux-musl = mkOciImage - pkgsHost - self.packages.${system}.static-aarch64-unknown-linux-musl; - - # Don't build a musl x86_64 OCI image because that would be pointless. - # Just use the gnu one (i.e. `self.packages."x86_64-linux".oci-image`). - } // builtins.listToAttrs ( - builtins.map - (crossSystem: { - name = "static-${crossSystem}"; - value = package (import nixpkgs { - inherit system; - crossSystem = { - config = crossSystem; - }; - }).pkgsStatic; - }) - [ - "x86_64-unknown-linux-musl" - "aarch64-unknown-linux-musl" - ] - ); + } + // + builtins.listToAttrs + (builtins.concatLists + (builtins.map + (crossSystem: + let + binaryName = "static-${crossSystem}"; + pkgsCrossStatic = + (import nixpkgs { + inherit system; + crossSystem = { + config = crossSystem; + }; + }).pkgsStatic; + in + [ + # An output for a statically-linked binary + { + name = binaryName; + value = package pkgsCrossStatic; + } + + # An output for an OCI image based on that binary + { + name = "oci-image-${crossSystem}"; + value = mkOciImage + pkgsCrossStatic + self.packages.${system}.${binaryName}; + } + ] + ) + [ + "x86_64-unknown-linux-musl" + "aarch64-unknown-linux-musl" + ] + ) + ); devShells.default = pkgsHost.mkShell { env = env pkgsHost // { From 1274b48ebb09ac1f1576cbb9e3417a4ca2256273 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 29 Jan 2024 15:54:31 -0800 Subject: [PATCH 049/129] run `cargo update` `IndexMap::remove` was deprecated in favor of explicitly named methods. I assume that we actually needed to be using `shift_remove`, otherwise we probably wouldn't be bothering with `indexmap` here in the first place. I wonder if this fixes any bugs lol --- Cargo.lock | 1232 ++++++++++++++++++++++++------------------- src/database/mod.rs | 6 +- 2 files changed, 696 insertions(+), 542 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d5e1d161..81b270db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + [[package]] name = "adler" version = "1.0.2" @@ -10,35 +19,36 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220" [[package]] name = "arc-swap" @@ -72,20 +82,23 @@ checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002" [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] name = "atomic" -version = "0.5.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" +checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" +dependencies = [ + "bytemuck", +] [[package]] name = "autocfg" @@ -95,9 +108,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", @@ -162,6 +175,21 @@ dependencies = [ "tower-service", ] +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.13.1" @@ -170,9 +198,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -198,7 +226,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] @@ -209,19 +237,19 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.2" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "blake2b_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq 0.2.6", + "constant_time_eq", ] [[package]] @@ -235,27 +263,27 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "ed2490600f404f2b94c167e31d3ed1d5f3c225a0f3b80230053b3e0b7b962bd9" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "bzip2-sys" @@ -270,11 +298,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -294,9 +323,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", @@ -305,43 +334,41 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.8" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9394150f5b4273a1763355bd1c2ec54cc5a2593f790587bcd6b2c947cfa9211" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.8" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a78fbdd3cc2914ddf37ba444114bc7765bbdcb55ec9cbe6fa054f0137400717" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstyle", - "bitflags 1.3.2", "clap_lex", ] [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "color_quant" @@ -356,7 +383,7 @@ dependencies = [ "async-trait", "axum", "axum-server", - "base64 0.21.2", + "base64 0.21.7", "bytes", "clap", "directories", @@ -378,7 +405,7 @@ dependencies = [ "rand", "regex", "reqwest", - "ring", + "ring 0.16.20", "rocksdb", "ruma", "rusqlite", @@ -406,9 +433,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.2" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_panic" @@ -418,21 +445,15 @@ checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" [[package]] name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "constant_time_eq" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -440,15 +461,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -464,9 +485,9 @@ dependencies = [ [[package]] name = "crc-catalog" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" @@ -479,22 +500,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -508,9 +525,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622178105f911d937a42cdb140730ba4a3ed2becd8ae6ce39c7d28b5d75d4588" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" dependencies = [ "cfg-if", "cpufeatures", @@ -525,23 +542,23 @@ dependencies = [ [[package]] name = "curve25519-dalek-derive" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] name = "dashmap" -version = "5.4.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.12.3", + "hashbrown 0.14.3", "lock_api", "once_cell", "parking_lot_core", @@ -549,9 +566,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" @@ -563,6 +580,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "digest" version = "0.10.7" @@ -596,9 +622,9 @@ dependencies = [ [[package]] name = "ed25519" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8", "signature", @@ -606,29 +632,30 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", + "subtle", "zeroize", ] [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -647,9 +674,9 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "fallible-iterator" @@ -665,38 +692,38 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fdeflate" -version = "0.3.0" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ "simd-adler32", ] [[package]] name = "fiat-crypto" -version = "0.2.1" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" [[package]] name = "figment" -version = "0.10.10" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4547e226f4c9ab860571e070a9034192b3175580ecea38da34fcdb53a018c9a5" +checksum = "2b6e5bc7bd59d60d0d45a6ccab6cf0f4ce28698fb4e81e750ddf229c9b824026" dependencies = [ "atomic", "pear", "serde", - "toml", + "toml 0.8.8", "uncased", "version_check", ] [[package]] name = "flate2" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "miniz_oxide", @@ -710,9 +737,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -729,9 +756,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -744,9 +771,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -754,15 +781,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -771,38 +798,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -828,9 +855,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "libc", @@ -847,6 +874,12 @@ dependencies = [ "weezl", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "glob" version = "0.3.1" @@ -855,9 +888,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.19" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -865,7 +898,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.2.1", "slab", "tokio", "tokio-util", @@ -880,9 +913,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", @@ -890,21 +923,20 @@ dependencies = [ [[package]] name = "hashlink" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.0", + "hashbrown 0.14.3", ] [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", + "base64 0.21.7", "bytes", "headers-core", "http", @@ -930,12 +962,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "hmac" @@ -959,9 +988,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -970,9 +999,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -981,9 +1010,9 @@ dependencies = [ [[package]] name = "http-range-header" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" @@ -993,15 +1022,15 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -1014,7 +1043,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2", "tokio", "tower-service", "tracing", @@ -1023,9 +1052,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http", @@ -1048,9 +1077,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1058,16 +1087,15 @@ dependencies = [ [[package]] name = "image" -version = "0.24.6" +version = "0.24.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" +checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" dependencies = [ "bytemuck", "byteorder", "color_quant", "gif", "jpeg-decoder", - "num-rational", "num-traits", "png", ] @@ -1084,12 +1112,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "serde", ] @@ -1111,17 +1139,17 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.3", + "socket2", "widestring", "windows-sys 0.48.0", - "winreg 0.50.0", + "winreg", ] [[package]] name = "ipnet" -version = "2.7.2" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "itertools" @@ -1134,30 +1162,30 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] [[package]] name = "jpeg-decoder" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -1186,9 +1214,9 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", "pem", - "ring", + "ring 0.16.20", "serde", "serde_json", "simple_asn1", @@ -1196,9 +1224,9 @@ dependencies = [ [[package]] name = "konst" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9a8bb6c7c71d151b25936b03e012a4c00daea99e3a3797c6ead66b0a0d55e2" +checksum = "8d712a8c49d4274f8d8a5cf61368cb5f3c143d149882b1a2918129e53395fdb0" dependencies = [ "const_panic", "konst_kernel", @@ -1207,9 +1235,9 @@ dependencies = [ [[package]] name = "konst_kernel" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d2ab266022e7309df89ed712bddc753e3a3c395c3ced1bb2e4470ec2a8146d" +checksum = "dac6ea8c376b6e208a81cf39b8e82bebf49652454d98a4829e907dac16ef1790" dependencies = [ "typewit", ] @@ -1228,18 +1256,29 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.146" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if", - "winapi", + "windows-sys 0.48.0", +] + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall", ] [[package]] @@ -1271,9 +1310,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.9" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" dependencies = [ "cc", "pkg-config", @@ -1288,9 +1327,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1298,9 +1337,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lru-cache" @@ -1339,7 +1378,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -1350,15 +1389,15 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memoffset" @@ -1393,9 +1432,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "wasi", @@ -1404,16 +1443,15 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", "memoffset", "pin-utils", - "static_assertions", ] [[package]] @@ -1438,9 +1476,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -1458,40 +1496,38 @@ dependencies = [ ] [[package]] -name = "num-rational" -version = "0.4.1" +name = "num-traits" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", - "num-integer", - "num-traits", ] [[package]] -name = "num-traits" -version = "0.2.15" +name = "num_cpus" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "autocfg", + "hermit-abi", + "libc", ] [[package]] -name = "num_cpus" -version = "1.15.0" +name = "object" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ - "hermit-abi", - "libc", + "memchr", ] [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl-probe" @@ -1600,28 +1636,28 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] name = "paste" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pear" -version = "0.2.4" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec95680a7087503575284e5063e14b694b7a9c0b065e5dceec661e0497127e8" +checksum = "4ccca0f6c17acc81df8e242ed473ec144cbf5c98037e69aa6d144780aad103c8" dependencies = [ "inlinable_string", "pear_codegen", @@ -1630,14 +1666,14 @@ dependencies = [ [[package]] name = "pear_codegen" -version = "0.2.4" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9661a3a53f93f09f2ea882018e4d7c88f6ff2956d809a276060476fd8c879d3c" +checksum = "2e22670e8eb757cff11d6c199ca7b987f352f0346e0be4dd23869ec72cb53c77" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] @@ -1657,15 +1693,15 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "persy" -version = "1.4.4" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3712821f12453814409ec149071bd4832a8ec458e648579c104aee30ed70b300" +checksum = "3cd38c602b23c2f451842d89f27cd5e0d4b292176daf40feeda859c658dcdc76" dependencies = [ "crc", "data-encoding", @@ -1679,29 +1715,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1721,21 +1757,21 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "platforms" -version = "3.1.2" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "png" -version = "0.17.9" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" +checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -1744,6 +1780,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1752,12 +1794,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.9" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9825a04601d60621feed79c4e6b56d65db77cdca55cef43b46b0de1096d1c282" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] @@ -1767,27 +1809,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", ] [[package]] name = "proc-macro2" -version = "1.0.61" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "363a6f739a0c0addeaf6ed75150b95743aa18643a3c6f40409ed7b6db3a6911f" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] [[package]] name = "proc-macro2-diagnostics" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", "version_check", "yansi", ] @@ -1800,9 +1842,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.28" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1839,42 +1881,34 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.4.5", + "regex-syntax 0.8.2", ] [[package]] @@ -1886,6 +1920,17 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -1894,17 +1939,17 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", @@ -1927,6 +1972,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-rustls", "tokio-socks", @@ -1935,7 +1981,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.10.1", + "winreg", ] [[package]] @@ -1957,12 +2003,26 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + [[package]] name = "rocksdb" version = "0.21.0" @@ -2028,11 +2088,11 @@ version = "0.11.3" source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" dependencies = [ "as_variant", - "base64 0.21.2", + "base64 0.21.7", "bytes", "form_urlencoded", "http", - "indexmap 2.0.0", + "indexmap 2.2.1", "js_int", "konst", "percent-encoding", @@ -2056,7 +2116,7 @@ version = "0.26.0" source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" dependencies = [ "as_variant", - "indexmap 2.0.0", + "indexmap 2.2.1", "js_int", "js_option", "percent-encoding", @@ -2114,8 +2174,8 @@ dependencies = [ "quote", "ruma-identifiers-validation", "serde", - "syn 2.0.21", - "toml", + "syn 2.0.48", + "toml 0.7.8", ] [[package]] @@ -2135,7 +2195,7 @@ name = "ruma-signatures" version = "0.13.1" source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", "ed25519-dalek", "pkcs8", "rand", @@ -2167,7 +2227,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" dependencies = [ - "bitflags 2.3.2", + "bitflags 2.4.2", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -2177,16 +2237,22 @@ dependencies = [ [[package]] name = "rust-argon2" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50162d19404029c1ceca6f6980fe40d45c8b369f6f44446fa14bb39573b5bb9" +checksum = "a5885493fdf0be6cdff808d1533ce878d21cfa49c7086fa00c66355cd9141bfc" dependencies = [ - "base64 0.13.1", + "base64 0.21.7", "blake2b_simd", - "constant_time_eq 0.1.5", + "constant_time_eq", "crossbeam-utils", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -2204,12 +2270,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.2" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring", + "ring 0.17.7", "rustls-webpki", "sct", ] @@ -2228,58 +2294,58 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.52.0", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] @@ -2290,9 +2356,9 @@ checksum = "621e3680f3e07db4c9c2c3fb07c6223ab2fab2e54bd3c04c3ae037990f428c32" [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -2303,9 +2369,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -2313,38 +2379,38 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] name = "serde_html_form" -version = "0.2.0" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53192e38d5c88564b924dbe9b60865ecbb71b81d38c4e61c817cffd3e36ef696" +checksum = "20e1066e1cfa6692a722cf40386a2caec36da5ddc4a2c16df592f0f609677e8c" dependencies = [ "form_urlencoded", - "indexmap 1.9.3", + "indexmap 2.2.1", "itoa", "ryu", "serde", @@ -2352,9 +2418,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.99" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", @@ -2363,18 +2429,19 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.11" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" dependencies = [ + "itoa", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -2393,11 +2460,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.22" +version = "0.9.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "452e67b9c20c37fa79df53201dc03839651086ed9bbe92b3ca585ca9fdaa7d85" +checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.1", "itoa", "ryu", "serde", @@ -2417,9 +2484,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -2428,9 +2495,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -2439,18 +2506,18 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] [[package]] name = "shlex" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" @@ -2463,15 +2530,18 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core", +] [[package]] name = "simd-adler32" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "simple_asn1" @@ -2487,34 +2557,24 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "socket2" -version = "0.4.9" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys 0.48.0", @@ -2526,22 +2586,22 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "subslice" version = "0.2.3" @@ -2570,9 +2630,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.21" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1182caafaab7018eaea9b404afa8184c0baf42a04d5e10ae4f4843c2029c8aab" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -2585,24 +2645,45 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] @@ -2639,9 +2720,9 @@ dependencies = [ [[package]] name = "tikv-jemalloc-ctl" -version = "0.5.0" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37706572f4b151dff7a0146e040804e9c26fe3a3118591112f05cf12a4216c1" +checksum = "619bfed27d807b54f7f776b9430d4f8060e66ee138a28632ca898584d462c31c" dependencies = [ "libc", "paste", @@ -2650,9 +2731,9 @@ dependencies = [ [[package]] name = "tikv-jemalloc-sys" -version = "0.5.3+5.3.0-patched" +version = "0.5.4+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a678df20055b43e57ef8cddde41cdfda9a3c1a060b67f4c5836dfb1d78543ba8" +checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" dependencies = [ "cc", "libc", @@ -2660,9 +2741,9 @@ dependencies = [ [[package]] name = "tikv-jemallocator" -version = "0.5.0" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20612db8a13a6c06d57ec83953694185a367e16945f66565e8028d2c0bd76979" +checksum = "965fe0c26be5c56c94e38ba547249074803efd52adfb66de62107d95aab3eaca" dependencies = [ "libc", "tikv-jemalloc-sys", @@ -2670,11 +2751,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ + "deranged", "itoa", + "powerfmt", "serde", "time-core", "time-macros", @@ -2682,15 +2765,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" dependencies = [ "time-core", ] @@ -2712,31 +2795,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", "mio", "num_cpus", "pin-project-lite", "signal-hook-registry", - "socket2 0.4.9", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] @@ -2774,9 +2857,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -2788,32 +2871,57 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.5" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.21.0", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ + "indexmap 2.2.1", "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] name = "toml_edit" -version = "0.19.11" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.1", "serde", "serde_spanned", "toml_datetime", @@ -2837,11 +2945,11 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8bd22a874a2d0b70452d5597b12c537331d49060824a95f49f108994f94aa4c" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.3.2", + "bitflags 2.4.2", "bytes", "futures-core", "futures-util", @@ -2869,11 +2977,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -2882,20 +2989,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -2914,12 +3021,23 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] @@ -2933,15 +3051,15 @@ dependencies = [ "opentelemetry", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.1.4", "tracing-subscriber", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "nu-ansi-term", @@ -2952,7 +3070,7 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.2.0", ] [[package]] @@ -3002,42 +3120,51 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typewit" -version = "1.4.0" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fb9ae6a3cafaf0a5d14c2302ca525f9ae8e07a0f0e6949de88d882c37a6e24" +dependencies = [ + "typewit_proc_macros", +] + +[[package]] +name = "typewit_proc_macros" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4061a10d4d8f3081a8ccc025182afd8434302d8d4b4503ec6d8510d09df08c2d" +checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" [[package]] name = "uncased" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" dependencies = [ "version_check", ] [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -3050,15 +3177,15 @@ dependencies = [ [[package]] name = "unsafe-libyaml" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6" +checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" [[package]] name = "unsigned-varint" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" [[package]] name = "untrusted" @@ -3066,22 +3193,28 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna 0.4.0", + "idna 0.5.0", "percent-encoding", ] [[package]] name = "uuid" -version = "1.3.4" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ "getrandom", ] @@ -3121,9 +3254,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3131,24 +3264,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if", "js-sys", @@ -3158,9 +3291,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3168,28 +3301,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.21", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -3197,9 +3330,9 @@ dependencies = [ [[package]] name = "weezl" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "widestring" @@ -3209,9 +3342,9 @@ checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" [[package]] name = "wildmatch" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee583bdc5ff1cf9db20e9db5bb3ff4c3089a8f6b8b31aff265c9aba85812db86" +checksum = "495ec47bf3c1345005f40724f0269362c8556cbc43aed0526ed44cae1d35fceb" [[package]] name = "winapi" @@ -3237,145 +3370,145 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.48.5", ] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.0", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.4.7" +version = "0.5.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" +checksum = "1931d78a9c73861da0134f453bb1f790ce49b2e30eba8410b4b79bac72b46a2d" dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "winreg" version = "0.50.0" @@ -3388,15 +3521,35 @@ dependencies = [ [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377" + +[[package]] +name = "zerocopy" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" [[package]] name = "zigzag" @@ -3409,11 +3562,10 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" +version = "2.0.9+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" dependencies = [ "cc", - "libc", "pkg-config", ] diff --git a/src/database/mod.rs b/src/database/mod.rs index e247d9f0..425ef4e9 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -852,7 +852,9 @@ impl KeyValueDatabase { if rule.is_some() { let mut rule = rule.unwrap().clone(); rule.rule_id = content_rule_transformation[1].to_owned(); - rules_list.content.remove(content_rule_transformation[0]); + rules_list + .content + .shift_remove(content_rule_transformation[0]); rules_list.content.insert(rule); } } @@ -875,7 +877,7 @@ impl KeyValueDatabase { if let Some(rule) = rule { let mut rule = rule.clone(); rule.rule_id = transformation[1].to_owned(); - rules_list.underride.remove(transformation[0]); + rules_list.underride.shift_remove(transformation[0]); rules_list.underride.insert(rule); } } From 7fb9e99649786afbed97d31d2a26e68374e2b15d Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 29 Jan 2024 16:08:29 -0800 Subject: [PATCH 050/129] update ring and jsonwebtoken to remove ring ^0.16 --- Cargo.lock | 81 ++++++++++++++++++------------------------------------ Cargo.toml | 4 +-- 2 files changed, 28 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 81b270db..94a0c5e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,12 +190,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.7" @@ -383,7 +377,7 @@ dependencies = [ "async-trait", "axum", "axum-server", - "base64 0.21.7", + "base64", "bytes", "clap", "directories", @@ -405,7 +399,7 @@ dependencies = [ "rand", "regex", "reqwest", - "ring 0.16.20", + "ring", "rocksdb", "ruma", "rusqlite", @@ -860,8 +854,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -936,7 +932,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.21.7", + "base64", "bytes", "headers-core", "http", @@ -1210,13 +1206,14 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "8.3.0" +version = "9.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4" dependencies = [ - "base64 0.21.7", + "base64", + "js-sys", "pem", - "ring 0.16.20", + "ring", "serde", "serde_json", "simple_asn1", @@ -1684,11 +1681,12 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pem" -version = "1.1.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" dependencies = [ - "base64 0.13.1", + "base64", + "serde", ] [[package]] @@ -1949,7 +1947,7 @@ version = "0.11.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" dependencies = [ - "base64 0.21.7", + "base64", "bytes", "encoding_rs", "futures-core", @@ -1994,21 +1992,6 @@ dependencies = [ "quick-error", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.7" @@ -2018,8 +2001,8 @@ dependencies = [ "cc", "getrandom", "libc", - "spin 0.9.8", - "untrusted 0.9.0", + "spin", + "untrusted", "windows-sys 0.48.0", ] @@ -2088,7 +2071,7 @@ version = "0.11.3" source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" dependencies = [ "as_variant", - "base64 0.21.7", + "base64", "bytes", "form_urlencoded", "http", @@ -2195,7 +2178,7 @@ name = "ruma-signatures" version = "0.13.1" source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" dependencies = [ - "base64 0.21.7", + "base64", "ed25519-dalek", "pkcs8", "rand", @@ -2241,7 +2224,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5885493fdf0be6cdff808d1533ce878d21cfa49c7086fa00c66355cd9141bfc" dependencies = [ - "base64 0.21.7", + "base64", "blake2b_simd", "constant_time_eq", "crossbeam-utils", @@ -2275,7 +2258,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.17.7", + "ring", "rustls-webpki", "sct", ] @@ -2298,7 +2281,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.7", + "base64", ] [[package]] @@ -2307,8 +2290,8 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] @@ -2344,8 +2327,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", + "ring", + "untrusted", ] [[package]] @@ -2580,12 +2563,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spin" version = "0.9.8" @@ -3187,12 +3164,6 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 5292399a..c00d56a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,13 +73,13 @@ image = { version = "0.24.6", default-features = false, features = ["jpeg", "png # Used to encode server public key base64 = "0.21.2" # Used when hashing the state -ring = "0.16.20" +ring = "0.17.7" # Used when querying the SRV record of other servers trust-dns-resolver = "0.22.0" # Used to find matching events for appservices regex = "1.8.1" # jwt jsonwebtokens -jsonwebtoken = "8.3.0" +jsonwebtoken = "9.2.0" # Performance measurements tracing = { version = "0.1.37", features = [] } tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } From d6c57f9b2e55c16218728aaf52b6ceae7908a3aa Mon Sep 17 00:00:00 2001 From: Samuel Meenzen Date: Tue, 30 Jan 2024 17:04:47 +0000 Subject: [PATCH 051/129] Publish oci image to the gitlab registry --- .gitlab-ci.yml | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- DEPLOY.md | 4 ++-- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d4e49ce4..639319c5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,7 @@ stages: - ci - artifacts + - publish variables: # Makes some things print in color @@ -84,10 +85,10 @@ oci-image:x86_64-unknown-linux-gnu: - ./bin/nix-build-and-cache .#oci-image # Make the output less difficult to find - - cp result oci-image.tar.gz + - cp result oci-image-amd64.tar.gz artifacts: paths: - - oci-image.tar.gz + - oci-image-amd64.tar.gz oci-image:aarch64-unknown-linux-musl: stage: artifacts @@ -101,10 +102,10 @@ oci-image:aarch64-unknown-linux-musl: - ./bin/nix-build-and-cache .#oci-image-aarch64-unknown-linux-musl # Make the output less difficult to find - - cp result oci-image.tar.gz + - cp result oci-image-arm64v8.tar.gz artifacts: paths: - - oci-image.tar.gz + - oci-image-arm64v8.tar.gz debian:x86_64-unknown-linux-gnu: stage: artifacts @@ -125,3 +126,44 @@ debian:x86_64-unknown-linux-gnu: paths: - target - .gitlab-ci.d + +docker-publish: + stage: publish + image: docker:25.0.0 + services: + - docker:25.0.0-dind + variables: + IMAGE_NAME: $CI_REGISTRY_IMAGE/matrix-conduit + IMAGE_SUFFIX_AMD64: amd64 + IMAGE_SUFFIX_ARM64V8: arm64v8 + before_script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + script: + - docker load -i oci-image-amd64.tar.gz + - IMAGE_ID_AMD64=$(docker images -q conduit:next) + - docker load -i oci-image-arm64v8.tar.gz + - IMAGE_ID_ARM64V8=$(docker images -q conduit:next) + # Tag and push the architecture specific images + - docker tag $IMAGE_ID_AMD64 $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_AMD64 + - docker tag $IMAGE_ID_ARM64V8 $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_ARM64V8 + - docker push $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_AMD64 + - docker push $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_ARM64V8 + # Tag the multi-arch image + - docker manifest create $IMAGE_NAME:$CI_COMMIT_SHA --amend $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_AMD64 --amend $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_ARM64V8 + - docker manifest push $IMAGE_NAME:$CI_COMMIT_SHA + # Tag and push the git ref + - docker manifest create $IMAGE_NAME:$CI_COMMIT_REF_NAME --amend $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_AMD64 --amend $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_ARM64V8 + - docker manifest push $IMAGE_NAME:$CI_COMMIT_REF_NAME + # Tag git tags as 'latest' + - | + if [[ -n "$CI_COMMIT_TAG" ]]; then + docker manifest create $IMAGE_NAME:latest --amend $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_AMD64 --amend $IMAGE_NAME:$CI_COMMIT_SHA-$IMAGE_SUFFIX_ARM64V8 + docker manifest push $IMAGE_NAME:latest + fi + dependencies: + - oci-image:x86_64-unknown-linux-gnu + - oci-image:aarch64-unknown-linux-musl + only: + - next + - master + - tags diff --git a/DEPLOY.md b/DEPLOY.md index dcb1777d..c74fb3f0 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -37,8 +37,8 @@ If you use a system with an older glibc version (e.g. RHEL8), you might need to | `x86_64-unknown-linux-gnu` | Dynamically linked Debian package | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit.deb?job=debian:x86_64-unknown-linux-gnu) | | `x86_64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit?job=static:x86_64-unknown-linux-musl) | | `aarch64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit?job=static:aarch64-unknown-linux-musl) | -| `x86_64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image.tar.gz?job=oci-image:x86_64-unknown-linux-musl) | -| `aarch64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image.tar.gz?job=oci-image:aarch64-unknown-linux-musl) | +| `x86_64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-amd64.tar.gz?job=oci-image:x86_64-unknown-linux-musl) | +| `aarch64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-arm64v8.tar.gz?job=oci-image:aarch64-unknown-linux-musl) | ```bash $ sudo wget -O /usr/local/bin/matrix-conduit From 3a63f9dfb66f60fd9cc755de1aaea7b05687af26 Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Fri, 2 Feb 2024 03:50:49 +0100 Subject: [PATCH 052/129] feat: support non-flake users This uses flakes-compat to read the `flake.nix` and expose it to non-flake users. Signed-off-by: Raito Bezarius --- default.nix | 10 ++++++++++ flake.lock | 17 +++++++++++++++++ flake.nix | 4 ++++ 3 files changed, 31 insertions(+) create mode 100644 default.nix diff --git a/default.nix b/default.nix new file mode 100644 index 00000000..f620865d --- /dev/null +++ b/default.nix @@ -0,0 +1,10 @@ +(import + ( + let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in + fetchTarball { + url = lock.nodes.flake-compat.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; + sha256 = lock.nodes.flake-compat.locked.narHash; + } + ) + { src = ./.; } +).defaultNix diff --git a/flake.lock b/flake.lock index 85b0ab53..1c97e5c6 100644 --- a/flake.lock +++ b/flake.lock @@ -102,6 +102,22 @@ "type": "github" } }, + "flake-compat_2": { + "flake": false, + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, "flake-utils": { "locked": { "lastModified": 1667395993, @@ -203,6 +219,7 @@ "attic": "attic", "crane": "crane_2", "fenix": "fenix", + "flake-compat": "flake-compat_2", "flake-utils": "flake-utils_2", "nix-filter": "nix-filter", "nixpkgs": "nixpkgs_2" diff --git a/flake.nix b/flake.nix index e0bc6fbb..6ca4c72d 100644 --- a/flake.nix +++ b/flake.nix @@ -3,6 +3,10 @@ nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; nix-filter.url = "github:numtide/nix-filter"; + flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; + }; fenix = { url = "github:nix-community/fenix"; From a2ac491c5460da736c8872747aa3417a65c81a4e Mon Sep 17 00:00:00 2001 From: strawberry Date: Sat, 25 Nov 2023 12:42:05 -0500 Subject: [PATCH 053/129] bump ruma, add wrong room keys error code, tiny logging change can't update ruma to very latest commit because of the weird JsOption thing for syncv4 that i can't wrap my head around how to use, not important anyways Signed-off-by: strawberry --- Cargo.toml | 5 ++++- src/api/client_server/membership.rs | 6 +++--- src/api/client_server/room.rs | 2 +- src/service/admin/mod.rs | 2 +- src/service/rooms/spaces/mod.rs | 6 +++--- src/service/rooms/state_accessor/mod.rs | 10 ++++++++-- src/utils/error.rs | 8 +++++--- 7 files changed, 25 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c00d56a9..0fa69147 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ tower-http = { version = "0.4.1", features = ["add-extension", "cors", "sensitiv # 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 = "b4853aa8fa5e3a24e3689fc88044de9915f6ab67", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "5446ea979b314b90da1734f20efaff443d64f73d", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "4ec9c69bb7e09391add2382b3ebac97b6e8f4c64", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } @@ -116,6 +116,9 @@ async-trait = "0.1.68" sd-notify = { version = "0.4.1", optional = true } +# stupid ruma using JsOption instead of Option +js_option = "0.1" + [target.'cfg(unix)'.dependencies] nix = { version = "0.26.2", features = ["resource"] } diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index ed59691d..09f70a03 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -64,7 +64,7 @@ pub async fn join_room_by_id_route( .map(|user| user.server_name().to_owned()), ); - servers.push(body.room_id.server_name().to_owned()); + servers.push(body.room_id.server_name().unwrap().into()); join_room_by_id_helper( body.sender_user.as_deref(), @@ -105,7 +105,7 @@ pub async fn join_room_by_id_or_alias_route( .map(|user| user.server_name().to_owned()), ); - servers.push(room_id.server_name().to_owned()); + servers.push(room_id.server_name().unwrap().into()); (servers, room_id) } @@ -1366,7 +1366,7 @@ pub async fn leave_all_rooms(user_id: &UserId) -> 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() + && room_id.server_name() != Some(services().globals.server_name()) { if let Err(e) = remote_leave_room(user_id, room_id).await { warn!("Failed to leave room {} remotely: {}", user_id, e); diff --git a/src/api/client_server/room.rs b/src/api/client_server/room.rs index 0e2d9326..20409a28 100644 --- a/src/api/client_server/room.rs +++ b/src/api/client_server/room.rs @@ -366,7 +366,7 @@ pub async fn create_room_route( services().rooms.timeline.build_and_append_pdu( PduBuilder { event_type: TimelineEventType::RoomName, - content: to_raw_value(&RoomNameEventContent::new(Some(name.clone()))) + content: to_raw_value(&RoomNameEventContent::new(name.clone())) .expect("event is valid, we just created it"), unsigned: None, state_key: Some("".to_owned()), diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index 64958fc7..bd682550 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -1051,7 +1051,7 @@ impl Service { services().rooms.timeline.build_and_append_pdu( PduBuilder { event_type: TimelineEventType::RoomName, - content: to_raw_value(&RoomNameEventContent::new(Some(room_name))) + content: to_raw_value(&RoomNameEventContent::new(room_name)) .expect("event is valid, we just created it"), unsigned: None, state_key: Some("".to_owned()), diff --git a/src/service/rooms/spaces/mod.rs b/src/service/rooms/spaces/mod.rs index 615e9ca0..0e84221f 100644 --- a/src/service/rooms/spaces/mod.rs +++ b/src/service/rooms/spaces/mod.rs @@ -134,7 +134,7 @@ impl Service { if serde_json::from_str::(pdu.content.get()) .ok() - .and_then(|c| c.via) + .and_then(|c| Some(c.via)) .map_or(true, |v| v.is_empty()) { continue; @@ -185,7 +185,7 @@ impl Service { stack.push(children_ids); } } else { - let server = current_room.server_name(); + let server = current_room.server_name().unwrap(); if server == services().globals.server_name() { continue; } @@ -193,7 +193,7 @@ impl Service { // Early return so the client can see some data already break; } - warn!("Asking {server} for /hierarchy"); + debug!("Asking {server} for /hierarchy"); if let Ok(response) = services() .sending .send_federation_request( diff --git a/src/service/rooms/state_accessor/mod.rs b/src/service/rooms/state_accessor/mod.rs index b00dc58c..14c3bae7 100644 --- a/src/service/rooms/state_accessor/mod.rs +++ b/src/service/rooms/state_accessor/mod.rs @@ -279,8 +279,14 @@ impl Service { .room_state_get(room_id, &StateEventType::RoomName, "")? .map_or(Ok(None), |s| { serde_json::from_str(s.content.get()) - .map(|c: RoomNameEventContent| c.name) - .map_err(|_| Error::bad_database("Invalid room name event in database.")) + .map(|c: RoomNameEventContent| Some(c.name)) + .map_err(|e| { + error!( + "Invalid room name event in database for room {}. {}", + room_id, e + ); + Error::bad_database("Invalid room name event in database.") + }) }) } diff --git a/src/utils/error.rs b/src/utils/error.rs index 6e88cf59..765a31bb 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -116,9 +116,11 @@ impl Error { Self::BadRequest(kind, _) => ( kind.clone(), match kind { - Forbidden | GuestAccessForbidden | ThreepidAuthFailed | ThreepidDenied => { - StatusCode::FORBIDDEN - } + WrongRoomKeysVersion { .. } + | Forbidden + | GuestAccessForbidden + | ThreepidAuthFailed + | ThreepidDenied => StatusCode::FORBIDDEN, Unauthorized | UnknownToken { .. } | MissingToken => StatusCode::UNAUTHORIZED, NotFound | Unrecognized => StatusCode::NOT_FOUND, LimitExceeded { .. } => StatusCode::TOO_MANY_REQUESTS, From 6dcc8b6cf1dd8554c54e435132ee90a9a7353ca8 Mon Sep 17 00:00:00 2001 From: strawberry Date: Sun, 7 Jan 2024 21:21:13 -0500 Subject: [PATCH 054/129] bump ruma to latest commit (syncv3 JsOption and push optional power levels) Signed-off-by: strawberry --- Cargo.toml | 2 +- src/api/client_server/sync.rs | 18 ++++++++++++++---- src/service/pusher/mod.rs | 12 ++++++++---- src/service/rooms/state_accessor/mod.rs | 5 +++-- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0fa69147..03f0cd6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ tower-http = { version = "0.4.1", features = ["add-extension", "cors", "sensitiv # 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 = "5446ea979b314b90da1734f20efaff443d64f73d", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "9a5142052c808275f47613d4b66cb6c9fc286079", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "4ec9c69bb7e09391add2382b3ebac97b6e8f4c64", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 57572284..5e675297 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1614,12 +1614,22 @@ pub async fn sync_events_v4_route( rooms.insert( room_id.clone(), sync_events::v4::SlidingSyncRoom { - name: services().rooms.state_accessor.get_name(room_id)?.or(name), - avatar: services() + name: services() .rooms .state_accessor - .get_avatar(room_id)? - .map_or(avatar, |a| a.url), + .get_name(room_id)? + .or_else(|| name), + avatar: if let Some(avatar) = avatar { + ruma::JsOption::Some(avatar) + } else { + match services().rooms.state_accessor.get_avatar(room_id)? { + ruma::JsOption::Some(avatar) => { + js_option::JsOption::Some(avatar.url.unwrap()) + } + ruma::JsOption::Null => ruma::JsOption::Null, + ruma::JsOption::Undefined => ruma::JsOption::Undefined, + } + }, initial: Some(roomsince == &0), is_dm: None, invite_state: None, diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index 315c5ef0..418b7a8f 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -1,6 +1,6 @@ mod data; pub use data::Data; -use ruma::events::AnySyncTimelineEvent; +use ruma::{events::AnySyncTimelineEvent, push::PushConditionPowerLevelsCtx}; use crate::{services, Error, PduEvent, Result}; use bytes::BytesMut; @@ -193,6 +193,12 @@ impl Service { pdu: &Raw, room_id: &RoomId, ) -> Result<&'a [Action]> { + let power_levels = PushConditionPowerLevelsCtx { + users: power_levels.users.clone(), + users_default: power_levels.users_default, + notifications: power_levels.notifications.clone(), + }; + let ctx = PushConditionRoomCtx { room_id: room_id.to_owned(), member_count: 10_u32.into(), // TODO: get member count efficiently @@ -201,9 +207,7 @@ impl Service { .users .displayname(user)? .unwrap_or_else(|| user.localpart().to_owned()), - users_power_levels: power_levels.users.clone(), - default_power_level: power_levels.users_default, - notification_power_levels: power_levels.notifications.clone(), + power_levels: Some(power_levels), }; Ok(ruleset.get_actions(pdu, &ctx)) diff --git a/src/service/rooms/state_accessor/mod.rs b/src/service/rooms/state_accessor/mod.rs index 14c3bae7..f49d8a3c 100644 --- a/src/service/rooms/state_accessor/mod.rs +++ b/src/service/rooms/state_accessor/mod.rs @@ -5,6 +5,7 @@ use std::{ }; pub use data::Data; +use js_option::JsOption; use lru_cache::LruCache; use ruma::{ events::{ @@ -290,12 +291,12 @@ impl Service { }) } - pub fn get_avatar(&self, room_id: &RoomId) -> Result> { + pub fn get_avatar(&self, room_id: &RoomId) -> Result> { services() .rooms .state_accessor .room_state_get(room_id, &StateEventType::RoomAvatar, "")? - .map_or(Ok(None), |s| { + .map_or(Ok(JsOption::Undefined), |s| { serde_json::from_str(s.content.get()) .map_err(|_| Error::bad_database("Invalid room avatar event in database.")) }) From e7070843456bf259e395b98c60f9b185eb75e86b Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Fri, 16 Feb 2024 20:52:07 +0000 Subject: [PATCH 055/129] chore: bump ruma to latest commit (as of 2024-02-16) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 03f0cd6f..0cf062f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ tower-http = { version = "0.4.1", features = ["add-extension", "cors", "sensitiv # 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 = "9a5142052c808275f47613d4b66cb6c9fc286079", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "f1a8497ecb0cc24b0159f301336a3bf3896d476e", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "4ec9c69bb7e09391add2382b3ebac97b6e8f4c64", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } From d841b81c56ab24210e966201258c6f7b9438340a Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Fri, 16 Feb 2024 20:52:19 +0000 Subject: [PATCH 056/129] chore: update Cargo.lock --- Cargo.lock | 79 +++++++++++++++++++++++------------------------------- 1 file changed, 33 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94a0c5e3..fc17fda3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -387,6 +387,7 @@ dependencies = [ "http", "hyper", "image", + "js_option", "jsonwebtoken", "lazy_static", "lru-cache", @@ -708,7 +709,7 @@ dependencies = [ "atomic", "pear", "serde", - "toml 0.8.8", + "toml", "uncased", "version_check", ] @@ -1802,12 +1803,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "toml_edit 0.20.7", ] [[package]] @@ -2018,8 +2018,8 @@ dependencies = [ [[package]] name = "ruma" -version = "0.8.2" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.9.4" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "assign", "js_int", @@ -2037,8 +2037,8 @@ dependencies = [ [[package]] name = "ruma-appservice-api" -version = "0.8.1" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.9.0" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "js_int", "ruma-common", @@ -2049,9 +2049,10 @@ dependencies = [ [[package]] name = "ruma-client-api" -version = "0.16.2" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.17.4" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ + "as_variant", "assign", "bytes", "http", @@ -2067,8 +2068,8 @@ dependencies = [ [[package]] name = "ruma-common" -version = "0.11.3" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.12.1" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "as_variant", "base64", @@ -2095,8 +2096,8 @@ dependencies = [ [[package]] name = "ruma-events" -version = "0.26.0" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.27.11" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "as_variant", "indexmap 2.2.1", @@ -2117,8 +2118,8 @@ dependencies = [ [[package]] name = "ruma-federation-api" -version = "0.7.1" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.8.0" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "js_int", "ruma-common", @@ -2129,8 +2130,8 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" -version = "0.9.1" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.9.3" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "js_int", "thiserror", @@ -2138,8 +2139,8 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" -version = "0.7.1" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.8.0" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "js_int", "ruma-common", @@ -2148,8 +2149,8 @@ dependencies = [ [[package]] name = "ruma-macros" -version = "0.11.3" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.12.0" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "once_cell", "proc-macro-crate", @@ -2158,13 +2159,13 @@ dependencies = [ "ruma-identifiers-validation", "serde", "syn 2.0.48", - "toml 0.7.8", + "toml", ] [[package]] name = "ruma-push-gateway-api" -version = "0.7.1" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.8.0" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "js_int", "ruma-common", @@ -2175,8 +2176,8 @@ dependencies = [ [[package]] name = "ruma-signatures" -version = "0.13.1" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.14.0" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "base64", "ed25519-dalek", @@ -2191,8 +2192,8 @@ dependencies = [ [[package]] name = "ruma-state-res" -version = "0.9.1" -source = "git+https://github.com/ruma/ruma?rev=b4853aa8fa5e3a24e3689fc88044de9915f6ab67#b4853aa8fa5e3a24e3689fc88044de9915f6ab67" +version = "0.10.0" +source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" dependencies = [ "itertools", "js_int", @@ -2846,18 +2847,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.19.15", -] - [[package]] name = "toml" version = "0.8.8" @@ -2881,13 +2870,11 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ "indexmap 2.2.1", - "serde", - "serde_spanned", "toml_datetime", "winnow", ] From 4c06f329c4d2f5128d6293de9bb0342559422746 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Fri, 16 Feb 2024 21:13:59 +0000 Subject: [PATCH 057/129] refactor: appease clippy --- src/api/client_server/sync.rs | 2 +- src/service/rooms/event_handler/mod.rs | 13 ++++++++++--- src/service/rooms/spaces/mod.rs | 3 +-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 5e675297..490a947b 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1618,7 +1618,7 @@ pub async fn sync_events_v4_route( .rooms .state_accessor .get_name(room_id)? - .or_else(|| name), + .or(name), avatar: if let Some(avatar) = avatar { ruma::JsOption::Some(avatar) } else { diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index e7db6f78..375d1ff0 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -966,14 +966,21 @@ impl Service { debug!("Resolving state"); - let lock = services().globals.stateres_mutex.lock(); - let state = match state_res::resolve(room_version_id, &fork_states, auth_chain_sets, |id| { + let fetch_event = |id: &_| { let res = services().rooms.timeline.get_pdu(id); if let Err(e) = &res { error!("LOOK AT ME Failed to fetch event: {}", e); } res.ok().flatten() - }) { + }; + + let lock = services().globals.stateres_mutex.lock(); + let state = match state_res::resolve( + room_version_id, + &fork_states, + auth_chain_sets, + fetch_event, + ) { Ok(new_state) => new_state, Err(_) => { return Err(Error::bad_database("State resolution failed, either an event could not be found or deserialization")); diff --git a/src/service/rooms/spaces/mod.rs b/src/service/rooms/spaces/mod.rs index 0e84221f..90523667 100644 --- a/src/service/rooms/spaces/mod.rs +++ b/src/service/rooms/spaces/mod.rs @@ -133,8 +133,7 @@ impl Service { .ok_or_else(|| Error::bad_database("Event in space state not found"))?; if serde_json::from_str::(pdu.content.get()) - .ok() - .and_then(|c| Some(c.via)) + .ok().map(|c| c.via) .map_or(true, |v| v.is_empty()) { continue; From 976a73a0e5e9aa7fc880a39f6478ec13943e2d3c Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Fri, 16 Feb 2024 21:19:40 +0000 Subject: [PATCH 058/129] style: appease rustfmt --- src/api/client_server/sync.rs | 6 +----- src/service/rooms/spaces/mod.rs | 3 ++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 490a947b..86b3b248 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1614,11 +1614,7 @@ pub async fn sync_events_v4_route( rooms.insert( room_id.clone(), sync_events::v4::SlidingSyncRoom { - name: services() - .rooms - .state_accessor - .get_name(room_id)? - .or(name), + name: services().rooms.state_accessor.get_name(room_id)?.or(name), avatar: if let Some(avatar) = avatar { ruma::JsOption::Some(avatar) } else { diff --git a/src/service/rooms/spaces/mod.rs b/src/service/rooms/spaces/mod.rs index 90523667..07d576a9 100644 --- a/src/service/rooms/spaces/mod.rs +++ b/src/service/rooms/spaces/mod.rs @@ -133,7 +133,8 @@ impl Service { .ok_or_else(|| Error::bad_database("Event in space state not found"))?; if serde_json::from_str::(pdu.content.get()) - .ok().map(|c| c.via) + .ok() + .map(|c| c.via) .map_or(true, |v| v.is_empty()) { continue; From 1c6a4b1b24c92e8fc4132c453fffab66d922dc71 Mon Sep 17 00:00:00 2001 From: Samuel Meenzen Date: Sun, 18 Feb 2024 01:36:50 +0000 Subject: [PATCH 059/129] feat(ci): push oci-image to docker hub --- .gitlab-ci.yml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 639319c5..4f4aa695 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -127,17 +127,14 @@ debian:x86_64-unknown-linux-gnu: - target - .gitlab-ci.d -docker-publish: +.push-oci-image: stage: publish image: docker:25.0.0 services: - docker:25.0.0-dind variables: - IMAGE_NAME: $CI_REGISTRY_IMAGE/matrix-conduit IMAGE_SUFFIX_AMD64: amd64 IMAGE_SUFFIX_ARM64V8: arm64v8 - before_script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker load -i oci-image-amd64.tar.gz - IMAGE_ID_AMD64=$(docker images -q conduit:next) @@ -167,3 +164,17 @@ docker-publish: - next - master - tags + +oci-image:push-gitlab: + extends: .push-oci-image + variables: + IMAGE_NAME: $CI_REGISTRY_IMAGE/matrix-conduit + before_script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + +oci-image:push-dockerhub: + extends: .push-oci-image + variables: + IMAGE_NAME: matrixconduit/matrix-conduit + before_script: + - docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_PASSWORD \ No newline at end of file From ace9637bc299df4c59efbeb3e1c432b239b7a165 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Fri, 23 Feb 2024 19:39:30 +0000 Subject: [PATCH 060/129] replace unwraps with expects --- src/api/client_server/membership.rs | 14 ++++++++++++-- src/api/client_server/sync.rs | 2 +- src/service/rooms/spaces/mod.rs | 4 +++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 09f70a03..5c78a1c2 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -64,7 +64,12 @@ pub async fn join_room_by_id_route( .map(|user| user.server_name().to_owned()), ); - servers.push(body.room_id.server_name().unwrap().into()); + servers.push( + body.room_id + .server_name() + .expect("Room IDs should always have a server name") + .into(), + ); join_room_by_id_helper( body.sender_user.as_deref(), @@ -105,7 +110,12 @@ pub async fn join_room_by_id_or_alias_route( .map(|user| user.server_name().to_owned()), ); - servers.push(room_id.server_name().unwrap().into()); + servers.push( + room_id + .server_name() + .expect("Room IDs should always have a server name") + .into(), + ); (servers, room_id) } diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 86b3b248..600a9737 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1620,7 +1620,7 @@ pub async fn sync_events_v4_route( } else { match services().rooms.state_accessor.get_avatar(room_id)? { ruma::JsOption::Some(avatar) => { - js_option::JsOption::Some(avatar.url.unwrap()) + js_option::JsOption::from_option(avatar.url) } ruma::JsOption::Null => ruma::JsOption::Null, ruma::JsOption::Undefined => ruma::JsOption::Undefined, diff --git a/src/service/rooms/spaces/mod.rs b/src/service/rooms/spaces/mod.rs index 07d576a9..b0a9ed2a 100644 --- a/src/service/rooms/spaces/mod.rs +++ b/src/service/rooms/spaces/mod.rs @@ -185,7 +185,9 @@ impl Service { stack.push(children_ids); } } else { - let server = current_room.server_name().unwrap(); + let server = current_room + .server_name() + .expect("Room IDs should always have a server name"); if server == services().globals.server_name() { continue; } From 8aa915acb90552398530cc20efa1c71f788da9f6 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Fri, 23 Feb 2024 20:29:17 +0000 Subject: [PATCH 061/129] bump ruma, support deprecated user login field --- Cargo.lock | 24 ++++++++--------- Cargo.toml | 2 +- src/api/client_server/session.rs | 45 ++++++++++++++++++++------------ 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fc17fda3..e20c3f0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2019,7 +2019,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.9.4" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "assign", "js_int", @@ -2038,7 +2038,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "js_int", "ruma-common", @@ -2050,7 +2050,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.17.4" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "as_variant", "assign", @@ -2069,7 +2069,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.12.1" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "as_variant", "base64", @@ -2097,7 +2097,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.27.11" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "as_variant", "indexmap 2.2.1", @@ -2119,7 +2119,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "js_int", "ruma-common", @@ -2131,7 +2131,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.3" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "js_int", "thiserror", @@ -2140,7 +2140,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "js_int", "ruma-common", @@ -2150,7 +2150,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.12.0" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "once_cell", "proc-macro-crate", @@ -2165,7 +2165,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "js_int", "ruma-common", @@ -2177,7 +2177,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.14.0" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "base64", "ed25519-dalek", @@ -2193,7 +2193,7 @@ dependencies = [ [[package]] name = "ruma-state-res" version = "0.10.0" -source = "git+https://github.com/ruma/ruma?rev=f1a8497ecb0cc24b0159f301336a3bf3896d476e#f1a8497ecb0cc24b0159f301336a3bf3896d476e" +source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" dependencies = [ "itertools", "js_int", diff --git a/Cargo.toml b/Cargo.toml index 0cf062f6..4bc9ad5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ tower-http = { version = "0.4.1", features = ["add-extension", "cors", "sensitiv # 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 = "f1a8497ecb0cc24b0159f301336a3bf3896d476e", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "4ec9c69bb7e09391add2382b3ebac97b6e8f4c64", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } diff --git a/src/api/client_server/session.rs b/src/api/client_server/session.rs index c17bd99b..23f0b457 100644 --- a/src/api/client_server/session.rs +++ b/src/api/client_server/session.rs @@ -42,24 +42,31 @@ 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 { + // To allow deprecated login methods + #![allow(deprecated)] // Validate login method // TODO: Other login methods let user_id = match &body.login_info { login::v3::LoginInfo::Password(login::v3::Password { identifier, password, + user, + address: _, + medium: _, }) => { - let username = if let UserIdentifier::UserIdOrLocalpart(user_id) = identifier { - user_id.to_lowercase() + let user_id = if let Some(UserIdentifier::UserIdOrLocalpart(user_id)) = identifier { + UserId::parse_with_server_name( + user_id.to_lowercase(), + services().globals.server_name(), + ) + } else if let Some(user) = user { + UserId::parse(user) } else { warn!("Bad login type: {:?}", &body.login_info); return Err(Error::BadRequest(ErrorKind::Forbidden, "Bad login type.")); - }; - let user_id = - UserId::parse_with_server_name(username, services().globals.server_name()) - .map_err(|_| { - Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid.") - })?; + } + .map_err(|_| Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid."))?; + let hash = services() .users .password_hash(&user_id)? @@ -105,22 +112,28 @@ pub async fn login_route(body: Ruma) -> Result { + login::v3::LoginInfo::ApplicationService(login::v3::ApplicationService { + identifier, + user, + }) => { if !body.from_appservice { return Err(Error::BadRequest( ErrorKind::Forbidden, "Forbidden login type.", )); }; - let username = if let UserIdentifier::UserIdOrLocalpart(user_id) = identifier { - user_id.to_lowercase() + if let Some(UserIdentifier::UserIdOrLocalpart(user_id)) = identifier { + UserId::parse_with_server_name( + user_id.to_lowercase(), + services().globals.server_name(), + ) + } else if let Some(user) = user { + UserId::parse(user) } else { + warn!("Bad login type: {:?}", &body.login_info); return Err(Error::BadRequest(ErrorKind::Forbidden, "Bad login type.")); - }; - - UserId::parse_with_server_name(username, services().globals.server_name()).map_err( - |_| Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid."), - )? + } + .map_err(|_| Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid."))? } _ => { warn!("Unsupported or unknown login type: {:?}", &body.login_info); From b27e9ea95cdddce51eca99f0fd003de131c23556 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sun, 25 Feb 2024 08:49:20 +0000 Subject: [PATCH 062/129] chore: bump ruma to latest commit (as of 2024-02-25) --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e20c3f0b..78e85266 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2019,7 +2019,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.9.4" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "assign", "js_int", @@ -2038,7 +2038,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "js_int", "ruma-common", @@ -2050,7 +2050,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.17.4" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "as_variant", "assign", @@ -2069,7 +2069,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.12.1" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "as_variant", "base64", @@ -2097,7 +2097,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.27.11" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "as_variant", "indexmap 2.2.1", @@ -2119,7 +2119,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "js_int", "ruma-common", @@ -2131,7 +2131,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.3" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "js_int", "thiserror", @@ -2140,7 +2140,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "js_int", "ruma-common", @@ -2150,7 +2150,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.12.0" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "once_cell", "proc-macro-crate", @@ -2165,7 +2165,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "js_int", "ruma-common", @@ -2177,7 +2177,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.14.0" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "base64", "ed25519-dalek", @@ -2193,7 +2193,7 @@ dependencies = [ [[package]] name = "ruma-state-res" version = "0.10.0" -source = "git+https://github.com/ruma/ruma?rev=abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3#abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3" +source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "itertools", "js_int", diff --git a/Cargo.toml b/Cargo.toml index 4bc9ad5a..4f873cff 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ tower-http = { version = "0.4.1", features = ["add-extension", "cors", "sensitiv # 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 = "abebde0cf1cbf3eb1cf8295b240c5d3f926da3a3", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "1a1c61ee1e8f0936e956a3b69c931ce12ee28475", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "4ec9c69bb7e09391add2382b3ebac97b6e8f4c64", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } From 21a5fa3ef0ccb1ad9ae9ea6328146e6dd69e4d78 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sun, 25 Feb 2024 10:30:30 +0000 Subject: [PATCH 063/129] refactor: use re-exported JsOption from ruma rather than directly adding it as a dependency --- Cargo.lock | 1 - Cargo.toml | 3 --- src/api/client_server/sync.rs | 12 +++++------- src/service/rooms/state_accessor/mod.rs | 3 +-- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78e85266..e99928e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -387,7 +387,6 @@ dependencies = [ "http", "hyper", "image", - "js_option", "jsonwebtoken", "lazy_static", "lru-cache", diff --git a/Cargo.toml b/Cargo.toml index 4f873cff..e8c1c8bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -116,9 +116,6 @@ async-trait = "0.1.68" sd-notify = { version = "0.4.1", optional = true } -# stupid ruma using JsOption instead of Option -js_option = "0.1" - [target.'cfg(unix)'.dependencies] nix = { version = "0.26.2", features = ["resource"] } diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 600a9737..04fdb2bb 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -20,7 +20,7 @@ use ruma::{ StateEventType, TimelineEventType, }, serde::Raw, - uint, DeviceId, OwnedDeviceId, OwnedUserId, RoomId, UInt, UserId, + uint, DeviceId, JsOption, OwnedDeviceId, OwnedUserId, RoomId, UInt, UserId, }; use std::{ collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet}, @@ -1616,14 +1616,12 @@ pub async fn sync_events_v4_route( sync_events::v4::SlidingSyncRoom { name: services().rooms.state_accessor.get_name(room_id)?.or(name), avatar: if let Some(avatar) = avatar { - ruma::JsOption::Some(avatar) + JsOption::Some(avatar) } else { match services().rooms.state_accessor.get_avatar(room_id)? { - ruma::JsOption::Some(avatar) => { - js_option::JsOption::from_option(avatar.url) - } - ruma::JsOption::Null => ruma::JsOption::Null, - ruma::JsOption::Undefined => ruma::JsOption::Undefined, + JsOption::Some(avatar) => JsOption::from_option(avatar.url), + JsOption::Null => JsOption::Null, + JsOption::Undefined => JsOption::Undefined, } }, initial: Some(roomsince == &0), diff --git a/src/service/rooms/state_accessor/mod.rs b/src/service/rooms/state_accessor/mod.rs index f49d8a3c..903ad47b 100644 --- a/src/service/rooms/state_accessor/mod.rs +++ b/src/service/rooms/state_accessor/mod.rs @@ -5,7 +5,6 @@ use std::{ }; pub use data::Data; -use js_option::JsOption; use lru_cache::LruCache; use ruma::{ events::{ @@ -17,7 +16,7 @@ use ruma::{ }, StateEventType, }, - EventId, OwnedServerName, OwnedUserId, RoomId, ServerName, UserId, + EventId, JsOption, OwnedServerName, OwnedUserId, RoomId, ServerName, UserId, }; use tracing::error; From f4e57fdb225e8bf87608dce62b759755b74c8393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Thu, 1 Feb 2024 12:05:59 +0100 Subject: [PATCH 064/129] Avoid federation when it is not necessary --- src/api/server_server.rs | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/api/server_server.rs b/src/api/server_server.rs index db17d586..1ba2edc0 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -1799,6 +1799,13 @@ pub async fn get_devices_route( return Err(Error::bad_config("Federation is disabled.")); } + if body.user_id.server_name() != services().globals.server_name() { + return Err(Error::BadRequest( + ErrorKind::InvalidParam, + "Tried to access user from other server.", + )); + } + let sender_servername = body .sender_servername .as_ref() @@ -1873,6 +1880,13 @@ pub async fn get_profile_information_route( return Err(Error::bad_config("Federation is disabled.")); } + if body.user_id.server_name() != services().globals.server_name() { + return Err(Error::BadRequest( + ErrorKind::InvalidParam, + "Tried to access user from other server.", + )); + } + let mut displayname = None; let mut avatar_url = None; let mut blurhash = None; @@ -1909,6 +1923,17 @@ pub async fn get_keys_route(body: Ruma) -> Result Date: Wed, 28 Feb 2024 16:24:26 +0100 Subject: [PATCH 065/129] fix: avoid panic when client is confused about rooms --- src/api/client_server/sync.rs | 3 +++ src/database/key_value/rooms/timeline.rs | 2 +- src/service/rooms/event_handler/mod.rs | 17 ++++++++++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 57572284..eefdffa2 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1476,6 +1476,9 @@ pub async fn sync_events_v4_route( let mut known_subscription_rooms = BTreeSet::new(); for (room_id, room) in &body.room_subscriptions { + if !services().rooms.metadata.exists(room_id)? { + continue; + } let todo_room = todo_rooms .entry(room_id.clone()) .or_insert((BTreeSet::new(), 0, u64::MAX)); diff --git a/src/database/key_value/rooms/timeline.rs b/src/database/key_value/rooms/timeline.rs index f322d430..0331a624 100644 --- a/src/database/key_value/rooms/timeline.rs +++ b/src/database/key_value/rooms/timeline.rs @@ -331,7 +331,7 @@ fn count_to_id( .rooms .short .get_shortroomid(room_id)? - .expect("room exists") + .ok_or_else(|| Error::bad_database("Looked for bad shortroomid in timeline"))? .to_be_bytes() .to_vec(); let mut pdu_id = prefix.clone(); diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index e7db6f78..4debc607 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -184,7 +184,22 @@ impl Service { } if errors >= 5 { - break; + // Timeout other events + match services() + .globals + .bad_event_ratelimiter + .write() + .unwrap() + .entry((*prev_id).to_owned()) + { + hash_map::Entry::Vacant(e) => { + e.insert((Instant::now(), 1)); + } + hash_map::Entry::Occupied(mut e) => { + *e.get_mut() = (Instant::now(), e.get().1 + 1) + } + } + continue; } if let Some((pdu, json)) = eventid_info.remove(&*prev_id) { From 726b6f0fa64bfbb13953366256e52052912cab96 Mon Sep 17 00:00:00 2001 From: olly1240 Date: Tue, 24 Oct 2023 11:56:49 +0000 Subject: [PATCH 066/129] Fixed nginx proxy_pass directive --- DEPLOY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPLOY.md b/DEPLOY.md index c74fb3f0..dcc41bdc 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -279,7 +279,7 @@ server { client_max_body_size 20M; location /_matrix/ { - proxy_pass http://127.0.0.1:6167$request_uri; + proxy_pass http://127.0.0.1:6167; proxy_set_header Host $http_host; proxy_buffering off; proxy_read_timeout 5m; From 62dda7a43f2797200d08f72078267892887fd135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Thu, 29 Feb 2024 10:28:06 +0100 Subject: [PATCH 067/129] improvement: delete old rocksdb LOG files --- src/database/abstraction/rocksdb.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/database/abstraction/rocksdb.rs b/src/database/abstraction/rocksdb.rs index b40c4393..7a93d787 100644 --- a/src/database/abstraction/rocksdb.rs +++ b/src/database/abstraction/rocksdb.rs @@ -49,6 +49,9 @@ fn db_options(max_open_files: i32, rocksdb_cache: &rocksdb::Cache) -> rocksdb::O db_opts.set_max_background_jobs(6); db_opts.set_bytes_per_sync(1048576); + // https://github.com/facebook/rocksdb/issues/849 + db_opts.set_keep_log_file_num(100); + // https://github.com/facebook/rocksdb/wiki/WAL-Recovery-Modes#ktoleratecorruptedtailrecords // // Unclean shutdowns of a Matrix homeserver are likely to be fine when From a159fff08aa07d9aa865bb03acbcdaec8cde5c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Thu, 29 Feb 2024 10:28:38 +0100 Subject: [PATCH 068/129] improvement: deactivate old presence code because it slows down sync The problem is that for each sync, it creates a new rocksdb iterator for each room, and creating iterators is somewhat expensive --- src/service/rooms/edus/presence/mod.rs | 37 ++++++++++++++------------ 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/service/rooms/edus/presence/mod.rs b/src/service/rooms/edus/presence/mod.rs index 860aea18..4b929d28 100644 --- a/src/service/rooms/edus/presence/mod.rs +++ b/src/service/rooms/edus/presence/mod.rs @@ -17,29 +17,32 @@ impl Service { /// make sure users outside these rooms can't see them. pub fn update_presence( &self, - user_id: &UserId, - room_id: &RoomId, - presence: PresenceEvent, + _user_id: &UserId, + _room_id: &RoomId, + _presence: PresenceEvent, ) -> Result<()> { - self.db.update_presence(user_id, room_id, presence) + // self.db.update_presence(user_id, room_id, presence) + Ok(()) } /// Resets the presence timeout, so the user will stay in their current presence state. - pub fn ping_presence(&self, user_id: &UserId) -> Result<()> { - self.db.ping_presence(user_id) + pub fn ping_presence(&self, _user_id: &UserId) -> Result<()> { + // self.db.ping_presence(user_id) + Ok(()) } pub fn get_last_presence_event( &self, - user_id: &UserId, - room_id: &RoomId, + _user_id: &UserId, + _room_id: &RoomId, ) -> Result> { - let last_update = match self.db.last_presence_update(user_id)? { - Some(last) => last, - None => return Ok(None), - }; + // let last_update = match self.db.last_presence_update(user_id)? { + // Some(last) => last, + // None => return Ok(None), + // }; - self.db.get_presence_event(room_id, user_id, last_update) + // self.db.get_presence_event(room_id, user_id, last_update) + Ok(None) } /* TODO @@ -111,12 +114,12 @@ impl Service { }*/ /// Returns the most recent presence updates that happened after the event with id `since`. - #[tracing::instrument(skip(self, since, room_id))] pub fn presence_since( &self, - room_id: &RoomId, - since: u64, + _room_id: &RoomId, + _since: u64, ) -> Result> { - self.db.presence_since(room_id, since) + // self.db.presence_since(room_id, since) + Ok(HashMap::new()) } } From e06e15d4ec614d284d494bac795299f05e5711fb Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sun, 3 Mar 2024 11:26:18 +0000 Subject: [PATCH 069/129] fix(accounts): don't give guests admin --- src/api/client_server/account.rs | 29 +++++++++++++-------- src/service/admin/mod.rs | 42 +++++++++++++++---------------- src/service/rooms/timeline/mod.rs | 20 ++++----------- 3 files changed, 44 insertions(+), 47 deletions(-) diff --git a/src/api/client_server/account.rs b/src/api/client_server/account.rs index 46551305..3a791215 100644 --- a/src/api/client_server/account.rs +++ b/src/api/client_server/account.rs @@ -149,17 +149,18 @@ pub async fn register_route(body: Ruma) -> Result) -> Result| { services() @@ -1105,6 +1095,24 @@ impl Service { Ok(()) } + /// Gets the room ID of the admin room + /// + /// If the room does not exist, this function panics, since it should have been created on first run + // ^ was the case before this function when the following code was re-used in multiple places + pub(crate) fn get_admin_room(&self) -> OwnedRoomId { + let admin_room_alias: Box = + format!("#admins:{}", services().globals.server_name()) + .try_into() + .expect("#admins:server_name is a valid alias name"); + + services() + .rooms + .alias + .resolve_local_alias(&admin_room_alias) + .expect("Room ID should be valid unicode, since this server created it") + .expect("Admin room must exist") + } + /// Invite the user to the conduit admin room. /// /// In conduit, this is equivalent to granting admin privileges. @@ -1113,15 +1121,7 @@ impl Service { user_id: &UserId, displayname: String, ) -> Result<()> { - let admin_room_alias: Box = - format!("#admins:{}", services().globals.server_name()) - .try_into() - .expect("#admins:server_name is a valid alias name"); - let room_id = services() - .rooms - .alias - .resolve_local_alias(&admin_room_alias)? - .expect("Admin room must exist"); + let room_id = services().admin.get_admin_room(); let mutex_state = Arc::clone( services() diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index ef09d061..13193e52 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -28,7 +28,7 @@ use ruma::{ state_res, state_res::{Event, RoomVersion}, uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, - OwnedServerName, RoomAliasId, RoomId, ServerName, UserId, + OwnedServerName, RoomId, ServerName, UserId, }; use serde::Deserialize; use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; @@ -448,12 +448,7 @@ impl Service { .search .index_pdu(shortroomid, &pdu_id, &body)?; - 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"), - )?; + let admin_room = services().admin.get_admin_room(); let server_user = format!("@conduit:{}", services().globals.server_name()); let to_conduit = body.starts_with(&format!("{server_user}: ")) @@ -466,7 +461,7 @@ impl Service { let from_conduit = pdu.sender == server_user && services().globals.emergency_password().is_none(); - if to_conduit && !from_conduit && admin_room.as_ref() == Some(&pdu.room_id) { + if to_conduit && !from_conduit && admin_room == pdu.room_id { services().admin.process_message(body); } } @@ -820,13 +815,8 @@ 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() { + let admin_room = services().admin.get_admin_room(); + if admin_room == room_id { match pdu.event_type() { TimelineEventType::RoomEncryption => { warn!("Encryption is not allowed in the admins room"); From 56a57d5489978a6b7a0a016a52e0a4a3347e687f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Sun, 3 Mar 2024 15:55:34 +0100 Subject: [PATCH 070/129] docs: small fixes for the README --- README.md | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 5e01c8c1..bf7bde5e 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,6 @@ There are still a few important features missing: - 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). - #### How can I deploy my own? - Simple install (this was tested the most): [DEPLOY.md](DEPLOY.md) @@ -44,13 +42,21 @@ If you want to connect an Appservice to Conduit, take a look at [APPSERVICES.md] #### How can I contribute? -1. Look for an issue you would like to work on and make sure it's not assigned - to other users -2. Ask someone to assign the issue to you (comment on the issue or chat in - [#conduit:fachschaften.org](https://matrix.to/#/#conduit:fachschaften.org)) -3. Fork the repo and work on the issue.[#conduit:fachschaften.org](https://matrix.to/#/#conduit:fachschaften.org) is happy to help :) +1. Look for an issue you would like to work on and make sure no one else is currently working on it. +2. Tell us that you are working on the issue (comment on the issue or chat in + [#conduit:fachschaften.org](https://matrix.to/#/#conduit:fachschaften.org)). If it is more complicated, please explain your approach and ask questions. +3. Fork the repo, create a new branch and push commits. 4. Submit a MR +#### Contact + +If you have any questions, feel free to +- Ask in `#conduit:fachschaften.org` on Matrix +- Write an E-Mail to `conduit@koesters.xyz` +- Send an direct message to `@timokoesters:fachschaften.org` on Matrix +- [Open an issue on GitLab](https://gitlab.com/famedly/conduit/-/issues/new) + + #### Thanks to Thanks to FUTO, Famedly, Prototype Fund (DLR and German BMBF) and all individuals for financially supporting this project. @@ -60,14 +66,6 @@ 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 `timokoesters@fachschaften.org` on Matrix -- [Open an issue on GitLab](https://gitlab.com/famedly/conduit/-/issues/new) - #### Donate Liberapay: \ From da5975d7271a717b2f788931771b879d0ea78bd9 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sun, 3 Mar 2024 22:42:24 +0000 Subject: [PATCH 071/129] fix: avoid panics when admin room is not available --- src/api/client_server/account.rs | 50 +++--- src/service/admin/mod.rs | 276 +++++++++++++++--------------- src/service/rooms/timeline/mod.rs | 148 ++++++++-------- 3 files changed, 239 insertions(+), 235 deletions(-) diff --git a/src/api/client_server/account.rs b/src/api/client_server/account.rs index 3a791215..d4529a40 100644 --- a/src/api/client_server/account.rs +++ b/src/api/client_server/account.rs @@ -149,18 +149,17 @@ pub async fn register_route(body: Ruma) -> Result) -> Result| { - services() - .rooms - .timeline - .build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMessage, - content: to_raw_value(&message) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: None, - redacts: None, - }, - &conduit_user, - &conduit_room, - mutex_lock, - ) - .unwrap(); - }; - - loop { - tokio::select! { - Some(event) = receiver.recv() => { - let message_content = match event { - AdminRoomEvent::SendMessage(content) => content, - AdminRoomEvent::ProcessMessage(room_message) => self.process_admin_message(room_message).await - }; - - let mutex_state = Arc::clone( - services().globals - .roomid_mutex_state - .write() - .unwrap() - .entry(conduit_room.to_owned()) - .or_default(), - ); - - let state_lock = mutex_state.lock().await; - - send_message(message_content, &state_lock); - - drop(state_lock); + if let Ok(Some(conduit_room)) = services().admin.get_admin_room() { + let send_message = |message: RoomMessageEventContent, + mutex_lock: &MutexGuard<'_, ()>| { + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMessage, + content: to_raw_value(&message) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: None, + redacts: None, + }, + &conduit_user, + &conduit_room, + mutex_lock, + ) + .unwrap(); + }; + + loop { + tokio::select! { + Some(event) = receiver.recv() => { + let message_content = match event { + AdminRoomEvent::SendMessage(content) => content, + AdminRoomEvent::ProcessMessage(room_message) => self.process_admin_message(room_message).await + }; + + let mutex_state = Arc::clone( + services().globals + .roomid_mutex_state + .write() + .unwrap() + .entry(conduit_room.to_owned()) + .or_default(), + ); + + let state_lock = mutex_state.lock().await; + + send_message(message_content, &state_lock); + + drop(state_lock); + } } } } @@ -1097,9 +1098,8 @@ impl Service { /// Gets the room ID of the admin room /// - /// If the room does not exist, this function panics, since it should have been created on first run - // ^ was the case before this function when the following code was re-used in multiple places - pub(crate) fn get_admin_room(&self) -> OwnedRoomId { + /// Errors are propagated from the database, and will have None if there is no admin room + pub(crate) fn get_admin_room(&self) -> Result> { let admin_room_alias: Box = format!("#admins:{}", services().globals.server_name()) .try_into() @@ -1109,8 +1109,6 @@ impl Service { .rooms .alias .resolve_local_alias(&admin_room_alias) - .expect("Room ID should be valid unicode, since this server created it") - .expect("Admin room must exist") } /// Invite the user to the conduit admin room. @@ -1121,94 +1119,93 @@ impl Service { user_id: &UserId, displayname: String, ) -> Result<()> { - let room_id = services().admin.get_admin_room(); - - let mutex_state = Arc::clone( - services() - .globals - .roomid_mutex_state - .write() - .unwrap() - .entry(room_id.clone()) - .or_default(), - ); - let state_lock = mutex_state.lock().await; - - // Use the server user to grant the new admin's power level - let conduit_user = - UserId::parse_with_server_name("conduit", services().globals.server_name()) - .expect("@conduit:server_name is valid"); - - // Invite and join the real user - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMember, - content: to_raw_value(&RoomMemberEventContent { - membership: MembershipState::Invite, - displayname: None, - avatar_url: None, - is_direct: None, - third_party_invite: None, - blurhash: None, - reason: None, - join_authorized_via_users_server: None, - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some(user_id.to_string()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMember, - content: to_raw_value(&RoomMemberEventContent { - membership: MembershipState::Join, - displayname: Some(displayname), - avatar_url: None, - is_direct: None, - third_party_invite: None, - blurhash: None, - reason: None, - join_authorized_via_users_server: None, - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some(user_id.to_string()), - redacts: None, - }, - user_id, - &room_id, - &state_lock, - )?; - - // Set power level - let mut users = BTreeMap::new(); - users.insert(conduit_user.to_owned(), 100.into()); - users.insert(user_id.to_owned(), 100.into()); - - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomPowerLevels, - content: to_raw_value(&RoomPowerLevelsEventContent { - users, - ..Default::default() - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; - - // Send welcome message - services().rooms.timeline.build_and_append_pdu( + if let Some(room_id) = services().admin.get_admin_room()? { + let mutex_state = Arc::clone( + services() + .globals + .roomid_mutex_state + .write() + .unwrap() + .entry(room_id.clone()) + .or_default(), + ); + let state_lock = mutex_state.lock().await; + + // Use the server user to grant the new admin's power level + let conduit_user = + UserId::parse_with_server_name("conduit", services().globals.server_name()) + .expect("@conduit:server_name is valid"); + + // Invite and join the real user + services().rooms.timeline.build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMember, + content: to_raw_value(&RoomMemberEventContent { + membership: MembershipState::Invite, + displayname: None, + avatar_url: None, + is_direct: None, + third_party_invite: None, + blurhash: None, + reason: None, + join_authorized_via_users_server: None, + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some(user_id.to_string()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + )?; + services().rooms.timeline.build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMember, + content: to_raw_value(&RoomMemberEventContent { + membership: MembershipState::Join, + displayname: Some(displayname), + avatar_url: None, + is_direct: None, + third_party_invite: None, + blurhash: None, + reason: None, + join_authorized_via_users_server: None, + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some(user_id.to_string()), + redacts: None, + }, + user_id, + &room_id, + &state_lock, + )?; + + // Set power level + let mut users = BTreeMap::new(); + users.insert(conduit_user.to_owned(), 100.into()); + users.insert(user_id.to_owned(), 100.into()); + + services().rooms.timeline.build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomPowerLevels, + content: to_raw_value(&RoomPowerLevelsEventContent { + users, + ..Default::default() + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + )?; + + // Send welcome message + services().rooms.timeline.build_and_append_pdu( PduBuilder { event_type: TimelineEventType::RoomMessage, content: to_raw_value(&RoomMessageEventContent::text_html( @@ -1225,7 +1222,10 @@ impl Service { &state_lock, )?; - Ok(()) + Ok(()) + } else { + Ok(()) + } } } diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 13193e52..b66fc645 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -448,7 +448,6 @@ impl Service { .search .index_pdu(shortroomid, &pdu_id, &body)?; - let admin_room = services().admin.get_admin_room(); let server_user = format!("@conduit:{}", services().globals.server_name()); let to_conduit = body.starts_with(&format!("{server_user}: ")) @@ -461,8 +460,10 @@ impl Service { let from_conduit = pdu.sender == server_user && services().globals.emergency_password().is_none(); - if to_conduit && !from_conduit && admin_room == pdu.room_id { - services().admin.process_message(body); + if let Some(admin_room) = services().admin.get_admin_room()? { + if to_conduit && !from_conduit && admin_room == pdu.room_id { + services().admin.process_message(body); + } } } } @@ -815,84 +816,85 @@ impl Service { let (pdu, pdu_json) = self.create_hash_and_sign_event(pdu_builder, sender, room_id, state_lock)?; - let admin_room = services().admin.get_admin_room(); - if admin_room == room_id { - match pdu.event_type() { - TimelineEventType::RoomEncryption => { - warn!("Encryption is not allowed in the admins room"); - return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Encryption is not allowed in the admins room.", - )); - } - TimelineEventType::RoomMember => { - #[derive(Deserialize)] - struct ExtractMembership { - membership: MembershipState, + if let Some(admin_room) = services().admin.get_admin_room()? { + if admin_room == room_id { + match pdu.event_type() { + TimelineEventType::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 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 { - if target == server_user { - warn!("Conduit user cannot leave from admins room"); - return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Conduit user cannot leave from admins room.", - )); + TimelineEventType::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() == server_name) - .filter(|m| m != target) - .count(); - if count < 2 { - warn!("Last admin cannot leave from admins room"); - return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Last admin cannot leave from admins room.", - )); + 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 { + if target == 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() == server_name) + .filter(|m| m != target) + .count(); + if count < 2 { + warn!("Last admin cannot leave from admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Last admin cannot leave from admins room.", + )); + } } - } - if content.membership == MembershipState::Ban && pdu.state_key().is_some() { - if target == 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() == server_name) - .filter(|m| m != target) - .count(); - if count < 2 { - warn!("Last admin cannot be banned in admins room"); - return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Last admin cannot be banned in admins room.", - )); + if content.membership == MembershipState::Ban && pdu.state_key().is_some() { + if target == 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() == server_name) + .filter(|m| m != target) + .count(); + if count < 2 { + warn!("Last admin cannot be banned in admins room"); + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Last admin cannot be banned in admins room.", + )); + } } } + _ => {} } - _ => {} } } From 4934020ee705a5ca28839583281f257f4ee1ec24 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Mon, 4 Mar 2024 09:32:21 +0000 Subject: [PATCH 072/129] style: remove unnecessary else block --- src/service/admin/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index 44c7934a..f6e52f7a 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -1221,11 +1221,8 @@ impl Service { &room_id, &state_lock, )?; - - Ok(()) - } else { - Ok(()) } + Ok(()) } } From becaad677f22e3fb9f4a4e076f576110daae9393 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Tue, 5 Mar 2024 14:22:54 +0000 Subject: [PATCH 073/129] refactor: use async-aware RwLocks and Mutexes where possible --- Cargo.lock | 12 + Cargo.toml | 1 + src/api/client_server/keys.rs | 27 +- src/api/client_server/membership.rs | 263 +++++++------ src/api/client_server/message.rs | 43 ++- src/api/client_server/profile.rs | 26 +- src/api/client_server/redact.rs | 38 +- src/api/client_server/room.rs | 493 +++++++++++++----------- src/api/client_server/state.rs | 30 +- src/api/client_server/sync.rs | 130 ++++--- src/api/server_server.rs | 13 +- src/lib.rs | 3 + src/service/admin/mod.rs | 503 +++++++++++++------------ src/service/globals/mod.rs | 18 +- src/service/mod.rs | 39 +- src/service/rooms/event_handler/mod.rs | 427 +++++++++++---------- src/service/rooms/lazy_loading/mod.rs | 14 +- src/service/rooms/spaces/mod.rs | 11 +- src/service/rooms/state/mod.rs | 2 +- src/service/rooms/timeline/mod.rs | 56 ++- src/service/users/mod.rs | 6 +- 21 files changed, 1160 insertions(+), 995 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e99928e0..426661bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,6 +80,17 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002" +[[package]] +name = "async-recursion" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "async-trait" version = "0.1.77" @@ -374,6 +385,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" name = "conduit" version = "0.7.0-alpha" dependencies = [ + "async-recursion", "async-trait", "axum", "axum-server", diff --git a/Cargo.toml b/Cargo.toml index e8c1c8bf..93ff2f3b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,6 +115,7 @@ lazy_static = "1.4.0" async-trait = "0.1.68" sd-notify = { version = "0.4.1", optional = true } +async-recursion = "1.0.5" [target.'cfg(unix)'.dependencies] nix = { version = "0.26.2", features = ["resource"] } diff --git a/src/api/client_server/keys.rs b/src/api/client_server/keys.rs index 9fd00897..4af8890d 100644 --- a/src/api/client_server/keys.rs +++ b/src/api/client_server/keys.rs @@ -339,17 +339,19 @@ pub(crate) async fn get_keys_helper bool>( let mut failures = BTreeMap::new(); - let back_off = |id| match services() - .globals - .bad_query_ratelimiter - .write() - .unwrap() - .entry(id) - { - hash_map::Entry::Vacant(e) => { - e.insert((Instant::now(), 1)); + let back_off = |id| async { + match services() + .globals + .bad_query_ratelimiter + .write() + .await + .entry(id) + { + hash_map::Entry::Vacant(e) => { + e.insert((Instant::now(), 1)); + } + hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1), } - hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1), }; let mut futures: FuturesUnordered<_> = get_over_federation @@ -359,7 +361,7 @@ pub(crate) async fn get_keys_helper bool>( .globals .bad_query_ratelimiter .read() - .unwrap() + .await .get(server) { // Exponential backoff @@ -428,7 +430,8 @@ pub(crate) async fn get_keys_helper bool>( device_keys.extend(response.device_keys); } _ => { - back_off(server.to_owned()); + back_off(server.to_owned()).await; + failures.insert(server.to_string(), json!({})); } } diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index 5c78a1c2..bc84b262 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -26,9 +26,10 @@ use ruma::{ use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; use std::{ collections::{hash_map::Entry, BTreeMap, HashMap, HashSet}, - sync::{Arc, RwLock}, + sync::Arc, time::{Duration, Instant}, }; +use tokio::sync::RwLock; use tracing::{debug, error, info, warn}; use crate::{ @@ -212,24 +213,28 @@ pub async fn kick_user_route( .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(body.room_id.clone()) .or_default(), ); let state_lock = mutex_state.lock().await; - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMember, - content: to_raw_value(&event).expect("event is valid, we just created it"), - unsigned: None, - state_key: Some(body.user_id.to_string()), - redacts: None, - }, - sender_user, - &body.room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMember, + content: to_raw_value(&event).expect("event is valid, we just created it"), + unsigned: None, + state_key: Some(body.user_id.to_string()), + redacts: None, + }, + sender_user, + &body.room_id, + &state_lock, + ) + .await?; drop(state_lock); @@ -276,24 +281,28 @@ pub async fn ban_user_route(body: Ruma) -> Result t, Err(_) => continue, }; @@ -710,7 +723,7 @@ async fn join_room_by_id_helper( .iter() .map(|pdu| validate_and_add_event_id(pdu, &room_version_id, &pub_key_map)) { - let (event_id, value) = match result { + let (event_id, value) = match result.await { Ok(t) => t, Err(_) => continue, }; @@ -784,12 +797,16 @@ async fn join_room_by_id_helper( let statehash_after_join = services().rooms.state.append_to_state(&parsed_join_pdu)?; info!("Appending new room join event"); - services().rooms.timeline.append_pdu( - &parsed_join_pdu, - join_event, - vec![(*parsed_join_pdu.event_id).to_owned()], - &state_lock, - )?; + services() + .rooms + .timeline + .append_pdu( + &parsed_join_pdu, + join_event, + vec![(*parsed_join_pdu.event_id).to_owned()], + &state_lock, + ) + .await?; info!("Setting final room state for new room"); // We set the room state after inserting the pdu, so that we never have a moment in time @@ -902,18 +919,23 @@ async fn join_room_by_id_helper( }; // Try normal join first - let error = match services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMember, - content: to_raw_value(&event).expect("event is valid, we just created it"), - unsigned: None, - state_key: Some(sender_user.to_string()), - redacts: None, - }, - sender_user, - room_id, - &state_lock, - ) { + let error = match services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMember, + content: to_raw_value(&event).expect("event is valid, we just created it"), + unsigned: None, + state_key: Some(sender_user.to_string()), + redacts: None, + }, + sender_user, + room_id, + &state_lock, + ) + .await + { Ok(_event_id) => return Ok(join_room_by_id::v3::Response::new(room_id.to_owned())), Err(e) => e, }; @@ -1109,7 +1131,7 @@ async fn make_join_request( make_join_response_and_server } -fn validate_and_add_event_id( +async fn validate_and_add_event_id( pdu: &RawJsonValue, room_version: &RoomVersionId, pub_key_map: &RwLock>>, @@ -1125,24 +1147,26 @@ fn validate_and_add_event_id( )) .expect("ruma's reference hashes are valid event ids"); - let back_off = |id| match services() - .globals - .bad_event_ratelimiter - .write() - .unwrap() - .entry(id) - { - Entry::Vacant(e) => { - e.insert((Instant::now(), 1)); + let back_off = |id| async { + match services() + .globals + .bad_event_ratelimiter + .write() + .await + .entry(id) + { + Entry::Vacant(e) => { + e.insert((Instant::now(), 1)); + } + Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1), } - Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1), }; if let Some((time, tries)) = services() .globals .bad_event_ratelimiter .read() - .unwrap() + .await .get(&event_id) { // Exponential backoff @@ -1157,15 +1181,10 @@ fn validate_and_add_event_id( } } - if let Err(e) = ruma::signatures::verify_event( - &*pub_key_map - .read() - .map_err(|_| Error::bad_database("RwLock is poisoned."))?, - &value, - room_version, - ) { + if let Err(e) = ruma::signatures::verify_event(&*pub_key_map.read().await, &value, room_version) + { warn!("Event {} failed verification {:?} {}", event_id, pdu, e); - back_off(event_id); + back_off(event_id).await; return Err(Error::BadServerResponse("Event failed verification.")); } @@ -1191,7 +1210,7 @@ pub(crate) async fn invite_helper<'a>( .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(room_id.to_owned()) .or_default(), ); @@ -1312,34 +1331,38 @@ pub(crate) async fn invite_helper<'a>( .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(room_id.to_owned()) .or_default(), ); let state_lock = mutex_state.lock().await; - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMember, - content: to_raw_value(&RoomMemberEventContent { - membership: MembershipState::Invite, - displayname: services().users.displayname(user_id)?, - avatar_url: services().users.avatar_url(user_id)?, - is_direct: Some(is_direct), - third_party_invite: None, - blurhash: services().users.blurhash(user_id)?, - reason, - join_authorized_via_users_server: None, - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some(user_id.to_string()), - redacts: None, - }, - sender_user, - room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMember, + content: to_raw_value(&RoomMemberEventContent { + membership: MembershipState::Invite, + displayname: services().users.displayname(user_id)?, + avatar_url: services().users.avatar_url(user_id)?, + is_direct: Some(is_direct), + third_party_invite: None, + blurhash: services().users.blurhash(user_id)?, + reason, + join_authorized_via_users_server: None, + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some(user_id.to_string()), + redacts: None, + }, + sender_user, + room_id, + &state_lock, + ) + .await?; drop(state_lock); @@ -1407,7 +1430,7 @@ pub async fn leave_room(user_id: &UserId, room_id: &RoomId, reason: Option JoinRule::Public, - // according to spec "invite" is the default - _ => JoinRule::Invite, - })) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - sender_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomJoinRules, + content: to_raw_value(&RoomJoinRulesEventContent::new(match preset { + RoomPreset::PublicChat => JoinRule::Public, + // according to spec "invite" is the default + _ => JoinRule::Invite, + })) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + sender_user, + &room_id, + &state_lock, + ) + .await?; // 5.2 History Visibility - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomHistoryVisibility, - content: to_raw_value(&RoomHistoryVisibilityEventContent::new( - HistoryVisibility::Shared, - )) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - sender_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomHistoryVisibility, + content: to_raw_value(&RoomHistoryVisibilityEventContent::new( + HistoryVisibility::Shared, + )) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + sender_user, + &room_id, + &state_lock, + ) + .await?; // 5.3 Guest Access - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomGuestAccess, - content: to_raw_value(&RoomGuestAccessEventContent::new(match preset { - RoomPreset::PublicChat => GuestAccess::Forbidden, - _ => GuestAccess::CanJoin, - })) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - sender_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomGuestAccess, + content: to_raw_value(&RoomGuestAccessEventContent::new(match preset { + RoomPreset::PublicChat => GuestAccess::Forbidden, + _ => GuestAccess::CanJoin, + })) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + sender_user, + &room_id, + &state_lock, + ) + .await?; // 6. Events listed in initial_state for event in &body.initial_state { @@ -353,47 +381,54 @@ pub async fn create_room_route( continue; } - services().rooms.timeline.build_and_append_pdu( - pdu_builder, - sender_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu(pdu_builder, sender_user, &room_id, &state_lock) + .await?; } // 7. Events implied by name and topic if let Some(name) = &body.name { - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomName, - content: to_raw_value(&RoomNameEventContent::new(name.clone())) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - sender_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomName, + content: to_raw_value(&RoomNameEventContent::new(name.clone())) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + sender_user, + &room_id, + &state_lock, + ) + .await?; } if let Some(topic) = &body.topic { - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomTopic, - content: to_raw_value(&RoomTopicEventContent { - topic: topic.clone(), - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - sender_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomTopic, + content: to_raw_value(&RoomTopicEventContent { + topic: topic.clone(), + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + sender_user, + &room_id, + &state_lock, + ) + .await?; } // 8. Events implied by invite (and TODO: invite_3pid) @@ -523,7 +558,7 @@ pub async fn upgrade_room_route( .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(body.room_id.clone()) .or_default(), ); @@ -531,22 +566,26 @@ pub async fn upgrade_room_route( // Send a m.room.tombstone event to the old room to indicate that it is not intended to be used any further // Fail if the sender does not have the required permissions - let tombstone_event_id = services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomTombstone, - content: to_raw_value(&RoomTombstoneEventContent { - body: "This room has been replaced".to_owned(), - replacement_room: replacement_room.clone(), - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - sender_user, - &body.room_id, - &state_lock, - )?; + let tombstone_event_id = services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomTombstone, + content: to_raw_value(&RoomTombstoneEventContent { + body: "This room has been replaced".to_owned(), + replacement_room: replacement_room.clone(), + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + sender_user, + &body.room_id, + &state_lock, + ) + .await?; // Change lock to replacement room drop(state_lock); @@ -555,7 +594,7 @@ pub async fn upgrade_room_route( .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(replacement_room.clone()) .or_default(), ); @@ -613,43 +652,51 @@ pub async fn upgrade_room_route( )); } - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomCreate, - content: to_raw_value(&create_event_content) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - sender_user, - &replacement_room, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomCreate, + content: to_raw_value(&create_event_content) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + sender_user, + &replacement_room, + &state_lock, + ) + .await?; // Join the new room - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMember, - content: to_raw_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: None, - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some(sender_user.to_string()), - redacts: None, - }, - sender_user, - &replacement_room, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMember, + content: to_raw_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: None, + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some(sender_user.to_string()), + redacts: None, + }, + sender_user, + &replacement_room, + &state_lock, + ) + .await?; // Recommended transferable state events list from the specs let transferable_state_events = vec![ @@ -676,18 +723,22 @@ pub async fn upgrade_room_route( None => continue, // Skipping missing events. }; - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: event_type.to_string().into(), - content: event_content, - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - sender_user, - &replacement_room, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: event_type.to_string().into(), + content: event_content, + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + sender_user, + &replacement_room, + &state_lock, + ) + .await?; } // Moves any local aliases to the new room @@ -721,19 +772,23 @@ pub async fn upgrade_room_route( power_levels_event_content.invite = new_level; // Modify the power levels in the old room to prevent sending of events and inviting new users - let _ = services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomPowerLevels, - content: to_raw_value(&power_levels_event_content) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - sender_user, - &body.room_id, - &state_lock, - )?; + let _ = services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomPowerLevels, + content: to_raw_value(&power_levels_event_content) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + sender_user, + &body.room_id, + &state_lock, + ) + .await?; drop(state_lock); diff --git a/src/api/client_server/state.rs b/src/api/client_server/state.rs index 174282a1..e62aa013 100644 --- a/src/api/client_server/state.rs +++ b/src/api/client_server/state.rs @@ -227,24 +227,28 @@ async fn send_state_event_for_key_helper( .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(room_id.to_owned()) .or_default(), ); let state_lock = mutex_state.lock().await; - let event_id = services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: event_type.to_string().into(), - content: serde_json::from_str(json.json().get()).expect("content is valid json"), - unsigned: None, - state_key: Some(state_key), - redacts: None, - }, - sender_user, - room_id, - &state_lock, - )?; + let event_id = services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: event_type.to_string().into(), + content: serde_json::from_str(json.json().get()).expect("content is valid json"), + unsigned: None, + state_key: Some(state_key), + redacts: None, + }, + sender_user, + room_id, + &state_lock, + ) + .await?; Ok(event_id) } diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 76b48d10..5ac00c60 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1,6 +1,7 @@ use crate::{ service::rooms::timeline::PduCount, services, Error, PduEvent, Result, Ruma, RumaResponse, }; + use ruma::{ api::client::{ filter::{FilterDefinition, LazyLoadOptions}, @@ -75,7 +76,7 @@ pub async fn sync_events_route( .globals .sync_receivers .write() - .unwrap() + .await .entry((sender_user.clone(), sender_device.clone())) { Entry::Vacant(v) => { @@ -147,7 +148,7 @@ async fn sync_helper_wrapper( .globals .sync_receivers .write() - .unwrap() + .await .entry((sender_user, sender_device)) { Entry::Occupied(o) => { @@ -302,11 +303,11 @@ async fn sync_helper( .globals .roomid_mutex_insert .write() - .unwrap() + .await .entry(room_id.clone()) .or_default(), ); - let insert_lock = mutex_insert.lock().unwrap(); + let insert_lock = mutex_insert.lock().await; drop(insert_lock); } @@ -434,11 +435,11 @@ async fn sync_helper( .globals .roomid_mutex_insert .write() - .unwrap() + .await .entry(room_id.clone()) .or_default(), ); - let insert_lock = mutex_insert.lock().unwrap(); + let insert_lock = mutex_insert.lock().await; drop(insert_lock); } @@ -577,11 +578,11 @@ async fn load_joined_room( .globals .roomid_mutex_insert .write() - .unwrap() + .await .entry(room_id.to_owned()) .or_default(), ); - let insert_lock = mutex_insert.lock().unwrap(); + let insert_lock = mutex_insert.lock().await; drop(insert_lock); } @@ -599,12 +600,11 @@ async fn load_joined_room( timeline_users.insert(event.sender.as_str().to_owned()); } - services().rooms.lazy_loading.lazy_load_confirm_delivery( - sender_user, - sender_device, - room_id, - sincecount, - )?; + services() + .rooms + .lazy_loading + .lazy_load_confirm_delivery(sender_user, sender_device, room_id, sincecount) + .await?; // Database queries: @@ -797,13 +797,17 @@ async fn load_joined_room( // The state_events above should contain all timeline_users, let's mark them as lazy // loaded. - services().rooms.lazy_loading.lazy_load_mark_sent( - sender_user, - sender_device, - room_id, - lazy_loaded, - next_batchcount, - ); + services() + .rooms + .lazy_loading + .lazy_load_mark_sent( + sender_user, + sender_device, + room_id, + lazy_loaded, + next_batchcount, + ) + .await; ( heroes, @@ -884,13 +888,17 @@ async fn load_joined_room( } } - services().rooms.lazy_loading.lazy_load_mark_sent( - sender_user, - sender_device, - room_id, - lazy_loaded, - next_batchcount, - ); + services() + .rooms + .lazy_loading + .lazy_load_mark_sent( + sender_user, + sender_device, + room_id, + lazy_loaded, + next_batchcount, + ) + .await; let encrypted_room = services() .rooms @@ -1189,11 +1197,14 @@ pub async fn sync_events_v4_route( if globalsince == 0 { if let Some(conn_id) = &body.conn_id { - services().users.forget_sync_request_connection( - sender_user.clone(), - sender_device.clone(), - conn_id.clone(), - ) + services() + .users + .forget_sync_request_connection( + sender_user.clone(), + sender_device.clone(), + conn_id.clone(), + ) + .await } } @@ -1463,14 +1474,17 @@ pub async fn sync_events_v4_route( ); if let Some(conn_id) = &body.conn_id { - services().users.update_sync_known_rooms( - sender_user.clone(), - sender_device.clone(), - conn_id.clone(), - list_id, - new_known_rooms, - globalsince, - ); + services() + .users + .update_sync_known_rooms( + sender_user.clone(), + sender_device.clone(), + conn_id.clone(), + list_id, + new_known_rooms, + globalsince, + ) + .await; } } @@ -1502,23 +1516,29 @@ pub async fn sync_events_v4_route( } if let Some(conn_id) = &body.conn_id { - services().users.update_sync_known_rooms( - sender_user.clone(), - sender_device.clone(), - conn_id.clone(), - "subscriptions".to_owned(), - known_subscription_rooms, - globalsince, - ); + services() + .users + .update_sync_known_rooms( + sender_user.clone(), + sender_device.clone(), + conn_id.clone(), + "subscriptions".to_owned(), + known_subscription_rooms, + globalsince, + ) + .await; } if let Some(conn_id) = &body.conn_id { - services().users.update_sync_subscriptions( - sender_user.clone(), - sender_device.clone(), - conn_id.clone(), - body.room_subscriptions, - ); + services() + .users + .update_sync_subscriptions( + sender_user.clone(), + sender_device.clone(), + conn_id.clone(), + body.room_subscriptions, + ) + .await; } let mut rooms = BTreeMap::new(); diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 1ba2edc0..f946feaf 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -51,9 +51,10 @@ use std::{ fmt::Debug, mem, net::{IpAddr, SocketAddr}, - sync::{Arc, RwLock}, + sync::Arc, time::{Duration, Instant, SystemTime}, }; +use tokio::sync::RwLock; use tracing::{debug, error, warn}; @@ -137,7 +138,7 @@ where .globals .actual_destination_cache .read() - .unwrap() + .await .get(destination) .cloned(); @@ -290,7 +291,7 @@ where .globals .actual_destination_cache .write() - .unwrap() + .await .insert( OwnedServerName::from(destination), (actual_destination, host), @@ -740,7 +741,7 @@ pub async fn send_transaction_message_route( .globals .roomid_mutex_federation .write() - .unwrap() + .await .entry(room_id.to_owned()) .or_default(), ); @@ -1409,7 +1410,7 @@ pub async fn create_join_event_template_route( .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(body.room_id.to_owned()) .or_default(), ); @@ -1579,7 +1580,7 @@ async fn create_join_event( .globals .roomid_mutex_federation .write() - .unwrap() + .await .entry(room_id.to_owned()) .or_default(), ); diff --git a/src/lib.rs b/src/lib.rs index 66d0c57c..9c1170dd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,9 @@ mod database; mod service; mod utils; +// Not async due to services() being used in many closures, and async colsures are not stable as of writing +// This is the case for every other occurence of sync Mutex/RwLock, except for database related ones, where +// the current maintainer (Timo) as asked to not modify those use std::sync::RwLock; pub use api::ruma_wrapper::{Ruma, RumaResponse}; diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index f6e52f7a..d99be878 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -1,7 +1,7 @@ use std::{ collections::BTreeMap, convert::{TryFrom, TryInto}, - sync::{Arc, RwLock}, + sync::Arc, time::Instant, }; @@ -26,7 +26,7 @@ use ruma::{ EventId, OwnedRoomAliasId, OwnedRoomId, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId, }; use serde_json::value::to_raw_value; -use tokio::sync::{mpsc, Mutex, MutexGuard}; +use tokio::sync::{mpsc, Mutex, RwLock}; use crate::{ api::client_server::{leave_all_rooms, AUTO_GEN_PASSWORD_LENGTH}, @@ -215,27 +215,6 @@ impl Service { .expect("@conduit:server_name is valid"); if let Ok(Some(conduit_room)) = services().admin.get_admin_room() { - let send_message = |message: RoomMessageEventContent, - mutex_lock: &MutexGuard<'_, ()>| { - services() - .rooms - .timeline - .build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMessage, - content: to_raw_value(&message) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: None, - redacts: None, - }, - &conduit_user, - &conduit_room, - mutex_lock, - ) - .unwrap(); - }; - loop { tokio::select! { Some(event) = receiver.recv() => { @@ -248,16 +227,30 @@ impl Service { services().globals .roomid_mutex_state .write() - .unwrap() + .await .entry(conduit_room.to_owned()) .or_default(), ); let state_lock = mutex_state.lock().await; - send_message(message_content, &state_lock); - - drop(state_lock); + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMessage, + content: to_raw_value(&message_content) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: None, + redacts: None, + }, + &conduit_user, + &conduit_room, + &state_lock, + ) + .await.unwrap(); } } } @@ -425,11 +418,7 @@ impl Service { Err(e) => RoomMessageEventContent::text_plain(e.to_string()), }, AdminCommand::IncomingFederation => { - let map = services() - .globals - .roomid_federationhandletime - .read() - .unwrap(); + let map = services().globals.roomid_federationhandletime.read().await; let mut msg: String = format!("Handling {} incoming pdus:\n", map.len()); for (r, (e, i)) in map.iter() { @@ -543,7 +532,7 @@ impl Service { } } AdminCommand::MemoryUsage => { - let response1 = services().memory_usage(); + let response1 = services().memory_usage().await; let response2 = services().globals.db.memory_usage(); RoomMessageEventContent::text_plain(format!( @@ -556,7 +545,7 @@ impl Service { RoomMessageEventContent::text_plain("Done.") } AdminCommand::ClearServiceCaches { amount } => { - services().clear_caches(amount); + services().clear_caches(amount).await; RoomMessageEventContent::text_plain("Done.") } @@ -797,7 +786,7 @@ impl Service { .fetch_required_signing_keys(&value, &pub_key_map) .await?; - let pub_key_map = pub_key_map.read().unwrap(); + let pub_key_map = pub_key_map.read().await; match ruma::signatures::verify_json(&pub_key_map, &value) { Ok(_) => RoomMessageEventContent::text_plain("Signature correct"), Err(e) => RoomMessageEventContent::text_plain(format!( @@ -913,7 +902,7 @@ impl Service { .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(room_id.clone()) .or_default(), ); @@ -932,164 +921,202 @@ impl Service { content.room_version = services().globals.default_room_version(); // 1. The room create event - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomCreate, - content: to_raw_value(&content).expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomCreate, + content: to_raw_value(&content).expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; // 2. Make conduit bot join - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMember, - content: to_raw_value(&RoomMemberEventContent { - membership: MembershipState::Join, - displayname: None, - avatar_url: None, - is_direct: None, - third_party_invite: None, - blurhash: None, - reason: None, - join_authorized_via_users_server: None, - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some(conduit_user.to_string()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMember, + content: to_raw_value(&RoomMemberEventContent { + membership: MembershipState::Join, + displayname: None, + avatar_url: None, + is_direct: None, + third_party_invite: None, + blurhash: None, + reason: None, + join_authorized_via_users_server: None, + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some(conduit_user.to_string()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; // 3. Power levels let mut users = BTreeMap::new(); users.insert(conduit_user.clone(), 100.into()); - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomPowerLevels, - content: to_raw_value(&RoomPowerLevelsEventContent { - users, - ..Default::default() - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomPowerLevels, + content: to_raw_value(&RoomPowerLevelsEventContent { + users, + ..Default::default() + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; // 4.1 Join Rules - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomJoinRules, - content: to_raw_value(&RoomJoinRulesEventContent::new(JoinRule::Invite)) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomJoinRules, + content: to_raw_value(&RoomJoinRulesEventContent::new(JoinRule::Invite)) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; // 4.2 History Visibility - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomHistoryVisibility, - content: to_raw_value(&RoomHistoryVisibilityEventContent::new( - HistoryVisibility::Shared, - )) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomHistoryVisibility, + content: to_raw_value(&RoomHistoryVisibilityEventContent::new( + HistoryVisibility::Shared, + )) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; // 4.3 Guest Access - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomGuestAccess, - content: to_raw_value(&RoomGuestAccessEventContent::new(GuestAccess::Forbidden)) + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomGuestAccess, + content: to_raw_value(&RoomGuestAccessEventContent::new( + GuestAccess::Forbidden, + )) .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; // 5. Events implied by name and topic let room_name = format!("{} Admin Room", services().globals.server_name()); - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomName, - content: to_raw_value(&RoomNameEventContent::new(room_name)) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomName, + content: to_raw_value(&RoomNameEventContent::new(room_name)) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomTopic, - content: to_raw_value(&RoomTopicEventContent { - topic: format!("Manage {}", services().globals.server_name()), - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomTopic, + content: to_raw_value(&RoomTopicEventContent { + topic: format!("Manage {}", services().globals.server_name()), + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; // 6. Room alias let alias: OwnedRoomAliasId = format!("#admins:{}", services().globals.server_name()) .try_into() .expect("#admins:server_name is a valid alias name"); - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomCanonicalAlias, - content: to_raw_value(&RoomCanonicalAliasEventContent { - alias: Some(alias.clone()), - alt_aliases: Vec::new(), - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomCanonicalAlias, + content: to_raw_value(&RoomCanonicalAliasEventContent { + alias: Some(alias.clone()), + alt_aliases: Vec::new(), + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; services().rooms.alias.set_alias(&alias, &room_id)?; @@ -1125,7 +1152,7 @@ impl Service { .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(room_id.clone()) .or_default(), ); @@ -1137,72 +1164,84 @@ impl Service { .expect("@conduit:server_name is valid"); // Invite and join the real user - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMember, - content: to_raw_value(&RoomMemberEventContent { - membership: MembershipState::Invite, - displayname: None, - avatar_url: None, - is_direct: None, - third_party_invite: None, - blurhash: None, - reason: None, - join_authorized_via_users_server: None, - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some(user_id.to_string()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomMember, - content: to_raw_value(&RoomMemberEventContent { - membership: MembershipState::Join, - displayname: Some(displayname), - avatar_url: None, - is_direct: None, - third_party_invite: None, - blurhash: None, - reason: None, - join_authorized_via_users_server: None, - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some(user_id.to_string()), - redacts: None, - }, - user_id, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMember, + content: to_raw_value(&RoomMemberEventContent { + membership: MembershipState::Invite, + displayname: None, + avatar_url: None, + is_direct: None, + third_party_invite: None, + blurhash: None, + reason: None, + join_authorized_via_users_server: None, + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some(user_id.to_string()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomMember, + content: to_raw_value(&RoomMemberEventContent { + membership: MembershipState::Join, + displayname: Some(displayname), + avatar_url: None, + is_direct: None, + third_party_invite: None, + blurhash: None, + reason: None, + join_authorized_via_users_server: None, + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some(user_id.to_string()), + redacts: None, + }, + user_id, + &room_id, + &state_lock, + ) + .await?; // Set power level let mut users = BTreeMap::new(); users.insert(conduit_user.to_owned(), 100.into()); users.insert(user_id.to_owned(), 100.into()); - services().rooms.timeline.build_and_append_pdu( - PduBuilder { - event_type: TimelineEventType::RoomPowerLevels, - content: to_raw_value(&RoomPowerLevelsEventContent { - users, - ..Default::default() - }) - .expect("event is valid, we just created it"), - unsigned: None, - state_key: Some("".to_owned()), - redacts: None, - }, - &conduit_user, - &room_id, - &state_lock, - )?; + services() + .rooms + .timeline + .build_and_append_pdu( + PduBuilder { + event_type: TimelineEventType::RoomPowerLevels, + content: to_raw_value(&RoomPowerLevelsEventContent { + users, + ..Default::default() + }) + .expect("event is valid, we just created it"), + unsigned: None, + state_key: Some("".to_owned()), + redacts: None, + }, + &conduit_user, + &room_id, + &state_lock, + ) + .await?; // Send welcome message services().rooms.timeline.build_and_append_pdu( @@ -1220,7 +1259,7 @@ impl Service { &conduit_user, &room_id, &state_lock, - )?; + ).await?; } Ok(()) } diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index f7822940..c3e02ad5 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -31,11 +31,11 @@ use std::{ path::PathBuf, sync::{ atomic::{self, AtomicBool}, - Arc, Mutex, RwLock, + Arc, RwLock as SyncRwLock, }, time::{Duration, Instant}, }; -use tokio::sync::{broadcast, watch::Receiver, Mutex as TokioMutex, Semaphore}; +use tokio::sync::{broadcast, watch::Receiver, Mutex, RwLock, Semaphore}; use tracing::{error, info}; use trust_dns_resolver::TokioAsyncResolver; @@ -53,7 +53,7 @@ pub struct Service { pub db: &'static dyn Data, pub actual_destination_cache: Arc>, // actual_destination, host - pub tls_name_override: Arc>, + pub tls_name_override: Arc>, pub config: Config, keypair: Arc, dns_resolver: TokioAsyncResolver, @@ -68,8 +68,8 @@ pub struct Service { pub servername_ratelimiter: Arc>>>, pub sync_receivers: RwLock>, pub roomid_mutex_insert: RwLock>>>, - pub roomid_mutex_state: RwLock>>>, - pub roomid_mutex_federation: RwLock>>>, // this lock will be held longer + pub roomid_mutex_state: RwLock>>>, + pub roomid_mutex_federation: RwLock>>>, // this lock will be held longer pub roomid_federationhandletime: RwLock>, pub stateres_mutex: Arc>, pub rotate: RotationHandler, @@ -109,11 +109,11 @@ impl Default for RotationHandler { pub struct Resolver { inner: GaiResolver, - overrides: Arc>, + overrides: Arc>, } impl Resolver { - pub fn new(overrides: Arc>) -> Self { + pub fn new(overrides: Arc>) -> Self { Resolver { inner: GaiResolver::new(), overrides, @@ -125,7 +125,7 @@ impl Resolve for Resolver { fn resolve(&self, name: Name) -> Resolving { self.overrides .read() - .expect("lock should not be poisoned") + .unwrap() .get(name.as_str()) .and_then(|(override_name, port)| { override_name.first().map(|first_name| { @@ -159,7 +159,7 @@ impl Service { } }; - let tls_name_override = Arc::new(RwLock::new(TlsNameMap::new())); + let tls_name_override = Arc::new(SyncRwLock::new(TlsNameMap::new())); let jwt_decoding_key = config .jwt_secret diff --git a/src/service/mod.rs b/src/service/mod.rs index f85da788..c1616c40 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,9 +1,10 @@ use std::{ collections::{BTreeMap, HashMap}, - sync::{Arc, Mutex}, + sync::{Arc, Mutex as SyncMutex}, }; use lru_cache::LruCache; +use tokio::sync::Mutex; use crate::{Config, Result}; @@ -79,17 +80,17 @@ impl Services { state: rooms::state::Service { db }, state_accessor: rooms::state_accessor::Service { db, - server_visibility_cache: Mutex::new(LruCache::new( + server_visibility_cache: SyncMutex::new(LruCache::new( (100.0 * config.conduit_cache_capacity_modifier) as usize, )), - user_visibility_cache: Mutex::new(LruCache::new( + user_visibility_cache: SyncMutex::new(LruCache::new( (100.0 * config.conduit_cache_capacity_modifier) as usize, )), }, state_cache: rooms::state_cache::Service { db }, state_compressor: rooms::state_compressor::Service { db, - stateinfo_cache: Mutex::new(LruCache::new( + stateinfo_cache: SyncMutex::new(LruCache::new( (100.0 * config.conduit_cache_capacity_modifier) as usize, )), }, @@ -107,7 +108,7 @@ impl Services { uiaa: uiaa::Service { db }, users: users::Service { db, - connections: Mutex::new(BTreeMap::new()), + connections: SyncMutex::new(BTreeMap::new()), }, account_data: account_data::Service { db }, admin: admin::Service::build(), @@ -118,14 +119,8 @@ impl Services { globals: globals::Service::load(db, config)?, }) } - fn memory_usage(&self) -> String { - let lazy_load_waiting = self - .rooms - .lazy_loading - .lazy_load_waiting - .lock() - .unwrap() - .len(); + async fn memory_usage(&self) -> String { + let lazy_load_waiting = self.rooms.lazy_loading.lazy_load_waiting.lock().await.len(); let server_visibility_cache = self .rooms .state_accessor @@ -152,15 +147,9 @@ impl Services { .timeline .lasttimelinecount_cache .lock() - .unwrap() - .len(); - let roomid_spacechunk_cache = self - .rooms - .spaces - .roomid_spacechunk_cache - .lock() - .unwrap() + .await .len(); + let roomid_spacechunk_cache = self.rooms.spaces.roomid_spacechunk_cache.lock().await.len(); format!( "\ @@ -173,13 +162,13 @@ roomid_spacechunk_cache: {roomid_spacechunk_cache}\ " ) } - fn clear_caches(&self, amount: u32) { + async fn clear_caches(&self, amount: u32) { if amount > 0 { self.rooms .lazy_loading .lazy_load_waiting .lock() - .unwrap() + .await .clear(); } if amount > 1 { @@ -211,7 +200,7 @@ roomid_spacechunk_cache: {roomid_spacechunk_cache}\ .timeline .lasttimelinecount_cache .lock() - .unwrap() + .await .clear(); } if amount > 5 { @@ -219,7 +208,7 @@ roomid_spacechunk_cache: {roomid_spacechunk_cache}\ .spaces .roomid_spacechunk_cache .lock() - .unwrap() + .await .clear(); } } diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 99fc2cb1..7cc662ee 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -1,25 +1,24 @@ /// An async function that can recursively call itself. type AsyncRecursiveType<'a, T> = Pin + 'a + Send>>; -use ruma::{ - api::federation::discovery::{get_remote_server_keys, get_server_keys}, - CanonicalJsonObject, CanonicalJsonValue, OwnedServerName, OwnedServerSigningKeyId, - RoomVersionId, -}; use std::{ collections::{hash_map, BTreeMap, HashMap, HashSet}, pin::Pin, - sync::{Arc, RwLock, RwLockWriteGuard}, + sync::Arc, time::{Duration, Instant, SystemTime}, }; -use tokio::sync::Semaphore; +use async_recursion::async_recursion; use futures_util::{stream::FuturesUnordered, Future, StreamExt}; use ruma::{ api::{ client::error::ErrorKind, federation::{ - discovery::get_remote_server_keys_batch::{self, v2::QueryCriteria}, + discovery::{ + get_remote_server_keys, + get_remote_server_keys_batch::{self, v2::QueryCriteria}, + get_server_keys, + }, event::{get_event, get_room_state_ids}, membership::create_join_event, }, @@ -31,9 +30,11 @@ use ruma::{ int, serde::Base64, state_res::{self, RoomVersion, StateMap}, - uint, EventId, MilliSecondsSinceUnixEpoch, RoomId, ServerName, + uint, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, + OwnedServerName, OwnedServerSigningKeyId, RoomId, RoomVersionId, ServerName, }; use serde_json::value::RawValue as RawJsonValue; +use tokio::sync::{RwLock, RwLockWriteGuard, Semaphore}; use tracing::{debug, error, info, trace, warn}; use crate::{service::*, services, Error, PduEvent, Result}; @@ -168,7 +169,7 @@ impl Service { .globals .bad_event_ratelimiter .read() - .unwrap() + .await .get(&*prev_id) { // Exponential backoff @@ -189,7 +190,7 @@ impl Service { .globals .bad_event_ratelimiter .write() - .unwrap() + .await .entry((*prev_id).to_owned()) { hash_map::Entry::Vacant(e) => { @@ -213,7 +214,7 @@ impl Service { .globals .roomid_federationhandletime .write() - .unwrap() + .await .insert(room_id.to_owned(), ((*prev_id).to_owned(), start_time)); if let Err(e) = self @@ -233,7 +234,7 @@ impl Service { .globals .bad_event_ratelimiter .write() - .unwrap() + .await .entry((*prev_id).to_owned()) { hash_map::Entry::Vacant(e) => { @@ -249,7 +250,7 @@ impl Service { .globals .roomid_federationhandletime .write() - .unwrap() + .await .remove(&room_id.to_owned()); debug!( "Handling prev event {} took {}m{}s", @@ -267,7 +268,7 @@ impl Service { .globals .roomid_federationhandletime .write() - .unwrap() + .await .insert(room_id.to_owned(), (event_id.to_owned(), start_time)); let r = services() .rooms @@ -285,7 +286,7 @@ impl Service { .globals .roomid_federationhandletime .write() - .unwrap() + .await .remove(&room_id.to_owned()); r @@ -326,11 +327,8 @@ impl Service { let room_version = RoomVersion::new(room_version_id).expect("room version is supported"); - let mut val = match ruma::signatures::verify_event( - &pub_key_map.read().expect("RwLock is poisoned."), - &value, - room_version_id, - ) { + let guard = pub_key_map.read().await; + let mut val = match ruma::signatures::verify_event(&guard, &value, room_version_id) { Err(e) => { // Drop warn!("Dropping bad event {}: {}", event_id, e,); @@ -365,6 +363,8 @@ impl Service { Ok(ruma::signatures::Verified::All) => value, }; + drop(guard); + // Now that we have checked the signature and hashes we can add the eventID and convert // to our PduEvent type val.insert( @@ -692,13 +692,15 @@ impl Service { { Ok(res) => { debug!("Fetching state events at event."); + let collect = res + .pdu_ids + .iter() + .map(|x| Arc::from(&**x)) + .collect::>(); let state_vec = self .fetch_and_handle_outliers( origin, - &res.pdu_ids - .iter() - .map(|x| Arc::from(&**x)) - .collect::>(), + &collect, create_event, room_id, room_version_id, @@ -805,7 +807,7 @@ impl Service { .globals .roomid_mutex_state .write() - .unwrap() + .await .entry(room_id.to_owned()) .or_default(), ); @@ -884,14 +886,18 @@ impl Service { debug!("Starting soft fail auth check"); if soft_fail { - services().rooms.timeline.append_incoming_pdu( - &incoming_pdu, - val, - extremities.iter().map(|e| (**e).to_owned()).collect(), - state_ids_compressed, - soft_fail, - &state_lock, - )?; + services() + .rooms + .timeline + .append_incoming_pdu( + &incoming_pdu, + val, + extremities.iter().map(|e| (**e).to_owned()).collect(), + state_ids_compressed, + soft_fail, + &state_lock, + ) + .await?; // Soft fail, we keep the event as an outlier but don't add it to the timeline warn!("Event was soft failed: {:?}", incoming_pdu); @@ -912,14 +918,18 @@ impl Service { // We use the `state_at_event` instead of `state_after` so we accurately // represent the state for this event. - let pdu_id = services().rooms.timeline.append_incoming_pdu( - &incoming_pdu, - val, - extremities.iter().map(|e| (**e).to_owned()).collect(), - state_ids_compressed, - soft_fail, - &state_lock, - )?; + let pdu_id = services() + .rooms + .timeline + .append_incoming_pdu( + &incoming_pdu, + val, + extremities.iter().map(|e| (**e).to_owned()).collect(), + state_ids_compressed, + soft_fail, + &state_lock, + ) + .await?; debug!("Appended incoming pdu"); @@ -1034,7 +1044,8 @@ impl Service { /// d. TODO: Ask other servers over federation? #[allow(clippy::type_complexity)] #[tracing::instrument(skip_all)] - pub(crate) fn fetch_and_handle_outliers<'a>( + #[async_recursion] + pub(crate) async fn fetch_and_handle_outliers<'a>( &'a self, origin: &'a ServerName, events: &'a [Arc], @@ -1042,176 +1053,175 @@ impl Service { room_id: &'a RoomId, room_version_id: &'a RoomVersionId, pub_key_map: &'a RwLock>>, - ) -> AsyncRecursiveType<'a, Vec<(Arc, Option>)>> - { - Box::pin(async move { - let back_off = |id| match services() + ) -> Vec<(Arc, Option>)> { + let back_off = |id| async move { + match services() .globals .bad_event_ratelimiter .write() - .unwrap() + .await .entry(id) { hash_map::Entry::Vacant(e) => { e.insert((Instant::now(), 1)); } hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1), - }; - - let mut pdus = vec![]; - for id in events { - // a. Look in the main timeline (pduid_pdu tree) - // b. Look at outlier pdu tree - // (get_pdu_json checks both) - if let Ok(Some(local_pdu)) = services().rooms.timeline.get_pdu(id) { - trace!("Found {} in db", id); - pdus.push((local_pdu, None)); - continue; - } + } + }; - // c. Ask origin server over federation - // We also handle its auth chain here so we don't get a stack overflow in - // handle_outlier_pdu. - let mut todo_auth_events = vec![Arc::clone(id)]; - let mut events_in_reverse_order = Vec::new(); - let mut events_all = HashSet::new(); - let mut i = 0; - while let Some(next_id) = todo_auth_events.pop() { - if let Some((time, tries)) = services() - .globals - .bad_event_ratelimiter - .read() - .unwrap() - .get(&*next_id) - { - // Exponential backoff - let mut min_elapsed_duration = - Duration::from_secs(5 * 60) * (*tries) * (*tries); - if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) { - min_elapsed_duration = Duration::from_secs(60 * 60 * 24); - } + let mut pdus = vec![]; + for id in events { + // a. Look in the main timeline (pduid_pdu tree) + // b. Look at outlier pdu tree + // (get_pdu_json checks both) + if let Ok(Some(local_pdu)) = services().rooms.timeline.get_pdu(id) { + trace!("Found {} in db", id); + pdus.push((local_pdu, None)); + continue; + } - if time.elapsed() < min_elapsed_duration { - info!("Backing off from {}", next_id); - continue; - } + // c. Ask origin server over federation + // We also handle its auth chain here so we don't get a stack overflow in + // handle_outlier_pdu. + let mut todo_auth_events = vec![Arc::clone(id)]; + let mut events_in_reverse_order = Vec::new(); + let mut events_all = HashSet::new(); + let mut i = 0; + while let Some(next_id) = todo_auth_events.pop() { + if let Some((time, tries)) = services() + .globals + .bad_event_ratelimiter + .read() + .await + .get(&*next_id) + { + // Exponential backoff + let mut min_elapsed_duration = + Duration::from_secs(5 * 60) * (*tries) * (*tries); + if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) { + min_elapsed_duration = Duration::from_secs(60 * 60 * 24); } - if events_all.contains(&next_id) { + if time.elapsed() < min_elapsed_duration { + info!("Backing off from {}", next_id); continue; } + } - i += 1; - if i % 100 == 0 { - tokio::task::yield_now().await; - } + if events_all.contains(&next_id) { + continue; + } - if let Ok(Some(_)) = services().rooms.timeline.get_pdu(&next_id) { - trace!("Found {} in db", next_id); - continue; - } + i += 1; + if i % 100 == 0 { + tokio::task::yield_now().await; + } - info!("Fetching {} over federation.", next_id); - match services() - .sending - .send_federation_request( - origin, - get_event::v1::Request { - event_id: (*next_id).to_owned(), - }, - ) - .await - { - Ok(res) => { - info!("Got {} over federation", next_id); - let (calculated_event_id, value) = - match pdu::gen_event_id_canonical_json(&res.pdu, room_version_id) { - Ok(t) => t, - Err(_) => { - back_off((*next_id).to_owned()); - continue; - } - }; - - if calculated_event_id != *next_id { - warn!("Server didn't return event id we requested: requested: {}, we got {}. Event: {:?}", - next_id, calculated_event_id, &res.pdu); - } + if let Ok(Some(_)) = services().rooms.timeline.get_pdu(&next_id) { + trace!("Found {} in db", next_id); + continue; + } - if let Some(auth_events) = - value.get("auth_events").and_then(|c| c.as_array()) - { - for auth_event in auth_events { - if let Ok(auth_event) = - serde_json::from_value(auth_event.clone().into()) - { - let a: Arc = auth_event; - todo_auth_events.push(a); - } else { - warn!("Auth event id is not valid"); - } + info!("Fetching {} over federation.", next_id); + match services() + .sending + .send_federation_request( + origin, + get_event::v1::Request { + event_id: (*next_id).to_owned(), + }, + ) + .await + { + Ok(res) => { + info!("Got {} over federation", next_id); + let (calculated_event_id, value) = + match pdu::gen_event_id_canonical_json(&res.pdu, room_version_id) { + Ok(t) => t, + Err(_) => { + back_off((*next_id).to_owned()).await; + continue; } - } else { - warn!("Auth event list invalid"); - } + }; - events_in_reverse_order.push((next_id.clone(), value)); - events_all.insert(next_id); + if calculated_event_id != *next_id { + warn!("Server didn't return event id we requested: requested: {}, we got {}. Event: {:?}", + next_id, calculated_event_id, &res.pdu); } - Err(_) => { - warn!("Failed to fetch event: {}", next_id); - back_off((*next_id).to_owned()); + + if let Some(auth_events) = + value.get("auth_events").and_then(|c| c.as_array()) + { + for auth_event in auth_events { + if let Ok(auth_event) = + serde_json::from_value(auth_event.clone().into()) + { + let a: Arc = auth_event; + todo_auth_events.push(a); + } else { + warn!("Auth event id is not valid"); + } + } + } else { + warn!("Auth event list invalid"); } + + events_in_reverse_order.push((next_id.clone(), value)); + events_all.insert(next_id); + } + Err(_) => { + warn!("Failed to fetch event: {}", next_id); + back_off((*next_id).to_owned()).await; } } + } - for (next_id, value) in events_in_reverse_order.iter().rev() { - if let Some((time, tries)) = services() - .globals - .bad_event_ratelimiter - .read() - .unwrap() - .get(&**next_id) - { - // Exponential backoff - let mut min_elapsed_duration = - Duration::from_secs(5 * 60) * (*tries) * (*tries); - if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) { - min_elapsed_duration = Duration::from_secs(60 * 60 * 24); - } + for (next_id, value) in events_in_reverse_order.iter().rev() { + if let Some((time, tries)) = services() + .globals + .bad_event_ratelimiter + .read() + .await + .get(&**next_id) + { + // Exponential backoff + let mut min_elapsed_duration = + Duration::from_secs(5 * 60) * (*tries) * (*tries); + if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) { + min_elapsed_duration = Duration::from_secs(60 * 60 * 24); + } - if time.elapsed() < min_elapsed_duration { - info!("Backing off from {}", next_id); - continue; - } + if time.elapsed() < min_elapsed_duration { + info!("Backing off from {}", next_id); + continue; } + } - match self - .handle_outlier_pdu( - origin, - create_event, - next_id, - room_id, - value.clone(), - true, - pub_key_map, - ) - .await - { - Ok((pdu, json)) => { - if next_id == id { - pdus.push((pdu, Some(json))); - } - } - Err(e) => { - warn!("Authentication of event {} failed: {:?}", next_id, e); - back_off((**next_id).to_owned()); + match self + .handle_outlier_pdu( + origin, + create_event, + next_id, + room_id, + value.clone(), + true, + pub_key_map, + ) + .await + { + Ok((pdu, json)) => { + if next_id == id { + pdus.push((pdu, Some(json))); } } + Err(e) => { + warn!("Authentication of event {} failed: {:?}", next_id, e); + back_off((**next_id).to_owned()).await; + } } } - pdus - }) + } + pdus } async fn fetch_unknown_prev_events( @@ -1360,7 +1370,7 @@ impl Service { pub_key_map .write() - .map_err(|_| Error::bad_database("RwLock is poisoned."))? + .await .insert(signature_server.clone(), keys); } @@ -1369,7 +1379,7 @@ impl Service { // Gets a list of servers for which we don't have the signing key yet. We go over // the PDUs and either cache the key or add it to the list that needs to be retrieved. - fn get_server_keys_from_cache( + async fn get_server_keys_from_cache( &self, pdu: &RawJsonValue, servers: &mut BTreeMap>, @@ -1393,7 +1403,7 @@ impl Service { .globals .bad_event_ratelimiter .read() - .unwrap() + .await .get(event_id) { // Exponential backoff @@ -1469,17 +1479,19 @@ impl Service { > = BTreeMap::new(); { - let mut pkm = pub_key_map - .write() - .map_err(|_| Error::bad_database("RwLock is poisoned."))?; + let mut pkm = pub_key_map.write().await; // Try to fetch keys, failure is okay // Servers we couldn't find in the cache will be added to `servers` for pdu in &event.room_state.state { - let _ = self.get_server_keys_from_cache(pdu, &mut servers, room_version, &mut pkm); + let _ = self + .get_server_keys_from_cache(pdu, &mut servers, room_version, &mut pkm) + .await; } for pdu in &event.room_state.auth_chain { - let _ = self.get_server_keys_from_cache(pdu, &mut servers, room_version, &mut pkm); + let _ = self + .get_server_keys_from_cache(pdu, &mut servers, room_version, &mut pkm) + .await; } drop(pkm); @@ -1503,9 +1515,7 @@ impl Service { .await { trace!("Got signing keys: {:?}", keys); - let mut pkm = pub_key_map - .write() - .map_err(|_| Error::bad_database("RwLock is poisoned."))?; + let mut pkm = pub_key_map.write().await; for k in keys.server_keys { let k = match k.deserialize() { Ok(key) => key, @@ -1564,10 +1574,7 @@ impl Service { .into_iter() .map(|(k, v)| (k.to_string(), v.key)) .collect(); - pub_key_map - .write() - .map_err(|_| Error::bad_database("RwLock is poisoned."))? - .insert(origin.to_string(), result); + pub_key_map.write().await.insert(origin.to_string(), result); } } info!("Done handling result"); @@ -1632,14 +1639,14 @@ impl Service { .globals .servername_ratelimiter .read() - .unwrap() + .await .get(origin) .map(|s| Arc::clone(s).acquire_owned()); let permit = match permit { Some(p) => p, None => { - let mut write = services().globals.servername_ratelimiter.write().unwrap(); + let mut write = services().globals.servername_ratelimiter.write().await; let s = Arc::clone( write .entry(origin.to_owned()) @@ -1651,24 +1658,26 @@ impl Service { } .await; - let back_off = |id| match services() - .globals - .bad_signature_ratelimiter - .write() - .unwrap() - .entry(id) - { - hash_map::Entry::Vacant(e) => { - e.insert((Instant::now(), 1)); + let back_off = |id| async { + match services() + .globals + .bad_signature_ratelimiter + .write() + .await + .entry(id) + { + hash_map::Entry::Vacant(e) => { + e.insert((Instant::now(), 1)); + } + hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1), } - hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1), }; if let Some((time, tries)) = services() .globals .bad_signature_ratelimiter .read() - .unwrap() + .await .get(&signature_ids) { // Exponential backoff @@ -1775,7 +1784,7 @@ impl Service { drop(permit); - back_off(signature_ids); + back_off(signature_ids).await; warn!("Failed to find public key for server: {}", origin); Err(Error::BadServerResponse( diff --git a/src/service/rooms/lazy_loading/mod.rs b/src/service/rooms/lazy_loading/mod.rs index c51a57e9..e2594a0a 100644 --- a/src/service/rooms/lazy_loading/mod.rs +++ b/src/service/rooms/lazy_loading/mod.rs @@ -1,11 +1,9 @@ mod data; -use std::{ - collections::{HashMap, HashSet}, - sync::Mutex, -}; +use std::collections::{HashMap, HashSet}; pub use data::Data; use ruma::{DeviceId, OwnedDeviceId, OwnedRoomId, OwnedUserId, RoomId, UserId}; +use tokio::sync::Mutex; use crate::Result; @@ -33,7 +31,7 @@ impl Service { } #[tracing::instrument(skip(self))] - pub fn lazy_load_mark_sent( + pub async fn lazy_load_mark_sent( &self, user_id: &UserId, device_id: &DeviceId, @@ -41,7 +39,7 @@ impl Service { lazy_load: HashSet, count: PduCount, ) { - self.lazy_load_waiting.lock().unwrap().insert( + self.lazy_load_waiting.lock().await.insert( ( user_id.to_owned(), device_id.to_owned(), @@ -53,14 +51,14 @@ impl Service { } #[tracing::instrument(skip(self))] - pub fn lazy_load_confirm_delivery( + pub async fn lazy_load_confirm_delivery( &self, user_id: &UserId, device_id: &DeviceId, room_id: &RoomId, since: PduCount, ) -> Result<()> { - if let Some(user_ids) = self.lazy_load_waiting.lock().unwrap().remove(&( + if let Some(user_ids) = self.lazy_load_waiting.lock().await.remove(&( user_id.to_owned(), device_id.to_owned(), room_id.to_owned(), diff --git a/src/service/rooms/spaces/mod.rs b/src/service/rooms/spaces/mod.rs index b0a9ed2a..981d4a37 100644 --- a/src/service/rooms/spaces/mod.rs +++ b/src/service/rooms/spaces/mod.rs @@ -1,4 +1,4 @@ -use std::sync::{Arc, Mutex}; +use std::sync::Arc; use lru_cache::LruCache; use ruma::{ @@ -25,6 +25,7 @@ use ruma::{ space::SpaceRoomJoinRule, OwnedRoomId, RoomId, UserId, }; +use tokio::sync::Mutex; use tracing::{debug, error, warn}; @@ -79,7 +80,7 @@ impl Service { if let Some(cached) = self .roomid_spacechunk_cache .lock() - .unwrap() + .await .get_mut(¤t_room.to_owned()) .as_ref() { @@ -171,7 +172,7 @@ impl Service { .transpose()? .unwrap_or(JoinRule::Invite); - self.roomid_spacechunk_cache.lock().unwrap().insert( + self.roomid_spacechunk_cache.lock().await.insert( current_room.clone(), Some(CachedSpaceChunk { chunk, @@ -265,7 +266,7 @@ impl Service { } } - self.roomid_spacechunk_cache.lock().unwrap().insert( + self.roomid_spacechunk_cache.lock().await.insert( current_room.clone(), Some(CachedSpaceChunk { chunk, @@ -289,7 +290,7 @@ impl Service { } else { self.roomid_spacechunk_cache .lock() - .unwrap() + .await .insert(current_room.clone(), None); } } diff --git a/src/service/rooms/state/mod.rs b/src/service/rooms/state/mod.rs index c209eb5a..f6581bb5 100644 --- a/src/service/rooms/state/mod.rs +++ b/src/service/rooms/state/mod.rs @@ -95,7 +95,7 @@ impl Service { .spaces .roomid_spacechunk_cache .lock() - .unwrap() + .await .remove(&pdu.room_id); } _ => continue, diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index b66fc645..097cc82f 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -2,12 +2,8 @@ mod data; use std::{ cmp::Ordering, - collections::{BTreeMap, HashMap}, -}; - -use std::{ - collections::HashSet, - sync::{Arc, Mutex, RwLock}, + collections::{BTreeMap, HashMap, HashSet}, + sync::Arc, }; pub use data::Data; @@ -32,7 +28,7 @@ use ruma::{ }; use serde::Deserialize; use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; -use tokio::sync::MutexGuard; +use tokio::sync::{Mutex, MutexGuard, RwLock}; use tracing::{error, info, warn}; use crate::{ @@ -201,7 +197,7 @@ impl Service { /// /// Returns pdu id #[tracing::instrument(skip(self, pdu, pdu_json, leaves))] - pub fn append_pdu<'a>( + pub async fn append_pdu<'a>( &self, pdu: &PduEvent, mut pdu_json: CanonicalJsonObject, @@ -263,11 +259,11 @@ impl Service { .globals .roomid_mutex_insert .write() - .unwrap() + .await .entry(pdu.room_id.clone()) .or_default(), ); - let insert_lock = mutex_insert.lock().unwrap(); + let insert_lock = mutex_insert.lock().await; let count1 = services().globals.next_count()?; // Mark as read first so the sending client doesn't get a notification even if appending @@ -395,7 +391,7 @@ impl Service { .spaces .roomid_spacechunk_cache .lock() - .unwrap() + .await .remove(&pdu.room_id); } } @@ -806,7 +802,7 @@ impl Service { /// Creates a new persisted data unit and adds it to a room. This function takes a /// roomid_mutex_state, meaning that only this function is able to mutate the room state. #[tracing::instrument(skip(self, state_lock))] - pub fn build_and_append_pdu( + pub async fn build_and_append_pdu( &self, pdu_builder: PduBuilder, sender: &UserId, @@ -902,14 +898,16 @@ impl Service { // pdu without it's state. This is okay because append_pdu can't fail. let statehashid = services().rooms.state.append_to_state(&pdu)?; - let pdu_id = self.append_pdu( - &pdu, - pdu_json, - // Since this PDU references all pdu_leaves we can update the leaves - // of the room - vec![(*pdu.event_id).to_owned()], - state_lock, - )?; + let pdu_id = self + .append_pdu( + &pdu, + pdu_json, + // Since this PDU references all pdu_leaves we can update the leaves + // of the room + vec![(*pdu.event_id).to_owned()], + state_lock, + ) + .await?; // We set the room state after inserting the pdu, so that we never have a moment in time // where events in the current room state do not exist @@ -947,7 +945,7 @@ impl Service { /// Append the incoming event setting the state snapshot to the state from the /// server that sent the event. #[tracing::instrument(skip_all)] - pub fn append_incoming_pdu<'a>( + pub async fn append_incoming_pdu<'a>( &self, pdu: &PduEvent, pdu_json: CanonicalJsonObject, @@ -977,11 +975,11 @@ impl Service { return Ok(None); } - let pdu_id = - services() - .rooms - .timeline - .append_pdu(pdu, pdu_json, new_room_leaves, state_lock)?; + let pdu_id = services() + .rooms + .timeline + .append_pdu(pdu, pdu_json, new_room_leaves, state_lock) + .await?; Ok(Some(pdu_id)) } @@ -1118,7 +1116,7 @@ impl Service { .globals .roomid_mutex_federation .write() - .unwrap() + .await .entry(room_id.to_owned()) .or_default(), ); @@ -1150,11 +1148,11 @@ impl Service { .globals .roomid_mutex_insert .write() - .unwrap() + .await .entry(room_id.clone()) .or_default(), ); - let insert_lock = mutex_insert.lock().unwrap(); + let insert_lock = mutex_insert.lock().await; let count = services().globals.next_count()?; let mut pdu_id = shortroomid.to_be_bytes().to_vec(); diff --git a/src/service/users/mod.rs b/src/service/users/mod.rs index fb983a41..c83463ed 100644 --- a/src/service/users/mod.rs +++ b/src/service/users/mod.rs @@ -45,7 +45,7 @@ impl Service { self.db.exists(user_id) } - pub fn forget_sync_request_connection( + pub async fn forget_sync_request_connection( &self, user_id: OwnedUserId, device_id: OwnedDeviceId, @@ -186,7 +186,7 @@ impl Service { cached.known_rooms.clone() } - pub fn update_sync_subscriptions( + pub async fn update_sync_subscriptions( &self, user_id: OwnedUserId, device_id: OwnedDeviceId, @@ -212,7 +212,7 @@ impl Service { cached.subscriptions = subscriptions; } - pub fn update_sync_known_rooms( + pub async fn update_sync_known_rooms( &self, user_id: OwnedUserId, device_id: OwnedDeviceId, From c58af8485de8eb5e01ad0a2c1f2669102efa7754 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Tue, 5 Mar 2024 19:58:39 +0000 Subject: [PATCH 074/129] revert: remove dependency on async_recursion --- Cargo.lock | 12 - Cargo.toml | 1 - src/service/rooms/event_handler/mod.rs | 289 +++++++++++++------------ 3 files changed, 146 insertions(+), 156 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 426661bf..e99928e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,17 +80,6 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002" -[[package]] -name = "async-recursion" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "async-trait" version = "0.1.77" @@ -385,7 +374,6 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" name = "conduit" version = "0.7.0-alpha" dependencies = [ - "async-recursion", "async-trait", "axum", "axum-server", diff --git a/Cargo.toml b/Cargo.toml index 93ff2f3b..e8c1c8bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -115,7 +115,6 @@ lazy_static = "1.4.0" async-trait = "0.1.68" sd-notify = { version = "0.4.1", optional = true } -async-recursion = "1.0.5" [target.'cfg(unix)'.dependencies] nix = { version = "0.26.2", features = ["resource"] } diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 7cc662ee..1547d406 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -8,7 +8,6 @@ use std::{ time::{Duration, Instant, SystemTime}, }; -use async_recursion::async_recursion; use futures_util::{stream::FuturesUnordered, Future, StreamExt}; use ruma::{ api::{ @@ -1044,8 +1043,7 @@ impl Service { /// d. TODO: Ask other servers over federation? #[allow(clippy::type_complexity)] #[tracing::instrument(skip_all)] - #[async_recursion] - pub(crate) async fn fetch_and_handle_outliers<'a>( + pub(crate) fn fetch_and_handle_outliers<'a>( &'a self, origin: &'a ServerName, events: &'a [Arc], @@ -1053,175 +1051,180 @@ impl Service { room_id: &'a RoomId, room_version_id: &'a RoomVersionId, pub_key_map: &'a RwLock>>, - ) -> Vec<(Arc, Option>)> { - let back_off = |id| async move { - match services() - .globals - .bad_event_ratelimiter - .write() - .await - .entry(id) - { - hash_map::Entry::Vacant(e) => { - e.insert((Instant::now(), 1)); - } - hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1), - } - }; - - let mut pdus = vec![]; - for id in events { - // a. Look in the main timeline (pduid_pdu tree) - // b. Look at outlier pdu tree - // (get_pdu_json checks both) - if let Ok(Some(local_pdu)) = services().rooms.timeline.get_pdu(id) { - trace!("Found {} in db", id); - pdus.push((local_pdu, None)); - continue; - } - - // c. Ask origin server over federation - // We also handle its auth chain here so we don't get a stack overflow in - // handle_outlier_pdu. - let mut todo_auth_events = vec![Arc::clone(id)]; - let mut events_in_reverse_order = Vec::new(); - let mut events_all = HashSet::new(); - let mut i = 0; - while let Some(next_id) = todo_auth_events.pop() { - if let Some((time, tries)) = services() + ) -> AsyncRecursiveType<'a, Vec<(Arc, Option>)>> + { + Box::pin(async move { + let back_off = |id| async move { + match services() .globals .bad_event_ratelimiter - .read() + .write() .await - .get(&*next_id) + .entry(id) { - // Exponential backoff - let mut min_elapsed_duration = - Duration::from_secs(5 * 60) * (*tries) * (*tries); - if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) { - min_elapsed_duration = Duration::from_secs(60 * 60 * 24); + hash_map::Entry::Vacant(e) => { + e.insert((Instant::now(), 1)); } - - if time.elapsed() < min_elapsed_duration { - info!("Backing off from {}", next_id); - continue; + hash_map::Entry::Occupied(mut e) => { + *e.get_mut() = (Instant::now(), e.get().1 + 1) } } + }; - if events_all.contains(&next_id) { + let mut pdus = vec![]; + for id in events { + // a. Look in the main timeline (pduid_pdu tree) + // b. Look at outlier pdu tree + // (get_pdu_json checks both) + if let Ok(Some(local_pdu)) = services().rooms.timeline.get_pdu(id) { + trace!("Found {} in db", id); + pdus.push((local_pdu, None)); continue; } - i += 1; - if i % 100 == 0 { - tokio::task::yield_now().await; - } + // c. Ask origin server over federation + // We also handle its auth chain here so we don't get a stack overflow in + // handle_outlier_pdu. + let mut todo_auth_events = vec![Arc::clone(id)]; + let mut events_in_reverse_order = Vec::new(); + let mut events_all = HashSet::new(); + let mut i = 0; + while let Some(next_id) = todo_auth_events.pop() { + if let Some((time, tries)) = services() + .globals + .bad_event_ratelimiter + .read() + .await + .get(&*next_id) + { + // Exponential backoff + let mut min_elapsed_duration = + Duration::from_secs(5 * 60) * (*tries) * (*tries); + if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) { + min_elapsed_duration = Duration::from_secs(60 * 60 * 24); + } - if let Ok(Some(_)) = services().rooms.timeline.get_pdu(&next_id) { - trace!("Found {} in db", next_id); - continue; - } + if time.elapsed() < min_elapsed_duration { + info!("Backing off from {}", next_id); + continue; + } + } - info!("Fetching {} over federation.", next_id); - match services() - .sending - .send_federation_request( - origin, - get_event::v1::Request { - event_id: (*next_id).to_owned(), - }, - ) - .await - { - Ok(res) => { - info!("Got {} over federation", next_id); - let (calculated_event_id, value) = - match pdu::gen_event_id_canonical_json(&res.pdu, room_version_id) { - Ok(t) => t, - Err(_) => { - back_off((*next_id).to_owned()).await; - continue; - } - }; + if events_all.contains(&next_id) { + continue; + } + + i += 1; + if i % 100 == 0 { + tokio::task::yield_now().await; + } + + if let Ok(Some(_)) = services().rooms.timeline.get_pdu(&next_id) { + trace!("Found {} in db", next_id); + continue; + } - if calculated_event_id != *next_id { - warn!("Server didn't return event id we requested: requested: {}, we got {}. Event: {:?}", + info!("Fetching {} over federation.", next_id); + match services() + .sending + .send_federation_request( + origin, + get_event::v1::Request { + event_id: (*next_id).to_owned(), + }, + ) + .await + { + Ok(res) => { + info!("Got {} over federation", next_id); + let (calculated_event_id, value) = + match pdu::gen_event_id_canonical_json(&res.pdu, room_version_id) { + Ok(t) => t, + Err(_) => { + back_off((*next_id).to_owned()).await; + continue; + } + }; + + if calculated_event_id != *next_id { + warn!("Server didn't return event id we requested: requested: {}, we got {}. Event: {:?}", next_id, calculated_event_id, &res.pdu); - } + } - if let Some(auth_events) = - value.get("auth_events").and_then(|c| c.as_array()) - { - for auth_event in auth_events { - if let Ok(auth_event) = - serde_json::from_value(auth_event.clone().into()) - { - let a: Arc = auth_event; - todo_auth_events.push(a); - } else { - warn!("Auth event id is not valid"); + if let Some(auth_events) = + value.get("auth_events").and_then(|c| c.as_array()) + { + for auth_event in auth_events { + if let Ok(auth_event) = + serde_json::from_value(auth_event.clone().into()) + { + let a: Arc = auth_event; + todo_auth_events.push(a); + } else { + warn!("Auth event id is not valid"); + } } + } else { + warn!("Auth event list invalid"); } - } else { - warn!("Auth event list invalid"); - } - events_in_reverse_order.push((next_id.clone(), value)); - events_all.insert(next_id); - } - Err(_) => { - warn!("Failed to fetch event: {}", next_id); - back_off((*next_id).to_owned()).await; + events_in_reverse_order.push((next_id.clone(), value)); + events_all.insert(next_id); + } + Err(_) => { + warn!("Failed to fetch event: {}", next_id); + back_off((*next_id).to_owned()).await; + } } } - } - for (next_id, value) in events_in_reverse_order.iter().rev() { - if let Some((time, tries)) = services() - .globals - .bad_event_ratelimiter - .read() - .await - .get(&**next_id) - { - // Exponential backoff - let mut min_elapsed_duration = - Duration::from_secs(5 * 60) * (*tries) * (*tries); - if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) { - min_elapsed_duration = Duration::from_secs(60 * 60 * 24); - } + for (next_id, value) in events_in_reverse_order.iter().rev() { + if let Some((time, tries)) = services() + .globals + .bad_event_ratelimiter + .read() + .await + .get(&**next_id) + { + // Exponential backoff + let mut min_elapsed_duration = + Duration::from_secs(5 * 60) * (*tries) * (*tries); + if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) { + min_elapsed_duration = Duration::from_secs(60 * 60 * 24); + } - if time.elapsed() < min_elapsed_duration { - info!("Backing off from {}", next_id); - continue; + if time.elapsed() < min_elapsed_duration { + info!("Backing off from {}", next_id); + continue; + } } - } - match self - .handle_outlier_pdu( - origin, - create_event, - next_id, - room_id, - value.clone(), - true, - pub_key_map, - ) - .await - { - Ok((pdu, json)) => { - if next_id == id { - pdus.push((pdu, Some(json))); + match self + .handle_outlier_pdu( + origin, + create_event, + next_id, + room_id, + value.clone(), + true, + pub_key_map, + ) + .await + { + Ok((pdu, json)) => { + if next_id == id { + pdus.push((pdu, Some(json))); + } + } + Err(e) => { + warn!("Authentication of event {} failed: {:?}", next_id, e); + back_off((**next_id).to_owned()).await; } - } - Err(e) => { - warn!("Authentication of event {} failed: {:?}", next_id, e); - back_off((**next_id).to_owned()).await; } } } - } - pdus + pdus + }) } async fn fetch_unknown_prev_events( From e33d8430d31d022933d37ad74bacdc482590c018 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Tue, 5 Mar 2024 20:00:22 +0000 Subject: [PATCH 075/129] typo: colsures -> closures --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 9c1170dd..13bda4c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ mod database; mod service; mod utils; -// Not async due to services() being used in many closures, and async colsures are not stable as of writing +// Not async due to services() being used in many closures, and async closures are not stable as of writing // This is the case for every other occurence of sync Mutex/RwLock, except for database related ones, where // the current maintainer (Timo) as asked to not modify those use std::sync::RwLock; From 17dd8cb918b4592fb45ebbaa297414100ffe939c Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Tue, 5 Mar 2024 20:15:11 +0000 Subject: [PATCH 076/129] style: rename Sync(Mutex|RwLock) to Std(Mutex|RwLock) --- src/service/globals/mod.rs | 10 +++++----- src/service/mod.rs | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/service/globals/mod.rs b/src/service/globals/mod.rs index c3e02ad5..22dc6959 100644 --- a/src/service/globals/mod.rs +++ b/src/service/globals/mod.rs @@ -31,7 +31,7 @@ use std::{ path::PathBuf, sync::{ atomic::{self, AtomicBool}, - Arc, RwLock as SyncRwLock, + Arc, RwLock as StdRwLock, }, time::{Duration, Instant}, }; @@ -53,7 +53,7 @@ pub struct Service { pub db: &'static dyn Data, pub actual_destination_cache: Arc>, // actual_destination, host - pub tls_name_override: Arc>, + pub tls_name_override: Arc>, pub config: Config, keypair: Arc, dns_resolver: TokioAsyncResolver, @@ -109,11 +109,11 @@ impl Default for RotationHandler { pub struct Resolver { inner: GaiResolver, - overrides: Arc>, + overrides: Arc>, } impl Resolver { - pub fn new(overrides: Arc>) -> Self { + pub fn new(overrides: Arc>) -> Self { Resolver { inner: GaiResolver::new(), overrides, @@ -159,7 +159,7 @@ impl Service { } }; - let tls_name_override = Arc::new(SyncRwLock::new(TlsNameMap::new())); + let tls_name_override = Arc::new(StdRwLock::new(TlsNameMap::new())); let jwt_decoding_key = config .jwt_secret diff --git a/src/service/mod.rs b/src/service/mod.rs index c1616c40..8f9fb0a5 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -1,6 +1,6 @@ use std::{ collections::{BTreeMap, HashMap}, - sync::{Arc, Mutex as SyncMutex}, + sync::{Arc, Mutex as StdMutex}, }; use lru_cache::LruCache; @@ -80,17 +80,17 @@ impl Services { state: rooms::state::Service { db }, state_accessor: rooms::state_accessor::Service { db, - server_visibility_cache: SyncMutex::new(LruCache::new( + server_visibility_cache: StdMutex::new(LruCache::new( (100.0 * config.conduit_cache_capacity_modifier) as usize, )), - user_visibility_cache: SyncMutex::new(LruCache::new( + user_visibility_cache: StdMutex::new(LruCache::new( (100.0 * config.conduit_cache_capacity_modifier) as usize, )), }, state_cache: rooms::state_cache::Service { db }, state_compressor: rooms::state_compressor::Service { db, - stateinfo_cache: SyncMutex::new(LruCache::new( + stateinfo_cache: StdMutex::new(LruCache::new( (100.0 * config.conduit_cache_capacity_modifier) as usize, )), }, @@ -108,7 +108,7 @@ impl Services { uiaa: uiaa::Service { db }, users: users::Service { db, - connections: SyncMutex::new(BTreeMap::new()), + connections: StdMutex::new(BTreeMap::new()), }, account_data: account_data::Service { db }, admin: admin::Service::build(), From 07bb369c5cee46fba463f94dfb95151f46d2c8f9 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Tue, 5 Mar 2024 20:20:19 +0000 Subject: [PATCH 077/129] perf: remove unnecessary async --- src/api/client_server/sync.rs | 66 ++++++++++++++--------------------- src/service/users/mod.rs | 6 ++-- 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 5ac00c60..c510f5f5 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1197,14 +1197,11 @@ pub async fn sync_events_v4_route( if globalsince == 0 { if let Some(conn_id) = &body.conn_id { - services() - .users - .forget_sync_request_connection( - sender_user.clone(), - sender_device.clone(), - conn_id.clone(), - ) - .await + services().users.forget_sync_request_connection( + sender_user.clone(), + sender_device.clone(), + conn_id.clone(), + ) } } @@ -1474,17 +1471,14 @@ pub async fn sync_events_v4_route( ); if let Some(conn_id) = &body.conn_id { - services() - .users - .update_sync_known_rooms( - sender_user.clone(), - sender_device.clone(), - conn_id.clone(), - list_id, - new_known_rooms, - globalsince, - ) - .await; + services().users.update_sync_known_rooms( + sender_user.clone(), + sender_device.clone(), + conn_id.clone(), + list_id, + new_known_rooms, + globalsince, + ); } } @@ -1516,29 +1510,23 @@ pub async fn sync_events_v4_route( } if let Some(conn_id) = &body.conn_id { - services() - .users - .update_sync_known_rooms( - sender_user.clone(), - sender_device.clone(), - conn_id.clone(), - "subscriptions".to_owned(), - known_subscription_rooms, - globalsince, - ) - .await; + services().users.update_sync_known_rooms( + sender_user.clone(), + sender_device.clone(), + conn_id.clone(), + "subscriptions".to_owned(), + known_subscription_rooms, + globalsince, + ); } if let Some(conn_id) = &body.conn_id { - services() - .users - .update_sync_subscriptions( - sender_user.clone(), - sender_device.clone(), - conn_id.clone(), - body.room_subscriptions, - ) - .await; + services().users.update_sync_subscriptions( + sender_user.clone(), + sender_device.clone(), + conn_id.clone(), + body.room_subscriptions, + ); } let mut rooms = BTreeMap::new(); diff --git a/src/service/users/mod.rs b/src/service/users/mod.rs index c83463ed..fb983a41 100644 --- a/src/service/users/mod.rs +++ b/src/service/users/mod.rs @@ -45,7 +45,7 @@ impl Service { self.db.exists(user_id) } - pub async fn forget_sync_request_connection( + pub fn forget_sync_request_connection( &self, user_id: OwnedUserId, device_id: OwnedDeviceId, @@ -186,7 +186,7 @@ impl Service { cached.known_rooms.clone() } - pub async fn update_sync_subscriptions( + pub fn update_sync_subscriptions( &self, user_id: OwnedUserId, device_id: OwnedDeviceId, @@ -212,7 +212,7 @@ impl Service { cached.subscriptions = subscriptions; } - pub async fn update_sync_known_rooms( + pub fn update_sync_known_rooms( &self, user_id: OwnedUserId, device_id: OwnedDeviceId, From ee7efdd403ec514c84d20c51ad7536c4b38f3349 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Tue, 5 Mar 2024 20:31:40 +0000 Subject: [PATCH 078/129] typo: as -> has --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 13bda4c2..70c6f373 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ mod utils; // Not async due to services() being used in many closures, and async closures are not stable as of writing // This is the case for every other occurence of sync Mutex/RwLock, except for database related ones, where -// the current maintainer (Timo) as asked to not modify those +// the current maintainer (Timo) has asked to not modify those use std::sync::RwLock; pub use api::ruma_wrapper::{Ruma, RumaResponse}; From 161ad8f9a4dc56695656cd3c4a1a750bd6f93514 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 4 Mar 2024 22:37:23 -0800 Subject: [PATCH 079/129] update to latest crane before a regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Once these issues are fixed, or at least just the one against crane, we can go back to `ref=master`. Flake lock file updates: • Updated input 'crane': 'github:ipetkov/crane/c798790eabec3e3da48190ae3698ac227aab770c' (2024-01-28) → 'github:ipetkov/crane/2c653e4478476a52c6aa3ac0495e4dea7449ea0e' (2024-02-11) --- flake.lock | 8 ++++---- flake.nix | 7 ++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/flake.lock b/flake.lock index 1c97e5c6..e8748923 100644 --- a/flake.lock +++ b/flake.lock @@ -51,17 +51,17 @@ ] }, "locked": { - "lastModified": 1706473964, - "narHash": "sha256-Fq6xleee/TsX6NbtoRuI96bBuDHMU57PrcK9z1QEKbk=", + "lastModified": 1707685877, + "narHash": "sha256-XoXRS+5whotelr1rHiZle5t5hDg9kpguS5yk8c8qzOc=", "owner": "ipetkov", "repo": "crane", - "rev": "c798790eabec3e3da48190ae3698ac227aab770c", + "rev": "2c653e4478476a52c6aa3ac0495e4dea7449ea0e", "type": "github" }, "original": { "owner": "ipetkov", - "ref": "master", "repo": "crane", + "rev": "2c653e4478476a52c6aa3ac0495e4dea7449ea0e", "type": "github" } }, diff --git a/flake.nix b/flake.nix index 6ca4c72d..d1a947a6 100644 --- a/flake.nix +++ b/flake.nix @@ -13,7 +13,12 @@ inputs.nixpkgs.follows = "nixpkgs"; }; crane = { - url = "github:ipetkov/crane?ref=master"; + # Pin latest crane that's not affected by the following bugs: + # + # * + # * + # * + url = "github:ipetkov/crane?rev=2c653e4478476a52c6aa3ac0495e4dea7449ea0e"; inputs.nixpkgs.follows = "nixpkgs"; }; attic.url = "github:zhaofengli/attic?ref=main"; From e70f33741c04781ece5032c10a9261a1a72d3780 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 4 Mar 2024 22:40:47 -0800 Subject: [PATCH 080/129] update flake.lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also switch names to match the newer upstream nixpkgs code. Flake lock file updates: • Updated input 'attic': 'github:zhaofengli/attic/fbe252a5c21febbe920c025560cbd63b20e24f3b' (2024-01-18) → 'github:zhaofengli/attic/6eabc3f02fae3683bffab483e614bebfcd476b21' (2024-02-14) • Updated input 'fenix': 'github:nix-community/fenix/e132ea0eb0c799a2109a91688e499d7bf4962801' (2024-01-18) → 'github:nix-community/fenix/c8943ea9e98d41325ff57d4ec14736d330b321b2' (2024-03-05) • Updated input 'fenix/rust-analyzer-src': 'github:rust-lang/rust-analyzer/9d9b34354d2f13e33568c9c55b226dd014a146a0' (2024-01-17) → 'github:rust-lang/rust-analyzer/9f14343f9ee24f53f17492c5f9b653427e2ad15e' (2024-03-04) • Updated input 'flake-utils': 'github:numtide/flake-utils/1ef2e671c3b0c19053962c07dbda38332dcebf26' (2024-01-15) → 'github:numtide/flake-utils/d465f4819400de7c8d874d50b982301f28a84605' (2024-02-28) • Updated input 'nixpkgs': 'github:NixOS/nixpkgs/842d9d80cfd4560648c785f8a4e6f3b096790e19' (2024-01-17) → 'github:NixOS/nixpkgs/b8697e57f10292a6165a20f03d2f42920dfaf973' (2024-03-03) --- flake.lock | 30 +++++++++++++++--------------- flake.nix | 10 +++++----- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/flake.lock b/flake.lock index e8748923..1c2142f2 100644 --- a/flake.lock +++ b/flake.lock @@ -9,11 +9,11 @@ "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1705617092, - "narHash": "sha256-n9PK4O4X4S1JkwpkMuYm1wHZYJzRqif8g3RuVIPD+rY=", + "lastModified": 1707922053, + "narHash": "sha256-wSZjK+rOXn+UQiP1NbdNn5/UW6UcBxjvlqr2wh++MbM=", "owner": "zhaofengli", "repo": "attic", - "rev": "fbe252a5c21febbe920c025560cbd63b20e24f3b", + "rev": "6eabc3f02fae3683bffab483e614bebfcd476b21", "type": "github" }, "original": { @@ -73,11 +73,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1705559032, - "narHash": "sha256-Cb+Jd1+Gz4Wi+8elPnUIHnqQmE1qjDRZ+PsJaPaAffY=", + "lastModified": 1709619709, + "narHash": "sha256-l6EPVJfwfelWST7qWQeP6t/TDK3HHv5uUB1b2vw4mOQ=", "owner": "nix-community", "repo": "fenix", - "rev": "e132ea0eb0c799a2109a91688e499d7bf4962801", + "rev": "c8943ea9e98d41325ff57d4ec14736d330b321b2", "type": "github" }, "original": { @@ -138,11 +138,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1705309234, - "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "lastModified": 1709126324, + "narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=", "owner": "numtide", "repo": "flake-utils", - "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "rev": "d465f4819400de7c8d874d50b982301f28a84605", "type": "github" }, "original": { @@ -200,11 +200,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1705496572, - "narHash": "sha256-rPIe9G5EBLXdBdn9ilGc0nq082lzQd0xGGe092R/5QE=", + "lastModified": 1709479366, + "narHash": "sha256-n6F0n8UV6lnTZbYPl1A9q1BS0p4hduAv1mGAP17CVd0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "842d9d80cfd4560648c785f8a4e6f3b096790e19", + "rev": "b8697e57f10292a6165a20f03d2f42920dfaf973", "type": "github" }, "original": { @@ -228,11 +228,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1705523001, - "narHash": "sha256-TWq5vJ6m+9HGSDMsQAmz1TMegMi79R3TTyKjnPWsQp8=", + "lastModified": 1709571018, + "narHash": "sha256-ISFrxHxE0J5g7lDAscbK88hwaT5uewvWoma9TlFmRzM=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "9d9b34354d2f13e33568c9c55b226dd014a146a0", + "rev": "9f14343f9ee24f53f17492c5f9b653427e2ad15e", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index d1a947a6..460bffc3 100644 --- a/flake.nix +++ b/flake.nix @@ -55,7 +55,7 @@ # bindgen needs the build platform's libclang. Apparently due to # "splicing weirdness", pkgs.rustPlatform.bindgenHook on its own doesn't # quite do the right thing here. - pkgs.buildPackages.rustPlatform.bindgenHook + pkgs.pkgsBuildHost.rustPlatform.bindgenHook ]; env = pkgs: { @@ -83,7 +83,7 @@ # these flags when using a different linker. Don't ask me why, # though, because I don't know. All I know is it breaks otherwise. # - # [0]: https://github.com/NixOS/nixpkgs/blob/612f97239e2cc474c13c9dafa0df378058c5ad8d/pkgs/build-support/rust/lib/default.nix#L36-L39 + # [0]: https://github.com/NixOS/nixpkgs/blob/5cdb38bb16c6d0a38779db14fcc766bc1b2394d6/pkgs/build-support/rust/lib/default.nix#L37-L40 ( # Nixpkgs doesn't check for x86_64 here but we do, because I # observed a failure building statically for x86_64 without @@ -107,7 +107,7 @@ # even covers the case of build scripts that need native code compiled and # run on the build platform (I think). # - # [0]: https://github.com/NixOS/nixpkgs/blob/612f97239e2cc474c13c9dafa0df378058c5ad8d/pkgs/build-support/rust/lib/default.nix#L64-L78 + # [0]: https://github.com/NixOS/nixpkgs/blob/5cdb38bb16c6d0a38779db14fcc766bc1b2394d6/pkgs/build-support/rust/lib/default.nix#L57-L80 // ( let inherit (pkgs.rust.lib) envVars; @@ -145,8 +145,8 @@ "CC_${cargoEnvVarTarget}" = envVars.ccForBuild; "CXX_${cargoEnvVarTarget}" = envVars.cxxForBuild; "CARGO_TARGET_${cargoEnvVarTarget}_LINKER" = envVars.linkerForBuild; - HOST_CC = "${pkgs.buildPackages.stdenv.cc}/bin/cc"; - HOST_CXX = "${pkgs.buildPackages.stdenv.cc}/bin/c++"; + HOST_CC = "${pkgs.pkgsBuildHost.stdenv.cc}/bin/cc"; + HOST_CXX = "${pkgs.pkgsBuildHost.stdenv.cc}/bin/c++"; } )); From 10b7b174b6bac0921f704ab768799128bf298ef1 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 4 Mar 2024 20:49:41 -0800 Subject: [PATCH 081/129] fix documented target triple Even though it doesn't really matter because it's containerized anyway. --- DEPLOY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPLOY.md b/DEPLOY.md index dcc41bdc..1a6f4835 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -37,7 +37,7 @@ If you use a system with an older glibc version (e.g. RHEL8), you might need to | `x86_64-unknown-linux-gnu` | Dynamically linked Debian package | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit.deb?job=debian:x86_64-unknown-linux-gnu) | | `x86_64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit?job=static:x86_64-unknown-linux-musl) | | `aarch64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit?job=static:aarch64-unknown-linux-musl) | -| `x86_64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-amd64.tar.gz?job=oci-image:x86_64-unknown-linux-musl) | +| `x86_64-unknown-linux-gnu` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-amd64.tar.gz?job=oci-image:x86_64-unknown-linux-musl) | | `aarch64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-arm64v8.tar.gz?job=oci-image:aarch64-unknown-linux-musl) | ```bash From 4f352a711af865ca7e75e772a09aa96fc3219af4 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 4 Mar 2024 20:42:58 -0800 Subject: [PATCH 082/129] add trailing newline to file Please fix your editor configuration... --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4f4aa695..59de64f3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -177,4 +177,4 @@ oci-image:push-dockerhub: variables: IMAGE_NAME: matrixconduit/matrix-conduit before_script: - - docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_PASSWORD \ No newline at end of file + - docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_PASSWORD From 6281c64c331d9dd70b018eda1a124a0f12164f82 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 4 Mar 2024 20:44:15 -0800 Subject: [PATCH 083/129] upgrade nixos/nix image --- .gitlab-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 59de64f3..2fe90bf7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,7 +34,7 @@ before_script: ci: stage: ci - image: nixos/nix:2.19.2 + image: nixos/nix:2.20.4 script: - direnv exec . engage cache: @@ -45,7 +45,7 @@ ci: static:x86_64-unknown-linux-musl: stage: artifacts - image: nixos/nix:2.19.2 + image: nixos/nix:2.20.4 script: # Push artifacts and build requirements to binary cache - ./bin/nix-build-and-cache .#static-x86_64-unknown-linux-musl @@ -58,7 +58,7 @@ static:x86_64-unknown-linux-musl: static:aarch64-unknown-linux-musl: stage: artifacts - image: nixos/nix:2.19.2 + image: nixos/nix:2.20.4 script: # Push artifacts and build requirements to binary cache - ./bin/nix-build-and-cache .#static-aarch64-unknown-linux-musl @@ -74,7 +74,7 @@ static:aarch64-unknown-linux-musl: # all containerized anyway. oci-image:x86_64-unknown-linux-gnu: stage: artifacts - image: nixos/nix:2.19.2 + image: nixos/nix:2.20.4 script: # Push artifacts and build requirements to binary cache # @@ -96,7 +96,7 @@ oci-image:aarch64-unknown-linux-musl: # Wait for the static binary job to finish before starting so we don't have # to build that twice for no reason - static:aarch64-unknown-linux-musl - image: nixos/nix:2.19.2 + image: nixos/nix:2.20.4 script: # Push artifacts and build requirements to binary cache - ./bin/nix-build-and-cache .#oci-image-aarch64-unknown-linux-musl From 4e09c9e58a9de466887db659a6f9e02999a2f035 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 4 Mar 2024 20:38:57 -0800 Subject: [PATCH 084/129] build all nix-based artifacts in a single job This will reduce the amount of full builds that need to be done by runs that don't have write access to the nix binary cache. --- .gitlab-ci.yml | 61 +++++++++++--------------------------------------- DEPLOY.md | 8 +++---- 2 files changed, 17 insertions(+), 52 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2fe90bf7..b24481b1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,68 +43,34 @@ ci: - target - .gitlab-ci.d -static:x86_64-unknown-linux-musl: +nix:artifacts: stage: artifacts image: nixos/nix:2.20.4 script: - # Push artifacts and build requirements to binary cache - ./bin/nix-build-and-cache .#static-x86_64-unknown-linux-musl + - cp result/bin/conduit x86_64-unknown-linux-musl - # Make the output less difficult to find - - cp result/bin/conduit conduit - artifacts: - paths: - - conduit - -static:aarch64-unknown-linux-musl: - stage: artifacts - image: nixos/nix:2.20.4 - script: - # Push artifacts and build requirements to binary cache - - ./bin/nix-build-and-cache .#static-aarch64-unknown-linux-musl - - # Make the output less difficult to find - - cp result/bin/conduit conduit - artifacts: - paths: - - conduit - -# Note that although we have an `oci-image-x86_64-unknown-linux-musl` output, -# we don't build it because it would be largely redundant to this one since it's -# all containerized anyway. -oci-image:x86_64-unknown-linux-gnu: - stage: artifacts - image: nixos/nix:2.20.4 - script: - # Push artifacts and build requirements to binary cache - # # Since the OCI image package is based on the binary package, this has the # fun side effect of uploading the normal binary too. Conduit users who are # deploying with Nix can leverage this fact by adding our binary cache to # their systems. + # + # Note that although we have an `oci-image-x86_64-unknown-linux-musl` + # output, we don't build it because it would be largely redundant to this + # one since it's all containerized anyway. - ./bin/nix-build-and-cache .#oci-image - - # Make the output less difficult to find - cp result oci-image-amd64.tar.gz - artifacts: - paths: - - oci-image-amd64.tar.gz -oci-image:aarch64-unknown-linux-musl: - stage: artifacts - needs: - # Wait for the static binary job to finish before starting so we don't have - # to build that twice for no reason - - static:aarch64-unknown-linux-musl - image: nixos/nix:2.20.4 - script: - # Push artifacts and build requirements to binary cache - - ./bin/nix-build-and-cache .#oci-image-aarch64-unknown-linux-musl + - ./bin/nix-build-and-cache .#static-aarch64-unknown-linux-musl + - cp result/bin/conduit aarch64-unknown-linux-musl - # Make the output less difficult to find + - ./bin/nix-build-and-cache .#oci-image-aarch64-unknown-linux-musl - cp result oci-image-arm64v8.tar.gz artifacts: paths: + - x86_64-unknown-linux-musl + - aarch64-unknown-linux-musl + - oci-image-amd64.tar.gz - oci-image-arm64v8.tar.gz debian:x86_64-unknown-linux-gnu: @@ -158,8 +124,7 @@ debian:x86_64-unknown-linux-gnu: docker manifest push $IMAGE_NAME:latest fi dependencies: - - oci-image:x86_64-unknown-linux-gnu - - oci-image:aarch64-unknown-linux-musl + - nix:artifacts only: - next - master diff --git a/DEPLOY.md b/DEPLOY.md index 1a6f4835..ccf52c32 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -35,10 +35,10 @@ If you use a system with an older glibc version (e.g. RHEL8), you might need to | Target | Type | Download | |-|-|-| | `x86_64-unknown-linux-gnu` | Dynamically linked Debian package | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit.deb?job=debian:x86_64-unknown-linux-gnu) | -| `x86_64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit?job=static:x86_64-unknown-linux-musl) | -| `aarch64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit?job=static:aarch64-unknown-linux-musl) | -| `x86_64-unknown-linux-gnu` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-amd64.tar.gz?job=oci-image:x86_64-unknown-linux-musl) | -| `aarch64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-arm64v8.tar.gz?job=oci-image:aarch64-unknown-linux-musl) | +| `x86_64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/x86_64-unknown-linux-musl?job=nix:artifacts) | +| `aarch64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/aarch64-unknown-linux-musl?job=nix:artifacts) | +| `x86_64-unknown-linux-gnu` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-amd64.tar.gz?job=nix:artifacts) | +| `aarch64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-arm64v8.tar.gz?job=nix:artifacts) | ```bash $ sudo wget -O /usr/local/bin/matrix-conduit From d5a9c6ac32e15ca11a0f684274be9ca8356cdfcc Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 4 Mar 2024 23:12:17 -0800 Subject: [PATCH 085/129] use nix-built binary to produce debian package Currently just for `x86_64-unknown-linux-musl`. Theoretically, we can use this same mechanism for `aarch64-unknown-linux-musl`. Practically, I'm not sure just this will even work. --- .gitlab-ci.yml | 30 ++++++++---------------------- DEPLOY.md | 10 +++++----- flake.nix | 3 +++ 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b24481b1..866ef11f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,13 +43,18 @@ ci: - target - .gitlab-ci.d -nix:artifacts: +artifacts: stage: artifacts image: nixos/nix:2.20.4 script: - ./bin/nix-build-and-cache .#static-x86_64-unknown-linux-musl - cp result/bin/conduit x86_64-unknown-linux-musl + - mkdir -p target/release + - cp result/bin/conduit target/release + - direnv exec . cargo deb --no-build + - mv target/debian/*.deb x86_64-unknown-linux-musl.deb + # Since the OCI image package is based on the binary package, this has the # fun side effect of uploading the normal binary too. Conduit users who are # deploying with Nix can leverage this fact by adding our binary cache to @@ -70,29 +75,10 @@ nix:artifacts: paths: - x86_64-unknown-linux-musl - aarch64-unknown-linux-musl + - x86_64-unknown-linux-musl.deb - oci-image-amd64.tar.gz - oci-image-arm64v8.tar.gz -debian:x86_64-unknown-linux-gnu: - stage: artifacts - # See also `rust-toolchain.toml` - image: rust:1.75.0 - script: - - apt-get update && apt-get install -y --no-install-recommends libclang-dev - - cargo install cargo-deb - - cargo deb - - # Make the output less difficult to find - - mv target/debian/*.deb conduit.deb - artifacts: - paths: - - conduit.deb - cache: - key: debian - paths: - - target - - .gitlab-ci.d - .push-oci-image: stage: publish image: docker:25.0.0 @@ -124,7 +110,7 @@ debian:x86_64-unknown-linux-gnu: docker manifest push $IMAGE_NAME:latest fi dependencies: - - nix:artifacts + - artifacts only: - next - master diff --git a/DEPLOY.md b/DEPLOY.md index ccf52c32..dd279688 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -34,11 +34,11 @@ If you use a system with an older glibc version (e.g. RHEL8), you might need to | Target | Type | Download | |-|-|-| -| `x86_64-unknown-linux-gnu` | Dynamically linked Debian package | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/conduit.deb?job=debian:x86_64-unknown-linux-gnu) | -| `x86_64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/x86_64-unknown-linux-musl?job=nix:artifacts) | -| `aarch64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/aarch64-unknown-linux-musl?job=nix:artifacts) | -| `x86_64-unknown-linux-gnu` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-amd64.tar.gz?job=nix:artifacts) | -| `aarch64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-arm64v8.tar.gz?job=nix:artifacts) | +| `x86_64-unknown-linux-musl` | Statically linked Debian package | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/x86_64-unknown-linux-musl.deb?job=artifacts) | +| `x86_64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/x86_64-unknown-linux-musl?job=artifacts) | +| `aarch64-unknown-linux-musl` | Statically linked binary | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/aarch64-unknown-linux-musl?job=artifacts) | +| `x86_64-unknown-linux-gnu` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-amd64.tar.gz?job=artifacts) | +| `aarch64-unknown-linux-musl` | OCI image | [link](https://gitlab.com/api/v4/projects/famedly%2Fconduit/jobs/artifacts/next/raw/oci-image-arm64v8.tar.gz?job=artifacts) | ```bash $ sudo wget -O /usr/local/bin/matrix-conduit diff --git a/flake.nix b/flake.nix index 460bffc3..cc95aecb 100644 --- a/flake.nix +++ b/flake.nix @@ -252,6 +252,9 @@ ] ++ (with pkgsHost; [ engage + # Needed for producing Debian packages + cargo-deb + # Needed for Complement go olm From d411e9037c860368e433f9e413fc28b31f3e0e38 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Tue, 5 Mar 2024 12:05:50 -0800 Subject: [PATCH 086/129] upload all devshell inputs to the cache This will also include attic, so we don't need to explicitly do this in `./bin/nix-build-and-cache` anymore, which is good because that script gets called a good number of times and doing that repeatedly was a bit of a waste. --- .gitlab-ci.yml | 3 +++ bin/nix-build-and-cache | 15 +++++---------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 866ef11f..e0ed08ee 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -36,6 +36,9 @@ ci: stage: ci image: nixos/nix:2.20.4 script: + # Cache the inputs required for the devShell + - ./bin/nix-build-and-cache .#devShells.x86_64-linux.default.inputDerivation + - direnv exec . engage cache: key: nix diff --git a/bin/nix-build-and-cache b/bin/nix-build-and-cache index b37ebd85..0eb816c3 100755 --- a/bin/nix-build-and-cache +++ b/bin/nix-build-and-cache @@ -15,17 +15,12 @@ nix run --inputs-from . attic -- login \ https://nix.computer.surgery/conduit \ "$ATTIC_TOKEN" - push_args=( - # Attic and its build dependencies - "$(nix path-info --inputs-from . attic)" - "$(nix path-info --inputs-from . attic --derivation)" - - # The target installable and its build dependencies - "$(nix path-info "$INSTALLABLE" --derivation)" + # Push the target installable and its build dependencies + nix run --inputs-from . attic -- \ + push \ + conduit \ + "$(nix path-info "$INSTALLABLE" --derivation)" \ "$(nix path-info "$INSTALLABLE")" - ) - - nix run --inputs-from . attic -- push conduit "${push_args[@]}" else echo "\$ATTIC_TOKEN is unset, skipping uploading to the binary cache" fi From ae69da635b4745468896d43efd1f429d5312ca80 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 4 Mar 2024 23:47:46 -0800 Subject: [PATCH 087/129] allow overriding the attic endpoint And also the public key so that pulling from the new endpoint will work. This allows other people to host their own attic instances and configure their (CI) environment to override the default endpoint so e.g. they can take advantage of a binary cache without having write access to the official one. I didn't actually test this change but I think it should work. Also why'd I format the script like that, ew lol --- .gitlab-ci.yml | 4 ++++ bin/nix-build-and-cache | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e0ed08ee..0e56598c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,6 +15,10 @@ before_script: - if command -v nix > /dev/null; then echo "extra-substituters = https://nix.computer.surgery/conduit" >> /etc/nix/nix.conf; fi - if command -v nix > /dev/null; then echo "extra-trusted-public-keys = conduit:ZGAf6P6LhNvnoJJ3Me3PRg7tlLSrPxcQ2RiE5LIppjo=" >> /etc/nix/nix.conf; fi + # Add alternate binary cache + - if command -v nix > /dev/null && [ -n "$ATTIC_ENDPOINT" ]; then echo "extra-substituters = $ATTIC_ENDPOINT" >> /etc/nix/nix.conf; fi + - if command -v nix > /dev/null && [ -n "$ATTIC_PUBLIC_KEY" ]; then echo "extra-trusted-public-keys = $ATTIC_PUBLIC_KEY" >> /etc/nix/nix.conf; fi + # Add crane binary cache - if command -v nix > /dev/null; then echo "extra-substituters = https://crane.cachix.org" >> /etc/nix/nix.conf; fi - if command -v nix > /dev/null; then echo "extra-trusted-public-keys = crane.cachix.org-1:8Scfpmn9w+hGdXH/Q9tTLiYAE/2dnJYRJP7kl80GuRk=" >> /etc/nix/nix.conf; fi diff --git a/bin/nix-build-and-cache b/bin/nix-build-and-cache index 0eb816c3..350e1717 100755 --- a/bin/nix-build-and-cache +++ b/bin/nix-build-and-cache @@ -9,10 +9,10 @@ INSTALLABLE="$1" nix build "$@" if [ ! -z ${ATTIC_TOKEN+x} ]; then - -nix run --inputs-from . attic -- login \ - conduit \ - https://nix.computer.surgery/conduit \ + nix run --inputs-from . attic -- \ + login \ + conduit \ + "${ATTIC_ENDPOINT:-https://nix.computer.surgery/conduit}" \ "$ATTIC_TOKEN" # Push the target installable and its build dependencies From 0d2f1348daa573b3f0e577ffccfe605c88fab8b5 Mon Sep 17 00:00:00 2001 From: Samuel Meenzen Date: Wed, 6 Mar 2024 11:47:15 +0100 Subject: [PATCH 088/129] feat: run ci on demand to prevent unnecessary job executions --- .gitlab-ci.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0e56598c..348e7b19 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -49,6 +49,13 @@ ci: paths: - target - .gitlab-ci.d + rules: + # CI on upstream runners (only available for maintainers) + - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $IS_UPSTREAM_CI == "true" + # Manual CI on forks + - if: $IS_UPSTREAM_CI != "true" + when: manual + - if: $CI artifacts: stage: artifacts @@ -85,6 +92,14 @@ artifacts: - x86_64-unknown-linux-musl.deb - oci-image-amd64.tar.gz - oci-image-arm64v8.tar.gz + rules: + # CI required for all MRs + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + # Optional CI on forks + - if: $IS_UPSTREAM_CI != "true" + when: manual + allow_failure: true + - if: $CI .push-oci-image: stage: publish From fa930182aea942380f8db19b5e18152e17d9e634 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Wed, 27 Dec 2023 13:22:21 +0000 Subject: [PATCH 089/129] fix(appservices): don't panic on empty registration url perf(appservices): cache regex for namespaces --- src/api/appservice_server.rs | 166 ++++++++++---------- src/api/client_server/alias.rs | 34 ++-- src/api/ruma_wrapper/axum.rs | 15 +- src/database/key_value/appservice.rs | 11 +- src/database/key_value/rooms/state_cache.rs | 47 ++---- src/database/mod.rs | 20 ++- src/service/admin/mod.rs | 7 +- src/service/appservice/data.rs | 8 +- src/service/appservice/mod.rs | 114 +++++++++++++- src/service/mod.rs | 7 +- src/service/rooms/state_cache/data.rs | 8 +- src/service/rooms/state_cache/mod.rs | 4 +- src/service/rooms/timeline/mod.rs | 116 ++++++-------- src/service/sending/mod.rs | 19 ++- src/utils/error.rs | 5 + 15 files changed, 336 insertions(+), 245 deletions(-) diff --git a/src/api/appservice_server.rs b/src/api/appservice_server.rs index 082a1bc2..ab4da79f 100644 --- a/src/api/appservice_server.rs +++ b/src/api/appservice_server.rs @@ -1,105 +1,111 @@ use crate::{services, utils, Error, Result}; use bytes::BytesMut; -use ruma::api::{IncomingResponse, MatrixVersion, OutgoingRequest, SendAccessToken}; +use ruma::api::{ + appservice::Registration, IncomingResponse, MatrixVersion, OutgoingRequest, SendAccessToken, +}; use std::{fmt::Debug, mem, time::Duration}; use tracing::warn; +/// Sends a request to an appservice +/// +/// Only returns None if there is no url specified in the appservice registration file #[tracing::instrument(skip(request))] pub(crate) async fn send_request( - registration: serde_yaml::Value, + registration: Registration, request: T, -) -> Result +) -> Option> where T: Debug, { - let destination = registration.get("url").unwrap().as_str().unwrap(); - let hs_token = registration.get("hs_token").unwrap().as_str().unwrap(); + if let Some(destination) = registration.url { + let hs_token = registration.hs_token.as_str(); - let mut http_request = request - .try_into_http_request::( - destination, - SendAccessToken::IfRequired(hs_token), - &[MatrixVersion::V1_0], - ) - .unwrap() - .map(|body| body.freeze()); + let mut http_request = request + .try_into_http_request::( + &destination, + SendAccessToken::IfRequired(hs_token), + &[MatrixVersion::V1_0], + ) + .unwrap() + .map(|body| body.freeze()); - let mut parts = http_request.uri().clone().into_parts(); - let old_path_and_query = parts.path_and_query.unwrap().as_str().to_owned(); - let symbol = if old_path_and_query.contains('?') { - "&" - } else { - "?" - }; + let mut parts = http_request.uri().clone().into_parts(); + let old_path_and_query = parts.path_and_query.unwrap().as_str().to_owned(); + let symbol = if old_path_and_query.contains('?') { + "&" + } else { + "?" + }; + + parts.path_and_query = Some( + (old_path_and_query + symbol + "access_token=" + hs_token) + .parse() + .unwrap(), + ); + *http_request.uri_mut() = parts.try_into().expect("our manipulation is always valid"); - parts.path_and_query = Some( - (old_path_and_query + symbol + "access_token=" + hs_token) - .parse() - .unwrap(), - ); - *http_request.uri_mut() = parts.try_into().expect("our manipulation is always valid"); + let mut reqwest_request = reqwest::Request::try_from(http_request) + .expect("all http requests are valid reqwest requests"); - let mut reqwest_request = reqwest::Request::try_from(http_request) - .expect("all http requests are valid reqwest requests"); + *reqwest_request.timeout_mut() = Some(Duration::from_secs(30)); - *reqwest_request.timeout_mut() = Some(Duration::from_secs(30)); + let url = reqwest_request.url().clone(); + let mut response = match services() + .globals + .default_client() + .execute(reqwest_request) + .await + { + Ok(r) => r, + Err(e) => { + warn!( + "Could not send request to appservice {:?} at {}: {}", + registration.id, destination, e + ); + return Some(Err(e.into())); + } + }; - let url = reqwest_request.url().clone(); - let mut response = match services() - .globals - .default_client() - .execute(reqwest_request) - .await - { - Ok(r) => r, - Err(e) => { + // reqwest::Response -> http::Response conversion + let status = response.status(); + let mut http_response_builder = http::Response::builder() + .status(status) + .version(response.version()); + mem::swap( + response.headers_mut(), + http_response_builder + .headers_mut() + .expect("http::response::Builder is usable"), + ); + + let body = response.bytes().await.unwrap_or_else(|e| { + warn!("server error: {}", e); + Vec::new().into() + }); // TODO: handle timeout + + if status != 200 { warn!( - "Could not send request to appservice {:?} at {}: {}", - registration.get("id"), + "Appservice returned bad response {} {}\n{}\n{:?}", destination, - e + status, + url, + utils::string_from_bytes(&body) ); - return Err(e.into()); } - }; - - // reqwest::Response -> http::Response conversion - let status = response.status(); - let mut http_response_builder = http::Response::builder() - .status(status) - .version(response.version()); - mem::swap( - response.headers_mut(), - http_response_builder - .headers_mut() - .expect("http::response::Builder is usable"), - ); - let body = response.bytes().await.unwrap_or_else(|e| { - warn!("server error: {}", e); - Vec::new().into() - }); // TODO: handle timeout - - if status != 200 { - warn!( - "Appservice returned bad response {} {}\n{}\n{:?}", - destination, - status, - url, - utils::string_from_bytes(&body) + let response = T::IncomingResponse::try_from_http_response( + http_response_builder + .body(body) + .expect("reqwest body is valid http body"), ); + Some(response.map_err(|_| { + warn!( + "Appservice returned invalid response bytes {}\n{}", + destination, url + ); + Error::BadServerResponse("Server returned bad response.") + })) + } else { + None } - - let response = T::IncomingResponse::try_from_http_response( - http_response_builder - .body(body) - .expect("reqwest body is valid http body"), - ); - response.map_err(|_| { - warn!( - "Appservice returned invalid response bytes {}\n{}", - destination, url - ); - Error::BadServerResponse("Server returned bad response.") - }) } diff --git a/src/api/client_server/alias.rs b/src/api/client_server/alias.rs index 7660ca2f..d3a6e39a 100644 --- a/src/api/client_server/alias.rs +++ b/src/api/client_server/alias.rs @@ -1,6 +1,5 @@ use crate::{services, Error, Result, Ruma}; use rand::seq::SliceRandom; -use regex::Regex; use ruma::{ api::{ appservice, @@ -101,31 +100,28 @@ pub(crate) async fn get_alias_helper( match services().rooms.alias.resolve_local_alias(&room_alias)? { Some(r) => room_id = Some(r), None => { - for (_id, registration) in services().appservice.all()? { - let aliases = registration - .get("namespaces") - .and_then(|ns| ns.get("aliases")) - .and_then(|aliases| aliases.as_sequence()) - .map_or_else(Vec::new, |aliases| { - aliases - .iter() - .filter_map(|aliases| Regex::new(aliases.get("regex")?.as_str()?).ok()) - .collect::>() - }); - - if aliases - .iter() - .any(|aliases| aliases.is_match(room_alias.as_str())) - && services() + for appservice in services() + .appservice + .registration_info + .read() + .await + .values() + { + if appservice.aliases.is_match(room_alias.as_str()) + && if let Some(opt_result) = services() .sending .send_appservice_request( - registration, + appservice.registration.clone(), appservice::query::query_room_alias::v1::Request { room_alias: room_alias.clone(), }, ) .await - .is_ok() + { + opt_result.is_ok() + } else { + false + } { room_id = Some( services() diff --git a/src/api/ruma_wrapper/axum.rs b/src/api/ruma_wrapper/axum.rs index bbd48614..e841f13a 100644 --- a/src/api/ruma_wrapper/axum.rs +++ b/src/api/ruma_wrapper/axum.rs @@ -81,12 +81,9 @@ where let mut json_body = serde_json::from_slice::(&body).ok(); let appservices = services().appservice.all().unwrap(); - let appservice_registration = appservices.iter().find(|(_id, registration)| { - registration - .get("as_token") - .and_then(|as_token| as_token.as_str()) - .map_or(false, |as_token| token == Some(as_token)) - }); + let appservice_registration = appservices + .iter() + .find(|(_id, registration)| Some(registration.as_token.as_str()) == token); let (sender_user, sender_device, sender_servername, from_appservice) = if let Some((_id, registration)) = appservice_registration { @@ -95,11 +92,7 @@ where let user_id = query_params.user_id.map_or_else( || { UserId::parse_with_server_name( - registration - .get("sender_localpart") - .unwrap() - .as_str() - .unwrap(), + registration.sender_localpart.as_str(), services().globals.server_name(), ) .unwrap() diff --git a/src/database/key_value/appservice.rs b/src/database/key_value/appservice.rs index 9a821a65..3243183d 100644 --- a/src/database/key_value/appservice.rs +++ b/src/database/key_value/appservice.rs @@ -1,10 +1,11 @@ +use ruma::api::appservice::Registration; + use crate::{database::KeyValueDatabase, service, utils, Error, Result}; impl service::appservice::Data for KeyValueDatabase { /// Registers an appservice and returns the ID to the caller - fn register_appservice(&self, yaml: serde_yaml::Value) -> Result { - // TODO: Rumaify - let id = yaml.get("id").unwrap().as_str().unwrap(); + fn register_appservice(&self, yaml: Registration) -> Result { + let id = yaml.id.as_str(); self.id_appserviceregistrations.insert( id.as_bytes(), serde_yaml::to_string(&yaml).unwrap().as_bytes(), @@ -32,7 +33,7 @@ impl service::appservice::Data for KeyValueDatabase { Ok(()) } - fn get_registration(&self, id: &str) -> Result> { + fn get_registration(&self, id: &str) -> Result> { self.cached_registrations .read() .unwrap() @@ -64,7 +65,7 @@ impl service::appservice::Data for KeyValueDatabase { ))) } - fn all(&self) -> Result> { + fn all(&self) -> Result> { self.iter_ids()? .filter_map(|id| id.ok()) .map(move |id| { diff --git a/src/database/key_value/rooms/state_cache.rs b/src/database/key_value/rooms/state_cache.rs index 3dcaf4ae..49e3842b 100644 --- a/src/database/key_value/rooms/state_cache.rs +++ b/src/database/key_value/rooms/state_cache.rs @@ -1,13 +1,16 @@ use std::{collections::HashSet, sync::Arc}; -use regex::Regex; use ruma::{ events::{AnyStrippedStateEvent, AnySyncStateEvent}, serde::Raw, OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, ServerName, UserId, }; -use crate::{database::KeyValueDatabase, service, services, utils, Error, Result}; +use crate::{ + database::KeyValueDatabase, + service::{self, appservice::RegistrationInfo}, + services, utils, Error, Result, +}; impl service::rooms::state_cache::Data for KeyValueDatabase { fn mark_as_once_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> { @@ -184,46 +187,28 @@ impl service::rooms::state_cache::Data for KeyValueDatabase { } #[tracing::instrument(skip(self, room_id, appservice))] - fn appservice_in_room( - &self, - room_id: &RoomId, - appservice: &(String, serde_yaml::Value), - ) -> Result { + fn appservice_in_room(&self, room_id: &RoomId, appservice: &RegistrationInfo) -> Result { let maybe = self .appservice_in_room_cache .read() .unwrap() .get(room_id) - .and_then(|map| map.get(&appservice.0)) + .and_then(|map| map.get(&appservice.registration.id)) .copied(); if let Some(b) = maybe { Ok(b) - } else if let Some(namespaces) = appservice.1.get("namespaces") { - let users = namespaces - .get("users") - .and_then(|users| users.as_sequence()) - .map_or_else(Vec::new, |users| { - users - .iter() - .filter_map(|users| Regex::new(users.get("regex")?.as_str()?).ok()) - .collect::>() - }); - - let bridge_user_id = appservice - .1 - .get("sender_localpart") - .and_then(|string| string.as_str()) - .and_then(|string| { - UserId::parse_with_server_name(string, services().globals.server_name()).ok() - }); + } else { + let bridge_user_id = UserId::parse_with_server_name( + appservice.registration.sender_localpart.as_str(), + services().globals.server_name(), + ) + .ok(); let in_room = bridge_user_id .map_or(false, |id| self.is_joined(&id, room_id).unwrap_or(false)) || self.room_members(room_id).any(|userid| { - userid.map_or(false, |userid| { - users.iter().any(|r| r.is_match(userid.as_str())) - }) + userid.map_or(false, |userid| appservice.users.is_match(userid.as_str())) }); self.appservice_in_room_cache @@ -231,11 +216,9 @@ impl service::rooms::state_cache::Data for KeyValueDatabase { .unwrap() .entry(room_id.to_owned()) .or_default() - .insert(appservice.0.clone(), in_room); + .insert(appservice.registration.id.clone(), in_room); Ok(in_room) - } else { - Ok(false) } } diff --git a/src/database/mod.rs b/src/database/mod.rs index 425ef4e9..5b8588cf 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -8,7 +8,9 @@ use crate::{ use abstraction::{KeyValueDatabaseEngine, KvTree}; use directories::ProjectDirs; use lru_cache::LruCache; + use ruma::{ + api::appservice::Registration, events::{ push_rules::{PushRulesEvent, PushRulesEventContent}, room::message::RoomMessageEventContent, @@ -162,7 +164,7 @@ pub struct KeyValueDatabase { //pub pusher: pusher::PushData, pub(super) senderkey_pusher: Arc, - pub(super) cached_registrations: Arc>>, + pub(super) cached_registrations: Arc>>, pub(super) pdu_cache: Mutex>>, pub(super) shorteventid_cache: Mutex>>, pub(super) auth_chain_cache: Mutex, Arc>>>, @@ -967,6 +969,22 @@ impl KeyValueDatabase { ); } + // Inserting registrations into cache + for appservice in services().appservice.all()? { + services() + .appservice + .registration_info + .write() + .await + .insert( + appservice.0, + appservice + .1 + .try_into() + .expect("Should be validated on registration"), + ); + } + // This data is probably outdated db.presenceid_presence.clear()?; diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index d99be878..12bc1cf6 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -8,6 +8,7 @@ use std::{ use clap::Parser; use regex::Regex; use ruma::{ + api::appservice::Registration, events::{ room::{ canonical_alias::RoomCanonicalAliasEventContent, @@ -335,10 +336,9 @@ impl Service { if body.len() > 2 && body[0].trim() == "```" && body.last().unwrap().trim() == "```" { let appservice_config = body[1..body.len() - 1].join("\n"); - let parsed_config = - serde_yaml::from_str::(&appservice_config); + let parsed_config = serde_yaml::from_str::(&appservice_config); match parsed_config { - Ok(yaml) => match services().appservice.register_appservice(yaml) { + Ok(yaml) => match services().appservice.register_appservice(yaml).await { Ok(id) => RoomMessageEventContent::text_plain(format!( "Appservice registered with ID: {id}." )), @@ -361,6 +361,7 @@ impl Service { } => match services() .appservice .unregister_appservice(&appservice_identifier) + .await { Ok(()) => RoomMessageEventContent::text_plain("Appservice unregistered."), Err(e) => RoomMessageEventContent::text_plain(format!( diff --git a/src/service/appservice/data.rs b/src/service/appservice/data.rs index 744f0f94..ab19a50c 100644 --- a/src/service/appservice/data.rs +++ b/src/service/appservice/data.rs @@ -1,8 +1,10 @@ +use ruma::api::appservice::Registration; + use crate::Result; pub trait Data: Send + Sync { /// Registers an appservice and returns the ID to the caller - fn register_appservice(&self, yaml: serde_yaml::Value) -> Result; + fn register_appservice(&self, yaml: Registration) -> Result; /// Remove an appservice registration /// @@ -11,9 +13,9 @@ pub trait Data: Send + Sync { /// * `service_name` - the name you send to register the service previously fn unregister_appservice(&self, service_name: &str) -> Result<()>; - fn get_registration(&self, id: &str) -> Result>; + fn get_registration(&self, id: &str) -> Result>; fn iter_ids<'a>(&'a self) -> Result> + 'a>>; - fn all(&self) -> Result>; + fn all(&self) -> Result>; } diff --git a/src/service/appservice/mod.rs b/src/service/appservice/mod.rs index 3052964d..40fa3ee8 100644 --- a/src/service/appservice/mod.rs +++ b/src/service/appservice/mod.rs @@ -1,16 +1,113 @@ mod data; +use std::collections::HashMap; + pub use data::Data; -use crate::Result; +use regex::RegexSet; +use ruma::api::appservice::{Namespace, Registration}; +use tokio::sync::RwLock; + +use crate::{services, Result}; + +/// Compiled regular expressions for a namespace +pub struct NamespaceRegex { + pub exclusive: Option, + pub non_exclusive: Option, +} + +impl NamespaceRegex { + /// Checks if this namespace has rights to a namespace + pub fn is_match(&self, heystack: &str) -> bool { + if self.is_exclusive_match(heystack) { + return true; + } + + if let Some(non_exclusive) = &self.non_exclusive { + if non_exclusive.is_match(heystack) { + return true; + } + } + false + } + + /// Checks if this namespace has exlusive rights to a namespace + pub fn is_exclusive_match(&self, heystack: &str) -> bool { + if let Some(exclusive) = &self.exclusive { + if exclusive.is_match(heystack) { + return true; + } + } + false + } +} + +impl TryFrom> for NamespaceRegex { + fn try_from(value: Vec) -> Result { + let mut exclusive = vec![]; + let mut non_exclusive = vec![]; + + for namespace in value { + if namespace.exclusive { + exclusive.push(namespace.regex); + } else { + non_exclusive.push(namespace.regex); + } + } + + Ok(NamespaceRegex { + exclusive: if exclusive.is_empty() { + None + } else { + Some(RegexSet::new(exclusive)?) + }, + non_exclusive: if non_exclusive.is_empty() { + None + } else { + Some(RegexSet::new(non_exclusive)?) + }, + }) + } + + type Error = regex::Error; +} + +/// Compiled regular expressions for an appservice +pub struct RegistrationInfo { + pub registration: Registration, + pub users: NamespaceRegex, + pub aliases: NamespaceRegex, + pub rooms: NamespaceRegex, +} + +impl TryFrom for RegistrationInfo { + fn try_from(value: Registration) -> Result { + Ok(RegistrationInfo { + users: value.namespaces.users.clone().try_into()?, + aliases: value.namespaces.aliases.clone().try_into()?, + rooms: value.namespaces.rooms.clone().try_into()?, + registration: value, + }) + } + + type Error = regex::Error; +} pub struct Service { pub db: &'static dyn Data, + pub registration_info: RwLock>, } impl Service { /// Registers an appservice and returns the ID to the caller - pub fn register_appservice(&self, yaml: serde_yaml::Value) -> Result { + pub async fn register_appservice(&self, yaml: Registration) -> Result { + services() + .appservice + .registration_info + .write() + .await + .insert(yaml.id.clone(), yaml.clone().try_into()?); + self.db.register_appservice(yaml) } @@ -19,11 +116,18 @@ impl Service { /// # Arguments /// /// * `service_name` - the name you send to register the service previously - pub fn unregister_appservice(&self, service_name: &str) -> Result<()> { + pub async fn unregister_appservice(&self, service_name: &str) -> Result<()> { + services() + .appservice + .registration_info + .write() + .await + .remove(service_name); + self.db.unregister_appservice(service_name) } - pub fn get_registration(&self, id: &str) -> Result> { + pub fn get_registration(&self, id: &str) -> Result> { self.db.get_registration(id) } @@ -31,7 +135,7 @@ impl Service { self.db.iter_ids() } - pub fn all(&self) -> Result> { + pub fn all(&self) -> Result> { self.db.all() } } diff --git a/src/service/mod.rs b/src/service/mod.rs index 8f9fb0a5..045ccd10 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -4,7 +4,7 @@ use std::{ }; use lru_cache::LruCache; -use tokio::sync::Mutex; +use tokio::sync::{Mutex, RwLock}; use crate::{Config, Result}; @@ -56,7 +56,10 @@ impl Services { config: Config, ) -> Result { Ok(Self { - appservice: appservice::Service { db }, + appservice: appservice::Service { + db, + registration_info: RwLock::new(HashMap::new()), + }, pusher: pusher::Service { db }, rooms: rooms::Service { alias: rooms::alias::Service { db }, diff --git a/src/service/rooms/state_cache/data.rs b/src/service/rooms/state_cache/data.rs index 8921909f..b511919a 100644 --- a/src/service/rooms/state_cache/data.rs +++ b/src/service/rooms/state_cache/data.rs @@ -1,6 +1,6 @@ use std::{collections::HashSet, sync::Arc}; -use crate::Result; +use crate::{service::appservice::RegistrationInfo, Result}; use ruma::{ events::{AnyStrippedStateEvent, AnySyncStateEvent}, serde::Raw, @@ -22,11 +22,7 @@ pub trait Data: Send + Sync { fn get_our_real_users(&self, room_id: &RoomId) -> Result>>; - fn appservice_in_room( - &self, - room_id: &RoomId, - appservice: &(String, serde_yaml::Value), - ) -> Result; + fn appservice_in_room(&self, room_id: &RoomId, appservice: &RegistrationInfo) -> Result; /// Makes a user forget a room. fn forget(&self, room_id: &RoomId, user_id: &UserId) -> Result<()>; diff --git a/src/service/rooms/state_cache/mod.rs b/src/service/rooms/state_cache/mod.rs index ef1ad61e..c108695d 100644 --- a/src/service/rooms/state_cache/mod.rs +++ b/src/service/rooms/state_cache/mod.rs @@ -16,7 +16,7 @@ use ruma::{ }; use tracing::warn; -use crate::{services, Error, Result}; +use crate::{service::appservice::RegistrationInfo, services, Error, Result}; pub struct Service { pub db: &'static dyn Data, @@ -205,7 +205,7 @@ impl Service { pub fn appservice_in_room( &self, room_id: &RoomId, - appservice: &(String, serde_yaml::Value), + appservice: &RegistrationInfo, ) -> Result { self.db.appservice_in_room(room_id, appservice) } diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 097cc82f..1df1db50 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -7,7 +7,7 @@ use std::{ }; pub use data::Data; -use regex::Regex; + use ruma::{ api::{client::error::ErrorKind, federation}, canonical_json::to_canonical_value, @@ -21,8 +21,7 @@ use ruma::{ }, push::{Action, Ruleset, Tweak}, serde::Base64, - state_res, - state_res::{Event, RoomVersion}, + state_res::{self, Event, RoomVersion}, uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, OwnedServerName, RoomId, ServerName, UserId, }; @@ -33,7 +32,10 @@ use tracing::{error, info, warn}; use crate::{ api::server_server, - service::pdu::{EventHash, PduBuilder}, + service::{ + appservice::NamespaceRegex, + pdu::{EventHash, PduBuilder}, + }, services, utils, Error, PduEvent, Result, }; @@ -522,15 +524,21 @@ impl Service { } } - for appservice in services().appservice.all()? { + for appservice in services() + .appservice + .registration_info + .read() + .await + .values() + { if services() .rooms .state_cache - .appservice_in_room(&pdu.room_id, &appservice)? + .appservice_in_room(&pdu.room_id, appservice)? { services() .sending - .send_pdu_appservice(appservice.0, pdu_id.clone())?; + .send_pdu_appservice(appservice.registration.id.clone(), pdu_id.clone())?; continue; } @@ -542,73 +550,41 @@ impl Service { .as_ref() .and_then(|state_key| UserId::parse(state_key.as_str()).ok()) { - if let Some(appservice_uid) = appservice - .1 - .get("sender_localpart") - .and_then(|string| string.as_str()) - .and_then(|string| { - UserId::parse_with_server_name(string, services().globals.server_name()) - .ok() - }) - { - if state_key_uid == &appservice_uid { - services() - .sending - .send_pdu_appservice(appservice.0, pdu_id.clone())?; - continue; - } + let appservice_uid = appservice.registration.sender_localpart.as_str(); + if state_key_uid == appservice_uid { + services().sending.send_pdu_appservice( + appservice.registration.id.clone(), + pdu_id.clone(), + )?; + continue; } } } - if let Some(namespaces) = appservice.1.get("namespaces") { - let users = namespaces - .get("users") - .and_then(|users| users.as_sequence()) - .map_or_else(Vec::new, |users| { - users - .iter() - .filter_map(|users| Regex::new(users.get("regex")?.as_str()?).ok()) - .collect::>() - }); - let aliases = namespaces - .get("aliases") - .and_then(|aliases| aliases.as_sequence()) - .map_or_else(Vec::new, |aliases| { - aliases - .iter() - .filter_map(|aliases| Regex::new(aliases.get("regex")?.as_str()?).ok()) - .collect::>() - }); - let rooms = namespaces - .get("rooms") - .and_then(|rooms| rooms.as_sequence()); - - let matching_users = |users: &Regex| { - users.is_match(pdu.sender.as_str()) - || pdu.kind == TimelineEventType::RoomMember - && pdu - .state_key - .as_ref() - .map_or(false, |state_key| users.is_match(state_key)) - }; - let matching_aliases = |aliases: &Regex| { - services() - .rooms - .alias - .local_aliases_for_room(&pdu.room_id) - .filter_map(|r| r.ok()) - .any(|room_alias| aliases.is_match(room_alias.as_str())) - }; - - if aliases.iter().any(matching_aliases) - || rooms.map_or(false, |rooms| rooms.contains(&pdu.room_id.as_str().into())) - || users.iter().any(matching_users) - { - services() - .sending - .send_pdu_appservice(appservice.0, pdu_id.clone())?; - } + let matching_users = |users: &NamespaceRegex| { + appservice.users.is_match(pdu.sender.as_str()) + || pdu.kind == TimelineEventType::RoomMember + && pdu + .state_key + .as_ref() + .map_or(false, |state_key| users.is_match(state_key)) + }; + let matching_aliases = |aliases: &NamespaceRegex| { + services() + .rooms + .alias + .local_aliases_for_room(&pdu.room_id) + .filter_map(|r| r.ok()) + .any(|room_alias| aliases.is_match(room_alias.as_str())) + }; + + if matching_aliases(&appservice.aliases) + || appservice.rooms.is_match(pdu.room_id.as_str()) + || matching_users(&appservice.users) + { + services() + .sending + .send_pdu_appservice(appservice.registration.id.clone(), pdu_id.clone())?; } } diff --git a/src/service/sending/mod.rs b/src/service/sending/mod.rs index f80c4f0a..bbacfdec 100644 --- a/src/service/sending/mod.rs +++ b/src/service/sending/mod.rs @@ -22,7 +22,7 @@ use base64::{engine::general_purpose, Engine as _}; use ruma::{ api::{ - appservice, + appservice::{self, Registration}, federation::{ self, transactions::edu::{ @@ -484,7 +484,7 @@ impl Service { let permit = services().sending.maximum_requests.acquire().await; - let response = appservice_server::send_request( + let response = match appservice_server::send_request( services() .appservice .get_registration(id) @@ -511,8 +511,12 @@ impl Service { }, ) .await - .map(|_response| kind.clone()) - .map_err(|e| (kind, e)); + { + None => Ok(kind.clone()), + Some(op_resp) => op_resp + .map(|_response| kind.clone()) + .map_err(|e| (kind.clone(), e)), + }; drop(permit); @@ -698,12 +702,15 @@ impl Service { response } + /// Sends a request to an appservice + /// + /// Only returns None if there is no url specified in the appservice registration file #[tracing::instrument(skip(self, registration, request))] pub async fn send_appservice_request( &self, - registration: serde_yaml::Value, + registration: Registration, request: T, - ) -> Result + ) -> Option> where T: Debug, { diff --git a/src/utils/error.rs b/src/utils/error.rs index 765a31bb..04390283 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -54,6 +54,11 @@ pub enum Error { #[from] source: reqwest::Error, }, + #[error("Could build regular expression: {source}")] + RegexError { + #[from] + source: regex::Error, + }, #[error("{0}")] FederationError(OwnedServerName, RumaError), #[error("Could not do this io: {source}")] From 10f3f9da494bf41899c83bdef62ebb83281ac363 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 28 Jan 2024 15:47:37 -0800 Subject: [PATCH 090/129] switch/update rocksdb crate This fork was created because the original seems de-facto unmaintained. --- Cargo.lock | 71 +++++++++++++++++++++++------------------------------- Cargo.toml | 12 ++++++--- flake.nix | 18 ++++++++++++-- 3 files changed, 55 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e99928e0..88217001 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,17 +204,16 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bindgen" -version = "0.65.1" +version = "0.69.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +checksum = "a4c69fae65a523209d34240b60abe0c42d33d1045d445c0839d8a4894a736e2d" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "cexpr", "clang-sys", "lazy_static", "lazycell", "peeking_take_while", - "prettyplease", "proc-macro2", "quote", "regex", @@ -400,10 +399,10 @@ dependencies = [ "regex", "reqwest", "ring", - "rocksdb", "ruma", "rusqlite", "rust-argon2", + "rust-rocksdb", "sd-notify", "serde", "serde_html_form", @@ -1278,22 +1277,6 @@ dependencies = [ "redox_syscall", ] -[[package]] -name = "librocksdb-sys" -version = "0.11.0+8.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" -dependencies = [ - "bindgen", - "bzip2-sys", - "cc", - "glob", - "libc", - "libz-sys", - "lz4-sys", - "zstd-sys", -] - [[package]] name = "libsqlite3-sys" version = "0.26.0" @@ -1790,16 +1773,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "prettyplease" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" -dependencies = [ - "proc-macro2", - "syn 2.0.48", -] - [[package]] name = "proc-macro-crate" version = "2.0.0" @@ -2005,16 +1978,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rocksdb" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" -dependencies = [ - "libc", - "librocksdb-sys", -] - [[package]] name = "ruma" version = "0.9.4" @@ -2230,6 +2193,32 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rust-librocksdb-sys" +version = "0.18.1+8.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef22f434855ceb8daf99073fcf909d957ad8705f5b530154e47978ae68e867c" +dependencies = [ + "bindgen", + "bzip2-sys", + "cc", + "glob", + "libc", + "libz-sys", + "lz4-sys", + "zstd-sys", +] + +[[package]] +name = "rust-rocksdb" +version = "0.22.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62223f035e676bb69da2ab9487e6f710da82be89473c658c51ed3b1a60c4b4a6" +dependencies = [ + "libc", + "rust-librocksdb-sys", +] + [[package]] name = "rustc-demangle" version = "0.1.23" diff --git a/Cargo.toml b/Cargo.toml index e8c1c8bf..7bb3b5db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,8 +97,6 @@ threadpool = "1.8.1" # Used for ruma wrapper serde_html_form = "0.2.0" -rocksdb = { version = "0.21.0", default-features = true, features = ["multi-threaded-cf", "zstd"], optional = true } - thread_local = "1.1.7" # used for TURN server authentication hmac = "0.12.1" @@ -116,6 +114,14 @@ async-trait = "0.1.68" sd-notify = { version = "0.4.1", optional = true } +[dependencies.rust-rocksdb] +version = "0.22.7" +optional = true +features = [ + "multi-threaded-cf", + "zstd", +] + [target.'cfg(unix)'.dependencies] nix = { version = "0.26.2", features = ["resource"] } @@ -125,7 +131,7 @@ default = ["conduit_bin", "backend_sqlite", "backend_rocksdb", "systemd"] backend_persy = ["persy", "parking_lot"] backend_sqlite = ["sqlite"] #backend_heed = ["heed", "crossbeam"] -backend_rocksdb = ["rocksdb"] +backend_rocksdb = ["rust-rocksdb"] jemalloc = ["tikv-jemalloc-ctl", "tikv-jemallocator"] sqlite = ["rusqlite", "parking_lot", "tokio/signal"] conduit_bin = ["axum"] diff --git a/flake.nix b/flake.nix index cc95aecb..cdfe91f8 100644 --- a/flake.nix +++ b/flake.nix @@ -58,9 +58,23 @@ pkgs.pkgsBuildHost.rustPlatform.bindgenHook ]; + rocksdb' = pkgs: + let + version = "8.11.3"; + in + pkgs.rocksdb.overrideAttrs (old: { + inherit version; + src = pkgs.fetchFromGitHub { + owner = "facebook"; + repo = "rocksdb"; + rev = "v${version}"; + hash = "sha256-OpEiMwGxZuxb9o3RQuSrwZMQGLhe9xLT1aa3HpI4KPs="; + }; + }); + env = pkgs: { - ROCKSDB_INCLUDE_DIR = "${pkgs.rocksdb}/include"; - ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; + ROCKSDB_INCLUDE_DIR = "${rocksdb' pkgs}/include"; + ROCKSDB_LIB_DIR = "${rocksdb' pkgs}/lib"; } // pkgs.lib.optionalAttrs pkgs.stdenv.hostPlatform.isStatic { ROCKSDB_STATIC = ""; From daed4cdddfcb84e9b648b15bcfcd89c4bbde834b Mon Sep 17 00:00:00 2001 From: tezlm Date: Sat, 14 Oct 2023 06:20:29 -0700 Subject: [PATCH 091/129] Remove log config modification --- src/main.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 524f6886..aaa34346 100644 --- a/src/main.rs +++ b/src/main.rs @@ -65,8 +65,6 @@ async fn main() { config.warn_deprecated(); - let log = format!("{},ruma_state_res=error,_=off,sled=off", config.log); - if config.allow_jaeger { opentelemetry::global::set_text_map_propagator(opentelemetry_jaeger::Propagator::new()); let tracer = opentelemetry_jaeger::new_agent_pipeline() @@ -76,7 +74,7 @@ async fn main() { .unwrap(); let telemetry = tracing_opentelemetry::layer().with_tracer(tracer); - let filter_layer = match EnvFilter::try_new(&log) { + let filter_layer = match EnvFilter::try_new(&config.log) { Ok(s) => s, Err(e) => { eprintln!( @@ -103,7 +101,7 @@ async fn main() { } else { let registry = tracing_subscriber::Registry::default(); let fmt_layer = tracing_subscriber::fmt::Layer::new(); - let filter_layer = match EnvFilter::try_new(&log) { + 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}"); From 9ff9e85ebe2b6358dd1e554a8ba5ce34f4faedf0 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 10 Mar 2024 22:33:54 -0700 Subject: [PATCH 092/129] add newline to end of file Please, people. --- docker/docker-compose.with-traefik.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-compose.with-traefik.yml b/docker/docker-compose.with-traefik.yml index fda942bc..e3289ba4 100644 --- a/docker/docker-compose.with-traefik.yml +++ b/docker/docker-compose.with-traefik.yml @@ -95,4 +95,4 @@ volumes: acme: networks: - proxy: \ No newline at end of file + proxy: From 5f053a93574e6bc2a36bd5b9a1c70c4bf6f5c8fa Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 10 Mar 2024 22:34:25 -0700 Subject: [PATCH 093/129] link to example config instead of copying it DRY FTW --- DEPLOY.md | 53 ++++------------------------------------------------- 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/DEPLOY.md b/DEPLOY.md index dd279688..e87fca3b 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -139,57 +139,12 @@ $ sudo systemctl daemon-reload ## Creating the Conduit configuration file -Now we need to create the Conduit's config file in `/etc/matrix-conduit/conduit.toml`. Paste this in **and take a moment -to read it. You need to change at least the server name.** +Now we need to create the Conduit's config file in +`/etc/matrix-conduit/conduit.toml`. Paste in the contents of +[`conduit-example.toml`](./conduit-example.toml) **and take a moment to read it. +You need to change at least the server name.** You can also choose to use a different database backend, but right now only `rocksdb` and `sqlite` are recommended. -```toml -[global] -# The server_name is the pretty name of this server. It is used as a suffix for user -# and room ids. Examples: matrix.org, conduit.rs - -# The Conduit server needs all /_matrix/ requests to be reachable at -# https://your.server.name/ on port 443 (client-server) and 8448 (federation). - -# If that's not possible for you, you can create /.well-known files to redirect -# requests. See -# https://matrix.org/docs/spec/client_server/latest#get-well-known-matrix-client -# and -# https://matrix.org/docs/spec/server_server/r0.1.4#get-well-known-matrix-server -# for more information - -# YOU NEED TO EDIT THIS -#server_name = "your.server.name" - -# This is the only directory where Conduit will save its data -database_path = "/var/lib/matrix-conduit/" -database_backend = "rocksdb" - -# The port Conduit will be running on. You need to set up a reverse proxy in -# your web server (e.g. apache or nginx), so all requests to /_matrix on port -# 443 and 8448 will be forwarded to the Conduit instance running on this port -# Docker users: Don't change this, you'll need to map an external port to this. -port = 6167 - -# Max size for uploads -max_request_size = 20_000_000 # in bytes - -# Enables registration. If set to false, no users can register on this server. -allow_registration = true - -allow_federation = true -allow_check_for_updates = true - -# Server to get public keys from. You probably shouldn't change this -trusted_servers = ["matrix.org"] - -#max_concurrent_requests = 100 # How many requests Conduit sends to other servers at the same time -#log = "warn,state_res=warn,rocket=off,_=off,sled=off" - -address = "127.0.0.1" # This makes sure Conduit can only be reached using the reverse proxy -#address = "0.0.0.0" # If Conduit is running in a container, make sure the reverse proxy (ie. Traefik) can reach it. -``` - ## Setting the correct file permissions As we are using a Conduit specific user we need to allow it to read the config. To do that you can run this command on From ed5bd2325596ae73a7e81e13aafdf774cc403449 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 10 Mar 2024 22:36:48 -0700 Subject: [PATCH 094/129] remove explicit references to log config They're all stale. Sled was yote long ago. --- debian/postinst | 1 - docker/README.md | 1 - docker/docker-compose.for-traefik.yml | 1 - docker/docker-compose.with-traefik.yml | 1 - docker/docker-compose.yml | 1 - 5 files changed, 5 deletions(-) diff --git a/debian/postinst b/debian/postinst index 69a766a0..110f22d6 100644 --- a/debian/postinst +++ b/debian/postinst @@ -78,7 +78,6 @@ allow_check_for_updates = true trusted_servers = ["matrix.org"] #max_concurrent_requests = 100 # How many requests Conduit sends to other servers at the same time -#log = "warn,state_res=warn,rocket=off,_=off,sled=off" EOF fi ;; diff --git a/docker/README.md b/docker/README.md index b34f9d87..2448e643 100644 --- a/docker/README.md +++ b/docker/README.md @@ -64,7 +64,6 @@ docker run -d -p 8448:6167 \ -e CONDUIT_MAX_REQUEST_SIZE="20_000_000" \ -e CONDUIT_TRUSTED_SERVERS="[\"matrix.org\"]" \ -e CONDUIT_MAX_CONCURRENT_REQUESTS="100" \ - -e CONDUIT_LOG="warn,rocket=off,_=off,sled=off" \ --name conduit ``` diff --git a/docker/docker-compose.for-traefik.yml b/docker/docker-compose.for-traefik.yml index bed734f1..82bb55b0 100644 --- a/docker/docker-compose.for-traefik.yml +++ b/docker/docker-compose.for-traefik.yml @@ -32,7 +32,6 @@ services: CONDUIT_ALLOW_CHECK_FOR_UPDATES: 'true' CONDUIT_TRUSTED_SERVERS: '["matrix.org"]' #CONDUIT_MAX_CONCURRENT_REQUESTS: 100 - #CONDUIT_LOG: warn,rocket=off,_=off,sled=off CONDUIT_ADDRESS: 0.0.0.0 CONDUIT_CONFIG: '' # Ignore this diff --git a/docker/docker-compose.with-traefik.yml b/docker/docker-compose.with-traefik.yml index e3289ba4..58603277 100644 --- a/docker/docker-compose.with-traefik.yml +++ b/docker/docker-compose.with-traefik.yml @@ -33,7 +33,6 @@ services: # CONDUIT_PORT: 6167 # CONDUIT_CONFIG: '/srv/conduit/conduit.toml' # if you want to configure purely by env vars, set this to an empty string '' # Available levels are: error, warn, info, debug, trace - more info at: https://docs.rs/env_logger/*/env_logger/#enabling-logging - # CONDUIT_LOG: info # default is: "warn,_=off,sled=off" # CONDUIT_ALLOW_JAEGER: 'false' # CONDUIT_ALLOW_ENCRYPTION: 'true' # CONDUIT_ALLOW_FEDERATION: 'true' diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 5bcf84f7..97f91daf 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -32,7 +32,6 @@ services: CONDUIT_ALLOW_CHECK_FOR_UPDATES: 'true' CONDUIT_TRUSTED_SERVERS: '["matrix.org"]' #CONDUIT_MAX_CONCURRENT_REQUESTS: 100 - #CONDUIT_LOG: warn,rocket=off,_=off,sled=off CONDUIT_ADDRESS: 0.0.0.0 CONDUIT_CONFIG: '' # Ignore this # From 516876f8ef5f88c42b44ef1c485dd9e69cb9659b Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 10 Mar 2024 22:37:22 -0700 Subject: [PATCH 095/129] remove final reference to sled in log config --- src/config/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/mod.rs b/src/config/mod.rs index a4d7cca4..4605855f 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -264,7 +264,7 @@ fn default_trusted_servers() -> Vec { } fn default_log() -> String { - "warn,state_res=warn,_=off,sled=off".to_owned() + "warn,state_res=warn,_=off".to_owned() } fn default_turn_ttl() -> u64 { From dc89fbed3ad6296e72c68f4209116cf05870fc27 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 10 Mar 2024 22:38:02 -0700 Subject: [PATCH 096/129] document log config syntax, don't give example Because the old one was stale. Shocking! --- conduit-example.toml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/conduit-example.toml b/conduit-example.toml index 836db654..a52121ac 100644 --- a/conduit-example.toml +++ b/conduit-example.toml @@ -51,7 +51,11 @@ enable_lightning_bolt = true trusted_servers = ["matrix.org"] #max_concurrent_requests = 100 # How many requests Conduit sends to other servers at the same time -#log = "warn,state_res=warn,rocket=off,_=off,sled=off" + +# Controls the log verbosity. See also [here][0]. +# +# [0]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives +#log = "..." address = "127.0.0.1" # This makes sure Conduit can only be reached using the reverse proxy #address = "0.0.0.0" # If Conduit is running in a container, make sure the reverse proxy (ie. Traefik) can reach it. From d1bc7fcfd2493b77a4f701e333d3eb0faf5e5109 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Sun, 10 Mar 2024 23:39:02 -0700 Subject: [PATCH 097/129] rename the `rust-rocksdb` crate to just `rocksdb` This way the old `cfg`s still work and we don't need to constantly remind ourselves what programming language we're using in `use` statements. Also fixes a problem where RocksDB users couldn't start Conduit because the old `cfg`s were using the original crate's name instead of the `backend_rocksdb` feature name for some reason. Maybe that should be changed, but I'm not sure. --- Cargo.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7bb3b5db..08188cb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -114,7 +114,8 @@ async-trait = "0.1.68" sd-notify = { version = "0.4.1", optional = true } -[dependencies.rust-rocksdb] +[dependencies.rocksdb] +package = "rust-rocksdb" version = "0.22.7" optional = true features = [ @@ -131,7 +132,7 @@ default = ["conduit_bin", "backend_sqlite", "backend_rocksdb", "systemd"] backend_persy = ["persy", "parking_lot"] backend_sqlite = ["sqlite"] #backend_heed = ["heed", "crossbeam"] -backend_rocksdb = ["rust-rocksdb"] +backend_rocksdb = ["rocksdb"] jemalloc = ["tikv-jemalloc-ctl", "tikv-jemallocator"] sqlite = ["rusqlite", "parking_lot", "tokio/signal"] conduit_bin = ["axum"] From 4af691d737b29f6fa7e98d302279f5a85a2c879a Mon Sep 17 00:00:00 2001 From: Samuel Meenzen Date: Mon, 11 Mar 2024 11:43:05 +0100 Subject: [PATCH 098/129] fix(ci): avoid duplicate pipelines --- .gitlab-ci.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 348e7b19..3b7016fb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,6 +7,15 @@ variables: # Makes some things print in color TERM: ansi +# Avoid duplicate pipelines +# See: https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines +workflow: + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS + when: never + - if: $CI + before_script: # Enable nix-command and flakes - if command -v nix > /dev/null; then echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf; fi @@ -52,10 +61,14 @@ ci: rules: # CI on upstream runners (only available for maintainers) - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $IS_UPSTREAM_CI == "true" + # Manual CI on unprotected branches that are not MRs + - if: $CI_PIPELINE_SOURCE != "merge_request_event" && $CI_COMMIT_REF_PROTECTED == "false" + when: manual # Manual CI on forks - if: $IS_UPSTREAM_CI != "true" when: manual - if: $CI + interruptible: true artifacts: stage: artifacts @@ -100,6 +113,7 @@ artifacts: when: manual allow_failure: true - if: $CI + interruptible: true .push-oci-image: stage: publish From 9a81a49c6ae1217928658dd1d6742868ec40931e Mon Sep 17 00:00:00 2001 From: Max Cohen Date: Sun, 25 Sep 2022 10:59:19 +0200 Subject: [PATCH 099/129] Add argument parser for the conduit executable Allow fetching the version with `conduit --version`. Fixes #285. --- src/clap.rs | 13 +++++++++++++ src/lib.rs | 1 + src/main.rs | 2 ++ 3 files changed, 16 insertions(+) create mode 100644 src/clap.rs diff --git a/src/clap.rs b/src/clap.rs new file mode 100644 index 00000000..444f21bf --- /dev/null +++ b/src/clap.rs @@ -0,0 +1,13 @@ +//! Integration with `clap` + +use clap::Parser; + +/// Command line arguments +#[derive(Parser)] +#[clap(about, version)] +pub struct Args {} + +/// Parse command line arguments into structured data +pub fn parse() -> Args { + Args::parse() +} diff --git a/src/lib.rs b/src/lib.rs index 70c6f373..5a89f805 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ pub mod api; +pub mod clap; mod config; mod database; mod service; diff --git a/src/main.rs b/src/main.rs index 524f6886..e5861846 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,6 +44,8 @@ static GLOBAL: Jemalloc = Jemalloc; #[tokio::main] async fn main() { + clap::parse(); + // Initialize config let raw_config = Figment::new() From ac22b1bed13c298b566acf503cba47e7e9bc072a Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Mon, 11 Mar 2024 20:11:59 -0700 Subject: [PATCH 100/129] allow including extra info in `--version` output --- Cargo.toml | 2 +- flake.nix | 1 + src/clap.rs | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 08188cb3..796791bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,7 +102,7 @@ thread_local = "1.1.7" hmac = "0.12.1" sha-1 = "0.10.1" # used for conduit's CLI and admin room command parsing -clap = { version = "4.3.0", default-features = false, features = ["std", "derive", "help", "usage", "error-context"] } +clap = { version = "4.3.0", default-features = false, features = ["std", "derive", "help", "usage", "error-context", "string"] } futures-util = { version = "0.3.28", default-features = false } # Used for reading the configuration from conduit.toml & environment variables figment = { version = "0.10.8", features = ["env", "toml"] } diff --git a/flake.nix b/flake.nix index cdfe91f8..97f68354 100644 --- a/flake.nix +++ b/flake.nix @@ -73,6 +73,7 @@ }); env = pkgs: { + CONDUIT_VERSION_EXTRA = self.shortRev or self.dirtyShortRev; ROCKSDB_INCLUDE_DIR = "${rocksdb' pkgs}/include"; ROCKSDB_LIB_DIR = "${rocksdb' pkgs}/lib"; } diff --git a/src/clap.rs b/src/clap.rs index 444f21bf..170d2a17 100644 --- a/src/clap.rs +++ b/src/clap.rs @@ -2,9 +2,23 @@ use clap::Parser; +/// Returns the current version of the crate with extra info if supplied +/// +/// Set the environment variable `CONDUIT_VERSION_EXTRA` to any UTF-8 string to +/// include it in parenthesis after the SemVer version. A common value are git +/// commit hashes. +fn version() -> String { + let cargo_pkg_version = env!("CARGO_PKG_VERSION"); + + match option_env!("CONDUIT_VERSION_EXTRA") { + Some(x) => format!("{} ({})", cargo_pkg_version, x), + None => cargo_pkg_version.to_owned(), + } +} + /// Command line arguments #[derive(Parser)] -#[clap(about, version)] +#[clap(about, version = version())] pub struct Args {} /// Parse command line arguments into structured data From 425660472cdbb66fd1bfea30f387598b680ed64a Mon Sep 17 00:00:00 2001 From: Samuel Meenzen Date: Wed, 13 Mar 2024 18:01:41 +0100 Subject: [PATCH 101/129] docs: build docs using mdBook --- .gitignore | 3 ++ .gitlab/route-map.yml | 3 ++ README.md | 29 ++++++++++--------- book.toml | 18 ++++++++++++ debian/README.md | 2 +- docs/SUMMARY.md | 12 ++++++++ APPSERVICES.md => docs/appservices.md | 0 docs/configuration.md | 5 ++++ docs/deploying.md | 8 +++++ docs/deploying/debian.md | 1 + .../deploying}/docker-compose.for-traefik.yml | 0 .../deploying}/docker-compose.override.yml | 0 .../docker-compose.with-traefik.yml | 0 {docker => docs/deploying}/docker-compose.yml | 0 docker/README.md => docs/deploying/docker.md | 7 ++--- nix/README.md => docs/deploying/nix.md | 0 DEPLOY.md => docs/deploying/simple.md | 10 ++++--- docs/introduction.md | 13 +++++++++ TURN.md => docs/turn.md | 2 +- 19 files changed, 89 insertions(+), 24 deletions(-) create mode 100644 .gitlab/route-map.yml create mode 100644 book.toml create mode 100644 docs/SUMMARY.md rename APPSERVICES.md => docs/appservices.md (100%) create mode 100644 docs/configuration.md create mode 100644 docs/deploying.md create mode 100644 docs/deploying/debian.md rename {docker => docs/deploying}/docker-compose.for-traefik.yml (100%) rename {docker => docs/deploying}/docker-compose.override.yml (100%) rename {docker => docs/deploying}/docker-compose.with-traefik.yml (100%) rename {docker => docs/deploying}/docker-compose.yml (100%) rename docker/README.md => docs/deploying/docker.md (97%) rename nix/README.md => docs/deploying/nix.md (100%) rename DEPLOY.md => docs/deploying/simple.md (97%) create mode 100644 docs/introduction.md rename TURN.md => docs/turn.md (97%) diff --git a/.gitignore b/.gitignore index a34d70ad..73ce2e1f 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,6 @@ cached_target # Gitlab CI cache /.gitlab-ci.d + +# mdbook output +public/ \ No newline at end of file diff --git a/.gitlab/route-map.yml b/.gitlab/route-map.yml new file mode 100644 index 00000000..2c23079c --- /dev/null +++ b/.gitlab/route-map.yml @@ -0,0 +1,3 @@ +# Docs: Map markdown to html files +- source: /docs/(.+)\.md/ + public: '\1.html' \ No newline at end of file diff --git a/README.md b/README.md index bf7bde5e..0026f077 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,15 @@ # Conduit + + ### A Matrix homeserver written in Rust + + +Please visit the [Conduit documentation](https://famedly.gitlab.io/conduit) for more information. +Alternatively you can open [docs/introduction.md](docs/introduction.md) in this repository. + #### 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) @@ -30,16 +38,9 @@ There are still a few important features missing: - E2EE emoji comparison over federation (E2EE chat works) - Outgoing read receipts, typing, presence over federation (incoming works) + -#### How can I deploy my own? - -- Simple install (this was tested the most): [DEPLOY.md](DEPLOY.md) -- Debian package: [debian/README.md](debian/README.md) -- Nix/NixOS: [nix/README.md](nix/README.md) -- Docker: [docker/README.md](docker/README.md) - -If you want to connect an Appservice to Conduit, take a look at [APPSERVICES.md](APPSERVICES.md). - + #### How can I contribute? 1. Look for an issue you would like to work on and make sure no one else is currently working on it. @@ -56,7 +57,6 @@ If you have any questions, feel free to - Send an direct message to `@timokoesters:fachschaften.org` on Matrix - [Open an issue on GitLab](https://gitlab.com/famedly/conduit/-/issues/new) - #### Thanks to Thanks to FUTO, Famedly, Prototype Fund (DLR and German BMBF) and all individuals for financially supporting this project. @@ -68,10 +68,11 @@ Thanks to the contributors to Conduit and all libraries we use, for example: #### Donate -Liberapay: \ -Bitcoin: `bc1qnnykf986tw49ur7wx9rpw2tevpsztvar5x8w4n` +- Liberapay: +- Bitcoin: `bc1qnnykf986tw49ur7wx9rpw2tevpsztvar5x8w4n` #### Logo -Lightning Bolt Logo: https://github.com/mozilla/fxemoji/blob/gh-pages/svgs/nature/u26A1-bolt.svg \ -Logo License: https://github.com/mozilla/fxemoji/blob/gh-pages/LICENSE.md +- Lightning Bolt Logo: +- Logo License: + diff --git a/book.toml b/book.toml new file mode 100644 index 00000000..e25746ca --- /dev/null +++ b/book.toml @@ -0,0 +1,18 @@ +[book] +title = "Conduit" +description = "Conduit is a simple, fast and reliable chat server for the Matrix protocol" +language = "en" +multilingual = false +src = "docs" + +[build] +build-dir = "public" +create-missing = true + +[output.html] +git-repository-url = "https://gitlab.com/famedly/conduit" +edit-url-template = "https://gitlab.com/famedly/conduit/-/edit/next/{path}" +git-repository-icon = "fa-git-square" + +[output.html.search] +limit-results = 15 diff --git a/debian/README.md b/debian/README.md index 443be76b..4ddb614d 100644 --- a/debian/README.md +++ b/debian/README.md @@ -5,7 +5,7 @@ Installation ------------ Information about downloading, building and deploying the Debian package, see -the "Installing Conduit" section in [DEPLOY.md](../DEPLOY.md). +the "Installing Conduit" section in the Deploying docs. All following sections until "Setting up the Reverse Proxy" be ignored because this is handled automatically by the packaging. diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md new file mode 100644 index 00000000..e7ed05d7 --- /dev/null +++ b/docs/SUMMARY.md @@ -0,0 +1,12 @@ +# Summary + +- [Introduction](introduction.md) + +- [Example configuration](configuration.md) +- [Deployment options](deploying.md) + - [Simple (Recommended)](deploying/simple.md) + - [Debian](deploying/debian.md) + - [Docker](deploying/docker.md) + - [Nix](deploying/nix.md) +- [TURN](turn.md) +- [Appservices](appservices.md) diff --git a/APPSERVICES.md b/docs/appservices.md similarity index 100% rename from APPSERVICES.md rename to docs/appservices.md diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 00000000..a47e5ff9 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,5 @@ +# Example configuration + +``` toml +{{#include ../conduit-example.toml}} +``` diff --git a/docs/deploying.md b/docs/deploying.md new file mode 100644 index 00000000..3694f6b2 --- /dev/null +++ b/docs/deploying.md @@ -0,0 +1,8 @@ +# Deployment options + +There are several ways to deploy a Conduit server. + +- [Simple (Recommended)](deploying/simple.md) - This is the recommended way to set up Conduit. +- [Debian](deploying/debian.md) - If you're using a debian-based system, you may find the `deb` package useful. +- [Docker](deploying/docker.md) - We provide multi-arch OCI images for Conduit. +- [Nix](deploying/nix.md) - Nix flake based setup. diff --git a/docs/deploying/debian.md b/docs/deploying/debian.md new file mode 100644 index 00000000..2e8a544a --- /dev/null +++ b/docs/deploying/debian.md @@ -0,0 +1 @@ +{{#include ../../debian/README.md}} diff --git a/docker/docker-compose.for-traefik.yml b/docs/deploying/docker-compose.for-traefik.yml similarity index 100% rename from docker/docker-compose.for-traefik.yml rename to docs/deploying/docker-compose.for-traefik.yml diff --git a/docker/docker-compose.override.yml b/docs/deploying/docker-compose.override.yml similarity index 100% rename from docker/docker-compose.override.yml rename to docs/deploying/docker-compose.override.yml diff --git a/docker/docker-compose.with-traefik.yml b/docs/deploying/docker-compose.with-traefik.yml similarity index 100% rename from docker/docker-compose.with-traefik.yml rename to docs/deploying/docker-compose.with-traefik.yml diff --git a/docker/docker-compose.yml b/docs/deploying/docker-compose.yml similarity index 100% rename from docker/docker-compose.yml rename to docs/deploying/docker-compose.yml diff --git a/docker/README.md b/docs/deploying/docker.md similarity index 97% rename from docker/README.md rename to docs/deploying/docker.md index 2448e643..4a38b30b 100644 --- a/docker/README.md +++ b/docs/deploying/docker.md @@ -69,7 +69,7 @@ docker run -d -p 8448:6167 \ or you can use [docker-compose](#docker-compose). -The `-d` flag lets the container run in detached mode. You now need to supply a `conduit.toml` config file, an example can be found [here](../conduit-example.toml). +The `-d` flag lets the container run in detached mode. You now need to supply a `conduit.toml` config file, an example can be found [here](../configuration.md). You can pass in different env vars to change config values on the fly. You can even configure Conduit completely by using env vars, but for that you need to pass `-e CONDUIT_CONFIG=""` into your container. For an overview of possible values, please take a look at the `docker-compose.yml` file. @@ -87,8 +87,7 @@ Depending on your proxy setup, you can use one of the following files; When picking the traefik-related compose file, rename it so it matches `docker-compose.yml`, and rename the override file to `docker-compose.override.yml`. Edit the latter with the values you want for your server. - -Additional info about deploying Conduit can be found [here](../DEPLOY.md). +Additional info about deploying Conduit can be found [here](simple.md). ### Build @@ -130,7 +129,7 @@ So...step by step: 1. Copy [`docker-compose.for-traefik.yml`](docker-compose.for-traefik.yml) (or [`docker-compose.with-traefik.yml`](docker-compose.with-traefik.yml)) and [`docker-compose.override.yml`](docker-compose.override.yml) from the repository and remove `.for-traefik` (or `.with-traefik`) from the filename. 2. Open both files and modify/adjust them to your needs. Meaning, change the `CONDUIT_SERVER_NAME` and the volume host mappings according to your needs. -3. Create the `conduit.toml` config file, an example can be found [here](../conduit-example.toml), or set `CONDUIT_CONFIG=""` and configure Conduit per env vars. +3. Create the `conduit.toml` config file, an example can be found [here](../configuration.md), or set `CONDUIT_CONFIG=""` and configure Conduit per env vars. 4. Uncomment the `element-web` service if you want to host your own Element Web Client and create a `element_config.json`. 5. Create the files needed by the `well-known` service. diff --git a/nix/README.md b/docs/deploying/nix.md similarity index 100% rename from nix/README.md rename to docs/deploying/nix.md diff --git a/DEPLOY.md b/docs/deploying/simple.md similarity index 97% rename from DEPLOY.md rename to docs/deploying/simple.md index e87fca3b..9542bf1a 100644 --- a/DEPLOY.md +++ b/docs/deploying/simple.md @@ -1,4 +1,6 @@ -# Deploying Conduit +# Simple setup + +This is the recommended way to set up Conduit. It is the easiest way to get started and is suitable for most use cases. > ## Getting help > @@ -141,7 +143,7 @@ $ sudo systemctl daemon-reload Now we need to create the Conduit's config file in `/etc/matrix-conduit/conduit.toml`. Paste in the contents of -[`conduit-example.toml`](./conduit-example.toml) **and take a moment to read it. +[`conduit-example.toml`](../configuration.md) **and take a moment to read it. You need to change at least the server name.** You can also choose to use a different database backend, but right now only `rocksdb` and `sqlite` are recommended. @@ -305,8 +307,8 @@ $ curl https://your.server.name:8448/_matrix/client/versions ## Audio/Video calls -For Audio/Video call functionality see the [TURN Guide](TURN.md). +For Audio/Video call functionality see the [TURN Guide](../turn.md). ## Appservices -If you want to set up an appservice, take a look at the [Appservice Guide](APPSERVICES.md). +If you want to set up an appservice, take a look at the [Appservice Guide](../appservices.md). diff --git a/docs/introduction.md b/docs/introduction.md new file mode 100644 index 00000000..da34ab6e --- /dev/null +++ b/docs/introduction.md @@ -0,0 +1,13 @@ +# Conduit + +{{#include ../README.md:catchphrase}} + +{{#include ../README.md:body}} + +#### How can I deploy my own? + +- [Deployment options](deploying.md) + +If you want to connect an Appservice to Conduit, take a look at the [appservices documentation](appservices.md). + +{{#include ../README.md:footer}} diff --git a/TURN.md b/docs/turn.md similarity index 97% rename from TURN.md rename to docs/turn.md index 63c1e99f..a61f1b13 100644 --- a/TURN.md +++ b/docs/turn.md @@ -22,4 +22,4 @@ turn_secret = "ADD SECRET HERE" ## Apply settings -Restart Conduit. \ No newline at end of file +Restart Conduit. From 4f8d3953b36e8a67deba44ef524e4e032453c575 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 14 Mar 2024 20:19:02 -0700 Subject: [PATCH 102/129] add nix output for the book --- flake.nix | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/flake.nix b/flake.nix index cdfe91f8..0e699e1d 100644 --- a/flake.nix +++ b/flake.nix @@ -207,6 +207,35 @@ packages = { default = package pkgsHost; oci-image = mkOciImage pkgsHost self.packages.${system}.default; + + book = + let + package = self.packages.${system}.default; + in + pkgsHost.stdenv.mkDerivation { + pname = "${package.pname}-book"; + version = package.version; + + src = nix-filter { + root = ./.; + include = [ + "book.toml" + "conduit-example.toml" + "README.md" + "debian/README.md" + "docs" + ]; + }; + + nativeBuildInputs = (with pkgsHost; [ + mdbook + ]); + + buildPhase = '' + mdbook build + mv public $out + ''; + }; } // builtins.listToAttrs From 6800e5fd185095ec84bdd692b2bd45502f94891a Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 14 Mar 2024 20:27:44 -0700 Subject: [PATCH 103/129] build book in ci, deploy it to gitlab pages --- .gitlab-ci.yml | 17 +++++++++++++++++ engage.toml | 10 ++++++++++ flake.nix | 3 +++ 3 files changed, 30 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3b7016fb..8c880b9c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -98,6 +98,10 @@ artifacts: - ./bin/nix-build-and-cache .#oci-image-aarch64-unknown-linux-musl - cp result oci-image-arm64v8.tar.gz + + - ./bin/nix-build-and-cache .#book + # We can't just copy the symlink, we need to dereference it https://gitlab.com/gitlab-org/gitlab/-/issues/19746 + - cp -r --dereference result public artifacts: paths: - x86_64-unknown-linux-musl @@ -105,6 +109,7 @@ artifacts: - x86_64-unknown-linux-musl.deb - oci-image-amd64.tar.gz - oci-image-arm64v8.tar.gz + - public rules: # CI required for all MRs - if: $CI_PIPELINE_SOURCE == "merge_request_event" @@ -165,3 +170,15 @@ oci-image:push-dockerhub: IMAGE_NAME: matrixconduit/matrix-conduit before_script: - docker login -u $DOCKER_HUB_USER -p $DOCKER_HUB_PASSWORD + +pages: + stage: publish + dependencies: + - artifacts + only: + - next + script: + - "true" + artifacts: + paths: + - public diff --git a/engage.toml b/engage.toml index 3e8884eb..cb284167 100644 --- a/engage.toml +++ b/engage.toml @@ -30,6 +30,11 @@ name = "cargo-clippy" group = "versions" script = "cargo clippy -- --version" +[[task]] +name = "lychee" +group = "versions" +script = "lychee --version" + [[task]] name = "cargo-fmt" group = "lints" @@ -51,6 +56,11 @@ name = "cargo-clippy" group = "lints" script = "cargo clippy --workspace --all-targets --color=always -- -D warnings" +[[task]] +name = "lychee" +group = "lints" +script = "lychee --offline docs" + [[task]] name = "cargo" group = "tests" diff --git a/flake.nix b/flake.nix index 0e699e1d..9cd826b8 100644 --- a/flake.nix +++ b/flake.nix @@ -304,6 +304,9 @@ # Needed for our script for Complement jq + + # Needed for finding broken markdown links + lychee ]); }; }); From a3968725b4938fec2fcbd24e655f8b5ba2d53490 Mon Sep 17 00:00:00 2001 From: Samuel Meenzen Date: Fri, 15 Mar 2024 12:23:09 +0100 Subject: [PATCH 104/129] chore: add EditorConfig --- .editorconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..a4e9e432 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# EditorConfig is awesome: https://EditorConfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +tab_width = 4 +indent_size = 4 +indent_style = space +insert_final_newline = true +max_line_length = 120 + +[*.nix] +indent_size = 2 From 120035685b225a318844f8aed9b4088644fe9ff9 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sun, 17 Mar 2024 17:13:34 +0000 Subject: [PATCH 105/129] docs: point people to the matrix client list instead of element --- README.md | 3 +-- docs/deploying/simple.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0026f077..474a5247 100644 --- a/README.md +++ b/README.md @@ -23,8 +23,7 @@ friends or company. #### Can I try it out? -Yes! You can test our Conduit instance by opening a Matrix client ( or Element Android for -example) and registering on the `conduit.rs` homeserver. The registration token is "for_testing_only". Don't share personal information. +Yes! You can test our Conduit instance by opening a client that supports registration tokens such as [Element web](https://app.element.io/), [Nheko](https://matrix.org/ecosystem/clients/nheko/) or [SchildiChat web](https://app.schildi.chat/) and registering on the `conduit.rs` homeserver. The registration token is "for_testing_only". Don't share personal information. Once you have registered, you can use any other [Matrix client](https://matrix.org/ecosystem/clients) to login. Server hosting for conduit.rs is donated by the Matrix.org Foundation. diff --git a/docs/deploying/simple.md b/docs/deploying/simple.md index 9542bf1a..ea12a281 100644 --- a/docs/deploying/simple.md +++ b/docs/deploying/simple.md @@ -289,7 +289,7 @@ $ sudo systemctl enable conduit ## How do I know it works? -You can open , enter your homeserver and try to register. +You can open [a Matrix client](https://matrix.org/ecosystem/clients), enter your homeserver and try to register. If you are using a registration token, use [Element web](https://app.element.io/), [Nheko](https://matrix.org/ecosystem/clients/nheko/) or [SchildiChat web](https://app.schildi.chat/), as they support this feature. You can also use these commands as a quick health check. From 5f0bea69614de0bc0dac3b440fcb070274ccb9cb Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sat, 16 Mar 2024 19:04:54 +0000 Subject: [PATCH 106/129] refactor: check if federation is disabled inside the authcheck where possible --- src/api/ruma_wrapper/axum.rs | 4 +++ src/api/server_server.rs | 68 ------------------------------------ 2 files changed, 4 insertions(+), 68 deletions(-) diff --git a/src/api/ruma_wrapper/axum.rs b/src/api/ruma_wrapper/axum.rs index bbd48614..c6a19578 100644 --- a/src/api/ruma_wrapper/axum.rs +++ b/src/api/ruma_wrapper/axum.rs @@ -149,6 +149,10 @@ where } } AuthScheme::ServerSignatures => { + if !services().globals.allow_federation() { + return Err(Error::bad_config("Federation is disabled.")); + } + let TypedHeader(Authorization(x_matrix)) = parts .extract::>>() .await diff --git a/src/api/server_server.rs b/src/api/server_server.rs index f946feaf..e0335493 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -601,10 +601,6 @@ pub async fn get_server_keys_deprecated_route() -> impl IntoResponse { pub async fn get_public_rooms_filtered_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let response = client_server::get_public_rooms_filtered_helper( None, body.limit, @@ -628,10 +624,6 @@ pub async fn get_public_rooms_filtered_route( pub async fn get_public_rooms_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let response = client_server::get_public_rooms_filtered_helper( None, body.limit, @@ -686,10 +678,6 @@ pub fn parse_incoming_pdu( pub async fn send_transaction_message_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let sender_servername = body .sender_servername .as_ref() @@ -954,10 +942,6 @@ pub async fn send_transaction_message_route( pub async fn get_event_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let sender_servername = body .sender_servername .as_ref() @@ -1016,10 +1000,6 @@ pub async fn get_event_route( pub async fn get_backfill_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let sender_servername = body .sender_servername .as_ref() @@ -1092,10 +1072,6 @@ pub async fn get_backfill_route( pub async fn get_missing_events_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let sender_servername = body .sender_servername .as_ref() @@ -1181,10 +1157,6 @@ pub async fn get_missing_events_route( pub async fn get_event_authorization_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let sender_servername = body .sender_servername .as_ref() @@ -1243,10 +1215,6 @@ pub async fn get_event_authorization_route( pub async fn get_room_state_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let sender_servername = body .sender_servername .as_ref() @@ -1323,10 +1291,6 @@ pub async fn get_room_state_route( pub async fn get_room_state_ids_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let sender_servername = body .sender_servername .as_ref() @@ -1384,10 +1348,6 @@ pub async fn get_room_state_ids_route( pub async fn create_join_event_template_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - if !services().rooms.metadata.exists(&body.room_id)? { return Err(Error::BadRequest( ErrorKind::NotFound, @@ -1495,10 +1455,6 @@ async fn create_join_event( room_id: &RoomId, pdu: &RawJsonValue, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - if !services().rooms.metadata.exists(room_id)? { return Err(Error::BadRequest( ErrorKind::NotFound, @@ -1679,10 +1635,6 @@ pub async fn create_join_event_v2_route( pub async fn create_invite_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let sender_servername = body .sender_servername .as_ref() @@ -1796,10 +1748,6 @@ pub async fn create_invite_route( pub async fn get_devices_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - if body.user_id.server_name() != services().globals.server_name() { return Err(Error::BadRequest( ErrorKind::InvalidParam, @@ -1852,10 +1800,6 @@ pub async fn get_devices_route( pub async fn get_room_information_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - let room_id = services() .rooms .alias @@ -1877,10 +1821,6 @@ pub async fn get_room_information_route( pub async fn get_profile_information_route( body: Ruma, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - if body.user_id.server_name() != services().globals.server_name() { return Err(Error::BadRequest( ErrorKind::InvalidParam, @@ -1920,10 +1860,6 @@ pub async fn get_profile_information_route( /// /// Gets devices and identity keys for the given users. pub async fn get_keys_route(body: Ruma) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - if body .device_keys .iter() @@ -1953,10 +1889,6 @@ pub async fn get_keys_route(body: Ruma) -> Result, ) -> Result { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - if body .one_time_keys .iter() From 879a8b969d4a6b664c2f00c219d8c18ca3d821da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 13 Mar 2024 12:52:11 +0100 Subject: [PATCH 107/129] improvement: use simpler rocksdb config --- Cargo.lock | 434 ++++++++++++------------ Cargo.toml | 1 + src/api/client_server/sync.rs | 4 +- src/api/client_server/user_directory.rs | 31 +- src/database/abstraction/rocksdb.rs | 73 ++-- 5 files changed, 288 insertions(+), 255 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88217001..4d294c08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -46,15 +46,15 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "anstyle" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "arc-swap" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "7b3d0060af21e8d11a926981cc00c6c1541aa91dd64b9f881985c3da1094425f" [[package]] name = "arrayref" @@ -88,7 +88,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -204,22 +204,22 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bindgen" -version = "0.69.2" +version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c69fae65a523209d34240b60abe0c42d33d1045d445c0839d8a4894a736e2d" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ "bitflags 2.4.2", "cexpr", "clang-sys", + "itertools 0.12.1", "lazy_static", "lazycell", - "peeking_take_while", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -256,15 +256,15 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "bytemuck" -version = "1.14.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2490600f404f2b94c167e31d3ed1d5f3c225a0f3b80230053b3e0b7b962bd9" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" [[package]] name = "byteorder" @@ -291,9 +291,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" dependencies = [ "jobserver", "libc", @@ -327,9 +327,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.18" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ "clap_builder", "clap_derive", @@ -337,9 +337,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstyle", "clap_lex", @@ -347,21 +347,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "color_quant" @@ -484,18 +484,18 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ "crossbeam-utils", ] @@ -518,9 +518,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ "cfg-if", "cpufeatures", @@ -541,7 +541,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -625,9 +625,9 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", @@ -640,9 +640,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" [[package]] name = "encoding_rs" @@ -694,9 +694,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" +checksum = "1676f435fc1dadde4d03e43f5d62b259e1ce5f40bd4ffb21db2b42ebe59c1382" [[package]] name = "figment" @@ -803,7 +803,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -861,9 +861,9 @@ dependencies = [ [[package]] name = "gif" -version = "0.12.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" dependencies = [ "color_quant", "weezl", @@ -893,7 +893,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.2.1", + "indexmap 2.2.5", "slab", "tokio", "tokio-util", @@ -957,9 +957,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.4" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hmac" @@ -983,9 +983,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -1082,9 +1082,9 @@ dependencies = [ [[package]] name = "image" -version = "0.24.8" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" dependencies = [ "bytemuck", "byteorder", @@ -1107,9 +1107,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.1" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -1155,6 +1155,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" @@ -1163,9 +1172,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" dependencies = [ "libc", ] @@ -1178,9 +1187,9 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1252,18 +1261,18 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-sys 0.48.0", + "windows-targets 0.52.4", ] [[package]] @@ -1317,9 +1326,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lru-cache" @@ -1402,9 +1411,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", "simd-adler32", @@ -1412,9 +1421,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi", @@ -1465,21 +1474,26 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] @@ -1653,15 +1667,9 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.48", + "syn 2.0.52", ] -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "pem" version = "3.0.3" @@ -1680,9 +1688,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "persy" -version = "1.4.7" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd38c602b23c2f451842d89f27cd5e0d4b292176daf40feeda859c658dcdc76" +checksum = "9ef4b7250ab3a90ded0e284b2633469c23ef01ea868fe7cbb64e2f0a7d6f6d02" dependencies = [ "crc", "data-encoding", @@ -1696,22 +1704,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -1738,9 +1746,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "platforms" @@ -1750,9 +1758,9 @@ checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "png" -version = "0.17.11" +version = "0.17.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" +checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -1775,18 +1783,19 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" dependencies = [ - "toml_edit 0.20.7", + "toml_datetime", + "toml_edit", ] [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -1799,7 +1808,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "version_check", "yansi", ] @@ -1877,7 +1886,7 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.6", "regex-syntax 0.8.2", ] @@ -1892,9 +1901,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -1915,9 +1924,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2" dependencies = [ "base64", "bytes", @@ -1942,6 +1951,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-rustls", @@ -1966,16 +1976,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2038,7 +2049,7 @@ dependencies = [ "bytes", "form_urlencoded", "http", - "indexmap 2.2.1", + "indexmap 2.2.5", "js_int", "konst", "percent-encoding", @@ -2062,7 +2073,7 @@ version = "0.27.11" source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ "as_variant", - "indexmap 2.2.1", + "indexmap 2.2.5", "js_int", "js_option", "percent-encoding", @@ -2120,7 +2131,7 @@ dependencies = [ "quote", "ruma-identifiers-validation", "serde", - "syn 2.0.48", + "syn 2.0.52", "toml", ] @@ -2157,7 +2168,7 @@ name = "ruma-state-res" version = "0.10.0" source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" dependencies = [ - "itertools", + "itertools 0.11.0", "js_int", "ruma-common", "ruma-events", @@ -2291,9 +2302,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "schannel" @@ -2351,38 +2362,38 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] name = "serde_html_form" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20e1066e1cfa6692a722cf40386a2caec36da5ddc4a2c16df592f0f609677e8c" +checksum = "50437e6a58912eecc08865e35ea2e8d365fbb2db0debb1c8bb43bf1faf055f25" dependencies = [ "form_urlencoded", - "indexmap 2.2.1", + "indexmap 2.2.5", "itoa", "ryu", "serde", @@ -2390,9 +2401,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", @@ -2401,9 +2412,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ "itoa", "serde", @@ -2432,11 +2443,11 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.31" +version = "0.9.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e" +checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" dependencies = [ - "indexmap 2.2.1", + "indexmap 2.2.5", "itoa", "ryu", "serde", @@ -2544,12 +2555,12 @@ checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2596,9 +2607,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -2634,29 +2645,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -2717,12 +2728,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -2737,10 +2749,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -2761,9 +2774,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -2785,7 +2798,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -2837,43 +2850,32 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.20.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" -dependencies = [ - "indexmap 2.2.1", - "toml_datetime", - "winnow", -] - -[[package]] -name = "toml_edit" -version = "0.21.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "indexmap 2.2.1", + "indexmap 2.2.5", "serde", "serde_spanned", "toml_datetime", @@ -2947,7 +2949,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] @@ -3120,9 +3122,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] @@ -3135,9 +3137,9 @@ checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" [[package]] name = "unsigned-varint" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" [[package]] name = "untrusted" @@ -3200,9 +3202,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3210,24 +3212,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3237,9 +3239,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3247,28 +3249,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -3288,9 +3290,9 @@ checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" [[package]] name = "wildmatch" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "495ec47bf3c1345005f40724f0269362c8556cbc43aed0526ed44cae1d35fceb" +checksum = "017f0a8ed8331210d91b7a4c30d4edef8f21a65c02f2540496e2e79725f6d8a8" [[package]] name = "winapi" @@ -3329,7 +3331,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.4", ] [[package]] @@ -3349,17 +3351,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -3370,9 +3372,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -3382,9 +3384,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -3394,9 +3396,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -3406,9 +3408,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -3418,9 +3420,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -3430,9 +3432,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -3442,15 +3444,15 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "winnow" -version = "0.5.35" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1931d78a9c73861da0134f453bb1f790ce49b2e30eba8410b4b79bac72b46a2d" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] @@ -3467,9 +3469,9 @@ dependencies = [ [[package]] name = "yansi" -version = "1.0.0-rc.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" @@ -3488,7 +3490,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.52", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 08188cb3..ac334728 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -121,6 +121,7 @@ optional = true features = [ "multi-threaded-cf", "zstd", + "lz4", ] [target.'cfg(unix)'.dependencies] diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index c510f5f5..103daeb0 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -29,7 +29,7 @@ use std::{ time::Duration, }; use tokio::sync::watch::Sender; -use tracing::error; +use tracing::{error, info}; /// # `GET /_matrix/client/r0/sync` /// @@ -99,6 +99,8 @@ pub async fn sync_events_route( o.insert((body.since.clone(), rx.clone())); + info!("Sync started for {sender_user}"); + tokio::spawn(sync_helper_wrapper( sender_user.clone(), sender_device.clone(), diff --git a/src/api/client_server/user_directory.rs b/src/api/client_server/user_directory.rs index c30bac51..b4d11800 100644 --- a/src/api/client_server/user_directory.rs +++ b/src/api/client_server/user_directory.rs @@ -48,6 +48,9 @@ pub async fn search_users_route( return None; } + // It's a matching user, but is the sender allowed to see them? + let mut user_visible = false; + let user_is_in_public_rooms = services() .rooms .state_cache @@ -69,22 +72,26 @@ pub async fn search_users_route( }); if user_is_in_public_rooms { - return Some(user); - } + user_visible = true; + } else { + let user_is_in_shared_rooms = services() + .rooms + .user + .get_shared_rooms(vec![sender_user.clone(), user_id]) + .ok()? + .next() + .is_some(); - let user_is_in_shared_rooms = services() - .rooms - .user - .get_shared_rooms(vec![sender_user.clone(), user_id]) - .ok()? - .next() - .is_some(); + if user_is_in_shared_rooms { + user_visible = true; + } + } - if user_is_in_shared_rooms { - return Some(user); + if !user_visible { + return None; } - None + Some(user) }); let results = users.by_ref().take(limit).collect(); diff --git a/src/database/abstraction/rocksdb.rs b/src/database/abstraction/rocksdb.rs index 7a93d787..447ee038 100644 --- a/src/database/abstraction/rocksdb.rs +++ b/src/database/abstraction/rocksdb.rs @@ -23,29 +23,23 @@ pub struct RocksDbEngineTree<'a> { fn db_options(max_open_files: i32, rocksdb_cache: &rocksdb::Cache) -> rocksdb::Options { let mut block_based_options = rocksdb::BlockBasedOptions::default(); block_based_options.set_block_cache(rocksdb_cache); - - // "Difference of spinning disk" - // https://zhangyuchi.gitbooks.io/rocksdbbook/content/RocksDB-Tuning-Guide.html + block_based_options.set_bloom_filter(10.0, false); block_based_options.set_block_size(4 * 1024); block_based_options.set_cache_index_and_filter_blocks(true); + block_based_options.set_pin_l0_filter_and_index_blocks_in_cache(true); + block_based_options.set_optimize_filters_for_memory(true); let mut db_opts = rocksdb::Options::default(); db_opts.set_block_based_table_factory(&block_based_options); - db_opts.set_optimize_filters_for_hits(true); - db_opts.set_skip_stats_update_on_db_open(true); - db_opts.set_level_compaction_dynamic_level_bytes(true); - db_opts.set_target_file_size_base(256 * 1024 * 1024); - //db_opts.set_compaction_readahead_size(2 * 1024 * 1024); - //db_opts.set_use_direct_reads(true); - //db_opts.set_use_direct_io_for_flush_and_compaction(true); db_opts.create_if_missing(true); db_opts.increase_parallelism(num_cpus::get() as i32); db_opts.set_max_open_files(max_open_files); - db_opts.set_compression_type(rocksdb::DBCompressionType::Zstd); + db_opts.set_compression_type(rocksdb::DBCompressionType::Lz4); + db_opts.set_bottommost_compression_type(rocksdb::DBCompressionType::Zstd); db_opts.set_compaction_style(rocksdb::DBCompactionStyle::Level); - db_opts.optimize_level_style_compaction(10 * 1024 * 1024); // https://github.com/facebook/rocksdb/wiki/Setup-Options-and-Basic-Tuning + db_opts.set_level_compaction_dynamic_level_bytes(true); db_opts.set_max_background_jobs(6); db_opts.set_bytes_per_sync(1048576); @@ -59,9 +53,6 @@ fn db_options(max_open_files: i32, rocksdb_cache: &rocksdb::Cache) -> rocksdb::O // restored via federation. db_opts.set_wal_recovery_mode(rocksdb::DBRecoveryMode::TolerateCorruptedTailRecords); - let prefix_extractor = rocksdb::SliceTransform::create_fixed_prefix(1); - db_opts.set_prefix_extractor(prefix_extractor); - db_opts } @@ -147,12 +138,17 @@ impl RocksDbEngineTree<'_> { impl KvTree for RocksDbEngineTree<'_> { fn get(&self, key: &[u8]) -> Result>> { - Ok(self.db.rocks.get_cf(&self.cf(), key)?) + let readoptions = rocksdb::ReadOptions::default(); + + Ok(self.db.rocks.get_cf_opt(&self.cf(), key, &readoptions)?) } fn insert(&self, key: &[u8], value: &[u8]) -> Result<()> { + let writeoptions = rocksdb::WriteOptions::default(); let lock = self.write_lock.read().unwrap(); - self.db.rocks.put_cf(&self.cf(), key, value)?; + self.db + .rocks + .put_cf_opt(&self.cf(), key, value, &writeoptions)?; drop(lock); self.watchers.wake(key); @@ -161,22 +157,31 @@ impl KvTree for RocksDbEngineTree<'_> { } fn insert_batch<'a>(&self, iter: &mut dyn Iterator, Vec)>) -> Result<()> { + let writeoptions = rocksdb::WriteOptions::default(); for (key, value) in iter { - self.db.rocks.put_cf(&self.cf(), key, value)?; + self.db + .rocks + .put_cf_opt(&self.cf(), key, value, &writeoptions)?; } Ok(()) } fn remove(&self, key: &[u8]) -> Result<()> { - Ok(self.db.rocks.delete_cf(&self.cf(), key)?) + let writeoptions = rocksdb::WriteOptions::default(); + Ok(self + .db + .rocks + .delete_cf_opt(&self.cf(), key, &writeoptions)?) } fn iter<'a>(&'a self) -> Box, Vec)> + 'a> { + let readoptions = rocksdb::ReadOptions::default(); + Box::new( self.db .rocks - .iterator_cf(&self.cf(), rocksdb::IteratorMode::Start) + .iterator_cf_opt(&self.cf(), readoptions, rocksdb::IteratorMode::Start) .map(|r| r.unwrap()) .map(|(k, v)| (Vec::from(k), Vec::from(v))), ) @@ -187,11 +192,14 @@ impl KvTree for RocksDbEngineTree<'_> { from: &[u8], backwards: bool, ) -> Box, Vec)> + 'a> { + let readoptions = rocksdb::ReadOptions::default(); + Box::new( self.db .rocks - .iterator_cf( + .iterator_cf_opt( &self.cf(), + readoptions, rocksdb::IteratorMode::From( from, if backwards { @@ -207,23 +215,33 @@ impl KvTree for RocksDbEngineTree<'_> { } fn increment(&self, key: &[u8]) -> Result> { + let readoptions = rocksdb::ReadOptions::default(); + let writeoptions = rocksdb::WriteOptions::default(); + let lock = self.write_lock.write().unwrap(); - let old = self.db.rocks.get_cf(&self.cf(), key)?; + let old = self.db.rocks.get_cf_opt(&self.cf(), key, &readoptions)?; let new = utils::increment(old.as_deref()).unwrap(); - self.db.rocks.put_cf(&self.cf(), key, &new)?; + self.db + .rocks + .put_cf_opt(&self.cf(), key, &new, &writeoptions)?; drop(lock); Ok(new) } fn increment_batch<'a>(&self, iter: &mut dyn Iterator>) -> Result<()> { + let readoptions = rocksdb::ReadOptions::default(); + let writeoptions = rocksdb::WriteOptions::default(); + let lock = self.write_lock.write().unwrap(); for key in iter { - let old = self.db.rocks.get_cf(&self.cf(), &key)?; + let old = self.db.rocks.get_cf_opt(&self.cf(), &key, &readoptions)?; let new = utils::increment(old.as_deref()).unwrap(); - self.db.rocks.put_cf(&self.cf(), key, new)?; + self.db + .rocks + .put_cf_opt(&self.cf(), key, new, &writeoptions)?; } drop(lock); @@ -235,11 +253,14 @@ impl KvTree for RocksDbEngineTree<'_> { &'a self, prefix: Vec, ) -> Box, Vec)> + 'a> { + let readoptions = rocksdb::ReadOptions::default(); + Box::new( self.db .rocks - .iterator_cf( + .iterator_cf_opt( &self.cf(), + readoptions, rocksdb::IteratorMode::From(&prefix, rocksdb::Direction::Forward), ) .map(|r| r.unwrap()) From 68a33862b3a0298f3e478d94a0255bd95cb54326 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 21 Mar 2024 15:40:10 -0700 Subject: [PATCH 108/129] add mdbook to the devshell --- flake.nix | 3 +++ 1 file changed, 3 insertions(+) diff --git a/flake.nix b/flake.nix index 9cd826b8..fdaa0b67 100644 --- a/flake.nix +++ b/flake.nix @@ -307,6 +307,9 @@ # Needed for finding broken markdown links lychee + + # Useful for editing the book locally + mdbook ]); }; }); From 0a790686c57c087103ccbbaf9096d0eba6a2d753 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 21 Mar 2024 15:31:57 -0700 Subject: [PATCH 109/129] avoid duplicating links in documentation Because one might forget to update them. I did, initially, which is why I'm making this change. --- docs/deploying.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docs/deploying.md b/docs/deploying.md index 3694f6b2..4c4b154a 100644 --- a/docs/deploying.md +++ b/docs/deploying.md @@ -1,8 +1,3 @@ # Deployment options -There are several ways to deploy a Conduit server. - -- [Simple (Recommended)](deploying/simple.md) - This is the recommended way to set up Conduit. -- [Debian](deploying/debian.md) - If you're using a debian-based system, you may find the `deb` package useful. -- [Docker](deploying/docker.md) - We provide multi-arch OCI images for Conduit. -- [Nix](deploying/nix.md) - Nix flake based setup. +This chapter describes various ways to deploy Conduit. From 2022efd2792034ab45a9e27db514744876009c93 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 21 Mar 2024 15:36:08 -0700 Subject: [PATCH 110/129] remove section about cross compilation It is very stale. Please just use Nix. Trying to do it outside of Nix will be an exercise in frustration, I guarantee it. --- docs/deploying/simple.md | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/docs/deploying/simple.md b/docs/deploying/simple.md index ea12a281..ef5c15d1 100644 --- a/docs/deploying/simple.md +++ b/docs/deploying/simple.md @@ -61,26 +61,6 @@ Then, `cd` into the source tree of conduit-next and run: $ cargo build --release ``` -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 While Conduit can run as any user it is usually better to use dedicated users for different services. This also allows From f56abba21651f64bf1b4f970ad0ca97c807256e8 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 21 Mar 2024 15:22:53 -0700 Subject: [PATCH 111/129] rename "simple" deployment to "generic" The main thing this section is really useful for is explaining how to configure various reverse proxies, which applies to basically anything. Also, remove all the language about this being "recommended", because nothing in this documentation is actually tested in CI. --- docs/SUMMARY.md | 2 +- docs/deploying/docker.md | 2 +- docs/deploying/{simple.md => generic.md} | 4 +--- 3 files changed, 3 insertions(+), 5 deletions(-) rename docs/deploying/{simple.md => generic.md} (98%) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index e7ed05d7..342d6957 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -4,7 +4,7 @@ - [Example configuration](configuration.md) - [Deployment options](deploying.md) - - [Simple (Recommended)](deploying/simple.md) + - [Generic](deploying/generic.md) - [Debian](deploying/debian.md) - [Docker](deploying/docker.md) - [Nix](deploying/nix.md) diff --git a/docs/deploying/docker.md b/docs/deploying/docker.md index 4a38b30b..20cd15f2 100644 --- a/docs/deploying/docker.md +++ b/docs/deploying/docker.md @@ -87,7 +87,7 @@ Depending on your proxy setup, you can use one of the following files; When picking the traefik-related compose file, rename it so it matches `docker-compose.yml`, and rename the override file to `docker-compose.override.yml`. Edit the latter with the values you want for your server. -Additional info about deploying Conduit can be found [here](simple.md). +Additional info about deploying Conduit can be found [here](generic.md). ### Build diff --git a/docs/deploying/simple.md b/docs/deploying/generic.md similarity index 98% rename from docs/deploying/simple.md rename to docs/deploying/generic.md index ef5c15d1..307de359 100644 --- a/docs/deploying/simple.md +++ b/docs/deploying/generic.md @@ -1,6 +1,4 @@ -# Simple setup - -This is the recommended way to set up Conduit. It is the easiest way to get started and is suitable for most use cases. +# Generic deployment documentation > ## Getting help > From f6bfba70146ea01ad00c526a022e6cad1c057e6c Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 21 Mar 2024 15:28:19 -0700 Subject: [PATCH 112/129] normalize headers to "Conduit for X" --- docs/deploying/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deploying/docker.md b/docs/deploying/docker.md index 20cd15f2..c19ef51b 100644 --- a/docs/deploying/docker.md +++ b/docs/deploying/docker.md @@ -1,4 +1,4 @@ -# Deploy using Docker +# Conduit for Docker > **Note:** To run and use Conduit you should probably use it with a Domain or Subdomain behind a reverse proxy (like Nginx, Traefik, Apache, ...) with a Lets Encrypt certificate. From 3dd21456efe8c38aed4206f05042eddba1cbbc94 Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 21 Mar 2024 15:25:34 -0700 Subject: [PATCH 113/129] reduce scope of nixos documentation There are so many ways to do this we realistically shouldn't bother describing any of them, especially because people should be learning all the options and choosing the one that suits them best anyway. --- docs/SUMMARY.md | 2 +- docs/deploying/nix.md | 198 ---------------------------------------- docs/deploying/nixos.md | 18 ++++ 3 files changed, 19 insertions(+), 199 deletions(-) delete mode 100644 docs/deploying/nix.md create mode 100644 docs/deploying/nixos.md diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 342d6957..89f620ea 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -7,6 +7,6 @@ - [Generic](deploying/generic.md) - [Debian](deploying/debian.md) - [Docker](deploying/docker.md) - - [Nix](deploying/nix.md) + - [NixOS](deploying/nixos.md) - [TURN](turn.md) - [Appservices](appservices.md) diff --git a/docs/deploying/nix.md b/docs/deploying/nix.md deleted file mode 100644 index bd6f0962..00000000 --- a/docs/deploying/nix.md +++ /dev/null @@ -1,198 +0,0 @@ -# Conduit for Nix/NixOS - -This guide assumes you have a recent version of Nix (^2.4) installed. - -Since Conduit ships as a Nix flake, you'll first need to [enable -flakes][enable_flakes]. - -You can now use the usual Nix commands to interact with Conduit's flake. For -example, `nix run gitlab:famedly/conduit` will run Conduit (though you'll need -to provide configuration and such manually as usual). - -If your NixOS configuration is defined as a flake, you can depend on this flake -to provide a more up-to-date version than provided by `nixpkgs`. In your flake, -add the following to your `inputs`: - -```nix -conduit = { - url = "gitlab:famedly/conduit"; - - # Assuming you have an input for nixpkgs called `nixpkgs`. If you experience - # build failures while using this, try commenting/deleting this line. This - # will probably also require you to always build from source. - inputs.nixpkgs.follows = "nixpkgs"; -}; -``` - -Next, make sure you're passing your flake inputs to the `specialArgs` argument -of `nixpkgs.lib.nixosSystem` [as explained here][specialargs]. This guide will -assume you've named the group `flake-inputs`. - -Now you can configure Conduit and a reverse proxy for it. Add the following to -a new Nix file and include it in your configuration: - -```nix -{ config -, pkgs -, flake-inputs -, ... -}: - -let - # You'll need to edit these values - - # The hostname that will appear in your user and room IDs - server_name = "example.com"; - - # The hostname that Conduit actually runs on - # - # This can be the same as `server_name` if you want. This is only necessary - # when Conduit is running on a different machine than the one hosting your - # root domain. This configuration also assumes this is all running on a single - # machine, some tweaks will need to be made if this is not the case. - matrix_hostname = "matrix.${server_name}"; - - # An admin email for TLS certificate notifications - admin_email = "admin@${server_name}"; - - # These ones you can leave alone - - # Build a dervation that stores the content of `${server_name}/.well-known/matrix/server` - well_known_server = pkgs.writeText "well-known-matrix-server" '' - { - "m.server": "${matrix_hostname}" - } - ''; - - # Build a dervation that stores the content of `${server_name}/.well-known/matrix/client` - well_known_client = pkgs.writeText "well-known-matrix-client" '' - { - "m.homeserver": { - "base_url": "https://${matrix_hostname}" - } - } - ''; -in - -{ - # Configure Conduit itself - services.matrix-conduit = { - enable = true; - - # This causes NixOS to use the flake defined in this repository instead of - # the build of Conduit built into nixpkgs. - package = flake-inputs.conduit.packages.${pkgs.system}.default; - - settings.global = { - inherit server_name; - }; - }; - - # Configure automated TLS acquisition/renewal - security.acme = { - acceptTerms = true; - defaults = { - email = admin_email; - }; - }; - - # ACME data must be readable by the NGINX user - users.users.nginx.extraGroups = [ - "acme" - ]; - - # Configure NGINX as a reverse proxy - services.nginx = { - enable = true; - recommendedProxySettings = true; - - virtualHosts = { - "${matrix_hostname}" = { - forceSSL = true; - enableACME = true; - - listen = [ - { - addr = "0.0.0.0"; - port = 443; - ssl = true; - } - { - addr = "[::]"; - port = 443; - ssl = true; - } { - addr = "0.0.0.0"; - port = 8448; - ssl = true; - } - { - addr = "[::]"; - port = 8448; - ssl = true; - } - ]; - - locations."/_matrix/" = { - proxyPass = "http://backend_conduit$request_uri"; - proxyWebsockets = true; - extraConfig = '' - proxy_set_header Host $host; - proxy_buffering off; - ''; - }; - - 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}"; - - extraConfig = '' - # Set the header since by default NGINX thinks it's just bytes - default_type application/json; - ''; - }; - - locations."=/.well-known/matrix/client" = { - # Use the contents of the derivation built previously - alias = "${well_known_client}"; - - extraConfig = '' - # Set the header since by default NGINX thinks it's just bytes - default_type application/json; - - # https://matrix.org/docs/spec/client_server/r0.4.0#web-browser-clients - add_header Access-Control-Allow-Origin "*"; - ''; - }; - }; - }; - - upstreams = { - "backend_conduit" = { - servers = { - "[::1]:${toString config.services.matrix-conduit.settings.global.port}" = { }; - }; - }; - }; - }; - - # Open firewall ports for HTTP, HTTPS, and Matrix federation - networking.firewall.allowedTCPPorts = [ 80 443 8448 ]; - networking.firewall.allowedUDPPorts = [ 80 443 8448 ]; -} -``` - -Now you can rebuild your system configuration and you should be good to go! - -[enable_flakes]: https://nixos.wiki/wiki/Flakes#Enable_flakes - -[specialargs]: https://nixos.wiki/wiki/Flakes#Using_nix_flakes_with_NixOS diff --git a/docs/deploying/nixos.md b/docs/deploying/nixos.md new file mode 100644 index 00000000..bf9b1a11 --- /dev/null +++ b/docs/deploying/nixos.md @@ -0,0 +1,18 @@ +# Conduit for NixOS + +Conduit can be acquired by Nix from various places: + +* The `flake.nix` at the root of the repo +* The `default.nix` at the root of the repo +* From Nixpkgs + +The `flake.nix` and `default.nix` do not (currently) provide a NixOS module, so +(for now) [`services.matrix-conduit`][module] from Nixpkgs should be used to +configure Conduit. + +If you want to run the latest code, you should get Conduit from the `flake.nix` +or `default.nix` and set [`services.matrix-conduit.package`][package] +appropriately. + +[module]: https://search.nixos.org/options?channel=unstable&query=services.matrix-conduit +[package]: https://search.nixos.org/options?channel=unstable&query=services.matrix-conduit.package From 5a4ee9808abeee0eedb932e4c02568d192ebdfca Mon Sep 17 00:00:00 2001 From: Charles Hall Date: Thu, 21 Mar 2024 15:42:36 -0700 Subject: [PATCH 114/129] make chapter name reflect file name Personally I think this makes more sense anyway. --- docs/SUMMARY.md | 2 +- docs/deploying.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 89f620ea..30316e27 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -3,7 +3,7 @@ - [Introduction](introduction.md) - [Example configuration](configuration.md) -- [Deployment options](deploying.md) +- [Deploying](deploying.md) - [Generic](deploying/generic.md) - [Debian](deploying/debian.md) - [Docker](deploying/docker.md) diff --git a/docs/deploying.md b/docs/deploying.md index 4c4b154a..136e6538 100644 --- a/docs/deploying.md +++ b/docs/deploying.md @@ -1,3 +1,3 @@ -# Deployment options +# Deploying This chapter describes various ways to deploy Conduit. From 6bd7ff4917978856613c464f813fff8cf2b7e6a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Tue, 5 Mar 2024 23:48:36 +0100 Subject: [PATCH 115/129] improvement: do not save typing edus in db --- src/api/client_server/sync.rs | 4 +- src/api/client_server/typing.rs | 4 +- src/api/server_server.rs | 4 +- src/service/mod.rs | 3 +- src/service/rooms/edus/typing/mod.rs | 57 ++++++++++++++++++++-------- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 103daeb0..ba2ceefa 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1055,10 +1055,10 @@ async fn load_joined_room( .map(|(_, _, v)| v) .collect(); - if services().rooms.edus.typing.last_typing_update(room_id)? > since { + if services().rooms.edus.typing.last_typing_update(room_id).await? > since { edus.push( serde_json::from_str( - &serde_json::to_string(&services().rooms.edus.typing.typings_all(room_id)?) + &serde_json::to_string(&services().rooms.edus.typing.typings_all(room_id).await?) .expect("event is valid, we just created it"), ) .expect("event is valid, we just created it"), diff --git a/src/api/client_server/typing.rs b/src/api/client_server/typing.rs index 43217e1a..eff84051 100644 --- a/src/api/client_server/typing.rs +++ b/src/api/client_server/typing.rs @@ -27,13 +27,13 @@ pub async fn create_typing_event_route( sender_user, &body.room_id, duration.as_millis() as u64 + utils::millis_since_unix_epoch(), - )?; + ).await?; } else { services() .rooms .edus .typing - .typing_remove(sender_user, &body.room_id)?; + .typing_remove(sender_user, &body.room_id).await?; } Ok(create_typing_event::v3::Response {}) diff --git a/src/api/server_server.rs b/src/api/server_server.rs index e0335493..59724b03 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -830,13 +830,13 @@ pub async fn send_transaction_message_route( &typing.user_id, &typing.room_id, 3000 + utils::millis_since_unix_epoch(), - )?; + ).await?; } else { services() .rooms .edus .typing - .typing_remove(&typing.user_id, &typing.room_id)?; + .typing_remove(&typing.user_id, &typing.room_id).await?; } } } diff --git a/src/service/mod.rs b/src/service/mod.rs index 8f9fb0a5..8c97cdd0 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -7,6 +7,7 @@ use lru_cache::LruCache; use tokio::sync::Mutex; use crate::{Config, Result}; +use tokio::sync::RwLock; pub mod account_data; pub mod admin; @@ -65,7 +66,7 @@ impl Services { edus: rooms::edus::Service { presence: rooms::edus::presence::Service { db }, read_receipt: rooms::edus::read_receipt::Service { db }, - typing: rooms::edus::typing::Service { db }, + typing: rooms::edus::typing::Service { db, typing: RwLock::new(BTreeMap::new()), last_typing_update: RwLock::new(BTreeMap::new()) }, }, event_handler: rooms::event_handler::Service, lazy_loading: rooms::lazy_loading::Service { diff --git a/src/service/rooms/edus/typing/mod.rs b/src/service/rooms/edus/typing/mod.rs index 7d44f7d7..f3436741 100644 --- a/src/service/rooms/edus/typing/mod.rs +++ b/src/service/rooms/edus/typing/mod.rs @@ -1,48 +1,73 @@ mod data; pub use data::Data; -use ruma::{events::SyncEphemeralRoomEvent, RoomId, UserId}; +use ruma::{events::SyncEphemeralRoomEvent, RoomId, UserId, OwnedRoomId, OwnedUserId}; +use tokio::sync::RwLock; +use std::collections::BTreeMap; -use crate::Result; +use crate::{utils, services, Result}; pub struct Service { pub db: &'static dyn Data, + pub typing: RwLock>>, // u64 is unix timestamp of timeout + pub last_typing_update: RwLock>, // timestamp of the last change to typing users } impl Service { /// Sets a user as typing until the timeout timestamp is reached or roomtyping_remove is /// called. - pub fn typing_add(&self, user_id: &UserId, room_id: &RoomId, timeout: u64) -> Result<()> { - self.db.typing_add(user_id, room_id, timeout) + pub async fn typing_add(&self, user_id: &UserId, room_id: &RoomId, timeout: u64) -> Result<()> { + self.typing.write().await.entry(room_id.to_owned()).or_default().insert(user_id.to_owned(), timeout); + self.last_typing_update.write().await.insert(room_id.to_owned(), services().globals.next_count()?); + Ok(()) } /// Removes a user from typing before the timeout is reached. - pub fn typing_remove(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> { - self.db.typing_remove(user_id, room_id) + pub async fn typing_remove(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> { + self.typing.write().await.entry(room_id.to_owned()).or_default().remove(user_id); + self.last_typing_update.write().await.insert(room_id.to_owned(), services().globals.next_count()?); + Ok(()) } /// Makes sure that typing events with old timestamps get removed. - fn typings_maintain(&self, room_id: &RoomId) -> Result<()> { - self.db.typings_maintain(room_id) + async fn typings_maintain(&self, room_id: &RoomId) -> Result<()> { + let current_timestamp = utils::millis_since_unix_epoch(); + let mut removable = Vec::new(); + { + let typing = self.typing.read().await; + let Some(room) = typing.get(room_id) else { return Ok(()); }; + for (user, timeout) in room { + if *timeout < current_timestamp { + removable.push(user.clone()); + } + } + drop(typing); + } + if !removable.is_empty() { + let typing = &mut self.typing.write().await; + let room = typing.entry(room_id.to_owned()).or_default(); + for user in removable { + room.remove(&user); + } + self.last_typing_update.write().await.insert(room_id.to_owned(), services().globals.next_count()?); + } + Ok(()) } /// 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) + pub async fn last_typing_update(&self, room_id: &RoomId) -> Result { + self.typings_maintain(room_id).await?; + Ok(self.last_typing_update.read().await.get(room_id).copied().unwrap_or(0)) } /// Returns a new typing EDU. - pub fn typings_all( + pub async fn typings_all( &self, room_id: &RoomId, ) -> Result> { - let user_ids = self.db.typings_all(room_id)?; - Ok(SyncEphemeralRoomEvent { content: ruma::events::typing::TypingEventContent { - user_ids: user_ids.into_iter().collect(), + user_ids: self.typing.read().await.get(room_id).map(|m| m.keys().cloned().collect()).unwrap_or_default(), }, }) } From d2817679e59494a7944e1141e65dc236bcf7b061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Fri, 22 Mar 2024 08:22:15 +0100 Subject: [PATCH 116/129] refactor: remove previous typing implementation and add sync wakeup for new one --- src/api/client_server/sync.rs | 9 +- src/api/client_server/typing.rs | 18 ++- src/api/server_server.rs | 18 ++- src/database/key_value/globals.rs | 4 +- src/database/key_value/rooms/edus/mod.rs | 1 - src/database/key_value/rooms/edus/typing.rs | 127 -------------------- src/database/mod.rs | 4 - src/service/mod.rs | 8 +- src/service/rooms/edus/mod.rs | 2 +- src/service/rooms/edus/typing/data.rs | 21 ---- src/service/rooms/edus/typing/mod.rs | 74 +++++++++--- 11 files changed, 101 insertions(+), 185 deletions(-) delete mode 100644 src/database/key_value/rooms/edus/typing.rs delete mode 100644 src/service/rooms/edus/typing/data.rs diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index ba2ceefa..da603dcf 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -1055,7 +1055,14 @@ async fn load_joined_room( .map(|(_, _, v)| v) .collect(); - if services().rooms.edus.typing.last_typing_update(room_id).await? > since { + if services() + .rooms + .edus + .typing + .last_typing_update(room_id) + .await? + > since + { edus.push( serde_json::from_str( &serde_json::to_string(&services().rooms.edus.typing.typings_all(room_id).await?) diff --git a/src/api/client_server/typing.rs b/src/api/client_server/typing.rs index eff84051..e9e93708 100644 --- a/src/api/client_server/typing.rs +++ b/src/api/client_server/typing.rs @@ -23,17 +23,23 @@ pub async fn create_typing_event_route( } if let Typing::Yes(duration) = body.state { - services().rooms.edus.typing.typing_add( - sender_user, - &body.room_id, - duration.as_millis() as u64 + utils::millis_since_unix_epoch(), - ).await?; + services() + .rooms + .edus + .typing + .typing_add( + sender_user, + &body.room_id, + duration.as_millis() as u64 + utils::millis_since_unix_epoch(), + ) + .await?; } else { services() .rooms .edus .typing - .typing_remove(sender_user, &body.room_id).await?; + .typing_remove(sender_user, &body.room_id) + .await?; } Ok(create_typing_event::v3::Response {}) diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 59724b03..0fdf22fc 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -826,17 +826,23 @@ pub async fn send_transaction_message_route( .is_joined(&typing.user_id, &typing.room_id)? { if typing.typing { - services().rooms.edus.typing.typing_add( - &typing.user_id, - &typing.room_id, - 3000 + utils::millis_since_unix_epoch(), - ).await?; + services() + .rooms + .edus + .typing + .typing_add( + &typing.user_id, + &typing.room_id, + 3000 + utils::millis_since_unix_epoch(), + ) + .await?; } else { services() .rooms .edus .typing - .typing_remove(&typing.user_id, &typing.room_id).await?; + .typing_remove(&typing.user_id, &typing.room_id) + .await?; } } } diff --git a/src/database/key_value/globals.rs b/src/database/key_value/globals.rs index 7a70af18..2851ce53 100644 --- a/src/database/key_value/globals.rs +++ b/src/database/key_value/globals.rs @@ -94,7 +94,9 @@ impl service::globals::Data for KeyValueDatabase { futures.push(self.pduid_pdu.watch_prefix(&short_roomid)); // EDUs - futures.push(self.roomid_lasttypingupdate.watch_prefix(&roomid_bytes)); + futures.push(Box::into_pin(Box::new(async move { + let _result = services().rooms.edus.typing.wait_for_update(&room_id).await; + }))); futures.push(self.readreceiptid_readreceipt.watch_prefix(&roomid_prefix)); diff --git a/src/database/key_value/rooms/edus/mod.rs b/src/database/key_value/rooms/edus/mod.rs index 6c652918..7abf946f 100644 --- a/src/database/key_value/rooms/edus/mod.rs +++ b/src/database/key_value/rooms/edus/mod.rs @@ -1,6 +1,5 @@ mod presence; mod read_receipt; -mod typing; use crate::{database::KeyValueDatabase, service}; diff --git a/src/database/key_value/rooms/edus/typing.rs b/src/database/key_value/rooms/edus/typing.rs deleted file mode 100644 index 5709192c..00000000 --- a/src/database/key_value/rooms/edus/typing.rs +++ /dev/null @@ -1,127 +0,0 @@ -use std::{collections::HashSet, mem}; - -use ruma::{OwnedUserId, RoomId, UserId}; - -use crate::{database::KeyValueDatabase, service, services, utils, Error, Result}; - -impl service::rooms::edus::typing::Data for KeyValueDatabase { - fn typing_add(&self, user_id: &UserId, room_id: &RoomId, timeout: u64) -> Result<()> { - let mut prefix = room_id.as_bytes().to_vec(); - prefix.push(0xff); - - let count = services().globals.next_count()?.to_be_bytes(); - - let mut room_typing_id = prefix; - room_typing_id.extend_from_slice(&timeout.to_be_bytes()); - room_typing_id.push(0xff); - room_typing_id.extend_from_slice(&count); - - self.typingid_userid - .insert(&room_typing_id, user_id.as_bytes())?; - - self.roomid_lasttypingupdate - .insert(room_id.as_bytes(), &count)?; - - Ok(()) - } - - fn typing_remove(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> { - let mut prefix = room_id.as_bytes().to_vec(); - prefix.push(0xff); - - let user_id = user_id.to_string(); - - let mut found_outdated = false; - - // Maybe there are multiple ones from calling roomtyping_add multiple times - for outdated_edu in self - .typingid_userid - .scan_prefix(prefix) - .filter(|(_, v)| &**v == user_id.as_bytes()) - { - 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 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 - .get(room_id.as_bytes())? - .map(|bytes| { - utils::u64_from_bytes(&bytes).map_err(|_| { - Error::bad_database("Count in roomid_lastroomactiveupdate is invalid.") - }) - }) - .transpose()? - .unwrap_or(0)) - } - - fn typings_all(&self, room_id: &RoomId) -> Result> { - let mut prefix = room_id.as_bytes().to_vec(); - prefix.push(0xff); - - let mut user_ids = HashSet::new(); - - for (_, user_id) in self.typingid_userid.scan_prefix(prefix) { - let user_id = UserId::parse(utils::string_from_bytes(&user_id).map_err(|_| { - Error::bad_database("User ID in typingid_userid is invalid unicode.") - })?) - .map_err(|_| Error::bad_database("User ID in typingid_userid is invalid."))?; - - user_ids.insert(user_id); - } - - Ok(user_ids) - } -} diff --git a/src/database/mod.rs b/src/database/mod.rs index 425ef4e9..0960dc96 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -70,8 +70,6 @@ pub struct KeyValueDatabase { pub(super) readreceiptid_readreceipt: Arc, // ReadReceiptId = RoomId + Count + UserId pub(super) roomuserid_privateread: Arc, // RoomUserId = Room + User, PrivateRead = Count pub(super) roomuserid_lastprivatereadupdate: Arc, // LastPrivateReadUpdate = Count - pub(super) typingid_userid: Arc, // TypingId = RoomId + TimeoutTime + Count - pub(super) roomid_lasttypingupdate: Arc, // LastRoomTypingUpdate = Count pub(super) presenceid_presence: Arc, // PresenceId = RoomId + Count + UserId pub(super) userid_lastpresenceupdate: Arc, // LastPresenceUpdate = Count @@ -301,8 +299,6 @@ impl KeyValueDatabase { roomuserid_privateread: builder.open_tree("roomuserid_privateread")?, // "Private" read receipt roomuserid_lastprivatereadupdate: builder .open_tree("roomuserid_lastprivatereadupdate")?, - typingid_userid: builder.open_tree("typingid_userid")?, - roomid_lasttypingupdate: builder.open_tree("roomid_lasttypingupdate")?, presenceid_presence: builder.open_tree("presenceid_presence")?, userid_lastpresenceupdate: builder.open_tree("userid_lastpresenceupdate")?, pduid_pdu: builder.open_tree("pduid_pdu")?, diff --git a/src/service/mod.rs b/src/service/mod.rs index 8c97cdd0..ba1ae1c8 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -4,7 +4,7 @@ use std::{ }; use lru_cache::LruCache; -use tokio::sync::Mutex; +use tokio::sync::{broadcast, Mutex}; use crate::{Config, Result}; use tokio::sync::RwLock; @@ -66,7 +66,11 @@ impl Services { edus: rooms::edus::Service { presence: rooms::edus::presence::Service { db }, read_receipt: rooms::edus::read_receipt::Service { db }, - typing: rooms::edus::typing::Service { db, typing: RwLock::new(BTreeMap::new()), last_typing_update: RwLock::new(BTreeMap::new()) }, + typing: rooms::edus::typing::Service { + typing: RwLock::new(BTreeMap::new()), + last_typing_update: RwLock::new(BTreeMap::new()), + typing_update_sender: broadcast::channel(100).0, + }, }, event_handler: rooms::event_handler::Service, lazy_loading: rooms::lazy_loading::Service { diff --git a/src/service/rooms/edus/mod.rs b/src/service/rooms/edus/mod.rs index cf7a3591..a6bc3d5b 100644 --- a/src/service/rooms/edus/mod.rs +++ b/src/service/rooms/edus/mod.rs @@ -2,7 +2,7 @@ pub mod presence; pub mod read_receipt; pub mod typing; -pub trait Data: presence::Data + read_receipt::Data + typing::Data + 'static {} +pub trait Data: presence::Data + read_receipt::Data + 'static {} pub struct Service { pub presence: presence::Service, diff --git a/src/service/rooms/edus/typing/data.rs b/src/service/rooms/edus/typing/data.rs deleted file mode 100644 index 3b1eecfb..00000000 --- a/src/service/rooms/edus/typing/data.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::Result; -use ruma::{OwnedUserId, RoomId, UserId}; -use std::collections::HashSet; - -pub trait Data: Send + Sync { - /// Sets a user as typing until the timeout timestamp is reached or roomtyping_remove is - /// called. - fn typing_add(&self, user_id: &UserId, room_id: &RoomId, timeout: u64) -> Result<()>; - - /// 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; - - /// Returns all user ids currently typing. - fn typings_all(&self, room_id: &RoomId) -> Result>; -} diff --git a/src/service/rooms/edus/typing/mod.rs b/src/service/rooms/edus/typing/mod.rs index f3436741..7546aa84 100644 --- a/src/service/rooms/edus/typing/mod.rs +++ b/src/service/rooms/edus/typing/mod.rs @@ -1,31 +1,57 @@ -mod data; - -pub use data::Data; -use ruma::{events::SyncEphemeralRoomEvent, RoomId, UserId, OwnedRoomId, OwnedUserId}; -use tokio::sync::RwLock; +use ruma::{events::SyncEphemeralRoomEvent, OwnedRoomId, OwnedUserId, RoomId, UserId}; use std::collections::BTreeMap; +use tokio::sync::{broadcast, RwLock}; -use crate::{utils, services, Result}; +use crate::{services, utils, Result}; pub struct Service { - pub db: &'static dyn Data, pub typing: RwLock>>, // u64 is unix timestamp of timeout pub last_typing_update: RwLock>, // timestamp of the last change to typing users + pub typing_update_sender: broadcast::Sender, } impl Service { /// Sets a user as typing until the timeout timestamp is reached or roomtyping_remove is /// called. pub async fn typing_add(&self, user_id: &UserId, room_id: &RoomId, timeout: u64) -> Result<()> { - self.typing.write().await.entry(room_id.to_owned()).or_default().insert(user_id.to_owned(), timeout); - self.last_typing_update.write().await.insert(room_id.to_owned(), services().globals.next_count()?); + self.typing + .write() + .await + .entry(room_id.to_owned()) + .or_default() + .insert(user_id.to_owned(), timeout); + self.last_typing_update + .write() + .await + .insert(room_id.to_owned(), services().globals.next_count()?); + let _ = self.typing_update_sender.send(room_id.to_owned()); Ok(()) } /// Removes a user from typing before the timeout is reached. pub async fn typing_remove(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> { - self.typing.write().await.entry(room_id.to_owned()).or_default().remove(user_id); - self.last_typing_update.write().await.insert(room_id.to_owned(), services().globals.next_count()?); + self.typing + .write() + .await + .entry(room_id.to_owned()) + .or_default() + .remove(user_id); + self.last_typing_update + .write() + .await + .insert(room_id.to_owned(), services().globals.next_count()?); + let _ = self.typing_update_sender.send(room_id.to_owned()); + Ok(()) + } + + pub async fn wait_for_update(&self, room_id: &RoomId) -> Result<()> { + let mut receiver = self.typing_update_sender.subscribe(); + while let Ok(next) = receiver.recv().await { + if next == room_id { + break; + } + } + Ok(()) } @@ -35,7 +61,9 @@ impl Service { let mut removable = Vec::new(); { let typing = self.typing.read().await; - let Some(room) = typing.get(room_id) else { return Ok(()); }; + let Some(room) = typing.get(room_id) else { + return Ok(()); + }; for (user, timeout) in room { if *timeout < current_timestamp { removable.push(user.clone()); @@ -49,7 +77,11 @@ impl Service { for user in removable { room.remove(&user); } - self.last_typing_update.write().await.insert(room_id.to_owned(), services().globals.next_count()?); + self.last_typing_update + .write() + .await + .insert(room_id.to_owned(), services().globals.next_count()?); + let _ = self.typing_update_sender.send(room_id.to_owned()); } Ok(()) } @@ -57,7 +89,13 @@ impl Service { /// Returns the count of the last typing update in this room. pub async fn last_typing_update(&self, room_id: &RoomId) -> Result { self.typings_maintain(room_id).await?; - Ok(self.last_typing_update.read().await.get(room_id).copied().unwrap_or(0)) + Ok(self + .last_typing_update + .read() + .await + .get(room_id) + .copied() + .unwrap_or(0)) } /// Returns a new typing EDU. @@ -67,7 +105,13 @@ impl Service { ) -> Result> { Ok(SyncEphemeralRoomEvent { content: ruma::events::typing::TypingEventContent { - user_ids: self.typing.read().await.get(room_id).map(|m| m.keys().cloned().collect()).unwrap_or_default(), + user_ids: self + .typing + .read() + .await + .get(room_id) + .map(|m| m.keys().cloned().collect()) + .unwrap_or_default(), }, }) } From 0bb28f60cfc68beaa521bb7dacdec7a9f92c2288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Fri, 22 Mar 2024 08:52:39 +0100 Subject: [PATCH 117/129] refactor: minor appservice code cleanup --- src/api/appservice_server.rs | 157 ++++++++++++++------------- src/api/client_server/alias.rs | 8 +- src/api/ruma_wrapper/axum.rs | 8 +- src/database/key_value/appservice.rs | 35 ++---- src/database/mod.rs | 19 ---- src/service/appservice/mod.rs | 39 +++++-- src/service/mod.rs | 7 +- src/service/rooms/timeline/mod.rs | 10 +- 8 files changed, 128 insertions(+), 155 deletions(-) diff --git a/src/api/appservice_server.rs b/src/api/appservice_server.rs index ab4da79f..841c32a1 100644 --- a/src/api/appservice_server.rs +++ b/src/api/appservice_server.rs @@ -17,95 +17,96 @@ pub(crate) async fn send_request( where T: Debug, { - if let Some(destination) = registration.url { - let hs_token = registration.hs_token.as_str(); + let Some(destination) = registration.url else { + return None; + }; - let mut http_request = request - .try_into_http_request::( - &destination, - SendAccessToken::IfRequired(hs_token), - &[MatrixVersion::V1_0], - ) - .unwrap() - .map(|body| body.freeze()); + let hs_token = registration.hs_token.as_str(); - let mut parts = http_request.uri().clone().into_parts(); - let old_path_and_query = parts.path_and_query.unwrap().as_str().to_owned(); - let symbol = if old_path_and_query.contains('?') { - "&" - } else { - "?" - }; + let mut http_request = request + .try_into_http_request::( + &destination, + SendAccessToken::IfRequired(hs_token), + &[MatrixVersion::V1_0], + ) + .unwrap() + .map(|body| body.freeze()); - parts.path_and_query = Some( - (old_path_and_query + symbol + "access_token=" + hs_token) - .parse() - .unwrap(), - ); - *http_request.uri_mut() = parts.try_into().expect("our manipulation is always valid"); - - let mut reqwest_request = reqwest::Request::try_from(http_request) - .expect("all http requests are valid reqwest requests"); + let mut parts = http_request.uri().clone().into_parts(); + let old_path_and_query = parts.path_and_query.unwrap().as_str().to_owned(); + let symbol = if old_path_and_query.contains('?') { + "&" + } else { + "?" + }; - *reqwest_request.timeout_mut() = Some(Duration::from_secs(30)); + parts.path_and_query = Some( + (old_path_and_query + symbol + "access_token=" + hs_token) + .parse() + .unwrap(), + ); + *http_request.uri_mut() = parts.try_into().expect("our manipulation is always valid"); - let url = reqwest_request.url().clone(); - let mut response = match services() - .globals - .default_client() - .execute(reqwest_request) - .await - { - Ok(r) => r, - Err(e) => { - warn!( - "Could not send request to appservice {:?} at {}: {}", - registration.id, destination, e - ); - return Some(Err(e.into())); - } - }; + let mut reqwest_request = reqwest::Request::try_from(http_request) + .expect("all http requests are valid reqwest requests"); - // reqwest::Response -> http::Response conversion - let status = response.status(); - let mut http_response_builder = http::Response::builder() - .status(status) - .version(response.version()); - mem::swap( - response.headers_mut(), - http_response_builder - .headers_mut() - .expect("http::response::Builder is usable"), - ); + *reqwest_request.timeout_mut() = Some(Duration::from_secs(30)); - let body = response.bytes().await.unwrap_or_else(|e| { - warn!("server error: {}", e); - Vec::new().into() - }); // TODO: handle timeout - - if status != 200 { + let url = reqwest_request.url().clone(); + let mut response = match services() + .globals + .default_client() + .execute(reqwest_request) + .await + { + Ok(r) => r, + Err(e) => { warn!( - "Appservice returned bad response {} {}\n{}\n{:?}", - destination, - status, - url, - utils::string_from_bytes(&body) + "Could not send request to appservice {:?} at {}: {}", + registration.id, destination, e ); + return Some(Err(e.into())); } + }; + + // reqwest::Response -> http::Response conversion + let status = response.status(); + let mut http_response_builder = http::Response::builder() + .status(status) + .version(response.version()); + mem::swap( + response.headers_mut(), + http_response_builder + .headers_mut() + .expect("http::response::Builder is usable"), + ); + + let body = response.bytes().await.unwrap_or_else(|e| { + warn!("server error: {}", e); + Vec::new().into() + }); // TODO: handle timeout - let response = T::IncomingResponse::try_from_http_response( - http_response_builder - .body(body) - .expect("reqwest body is valid http body"), + if status != 200 { + warn!( + "Appservice returned bad response {} {}\n{}\n{:?}", + destination, + status, + url, + utils::string_from_bytes(&body) ); - Some(response.map_err(|_| { - warn!( - "Appservice returned invalid response bytes {}\n{}", - destination, url - ); - Error::BadServerResponse("Server returned bad response.") - })) - } else { - None } + + let response = T::IncomingResponse::try_from_http_response( + http_response_builder + .body(body) + .expect("reqwest body is valid http body"), + ); + + Some(response.map_err(|_| { + warn!( + "Appservice returned invalid response bytes {}\n{}", + destination, url + ); + Error::BadServerResponse("Server returned bad response.") + })) } diff --git a/src/api/client_server/alias.rs b/src/api/client_server/alias.rs index d3a6e39a..00ee6c85 100644 --- a/src/api/client_server/alias.rs +++ b/src/api/client_server/alias.rs @@ -100,13 +100,7 @@ pub(crate) async fn get_alias_helper( match services().rooms.alias.resolve_local_alias(&room_alias)? { Some(r) => room_id = Some(r), None => { - for appservice in services() - .appservice - .registration_info - .read() - .await - .values() - { + for appservice in services().appservice.all().await { if appservice.aliases.is_match(room_alias.as_str()) && if let Some(opt_result) = services() .sending diff --git a/src/api/ruma_wrapper/axum.rs b/src/api/ruma_wrapper/axum.rs index e841f13a..6411ab9d 100644 --- a/src/api/ruma_wrapper/axum.rs +++ b/src/api/ruma_wrapper/axum.rs @@ -80,19 +80,19 @@ where let mut json_body = serde_json::from_slice::(&body).ok(); - let appservices = services().appservice.all().unwrap(); + let appservices = services().appservice.all().await; let appservice_registration = appservices .iter() - .find(|(_id, registration)| Some(registration.as_token.as_str()) == token); + .find(|info| Some(info.registration.as_token.as_str()) == token); let (sender_user, sender_device, sender_servername, from_appservice) = - if let Some((_id, registration)) = appservice_registration { + if let Some(info) = appservice_registration { match metadata.authentication { AuthScheme::AccessToken => { let user_id = query_params.user_id.map_or_else( || { UserId::parse_with_server_name( - registration.sender_localpart.as_str(), + info.registration.sender_localpart.as_str(), services().globals.server_name(), ) .unwrap() diff --git a/src/database/key_value/appservice.rs b/src/database/key_value/appservice.rs index 3243183d..b547e66a 100644 --- a/src/database/key_value/appservice.rs +++ b/src/database/key_value/appservice.rs @@ -10,10 +10,6 @@ impl service::appservice::Data for KeyValueDatabase { id.as_bytes(), serde_yaml::to_string(&yaml).unwrap().as_bytes(), )?; - self.cached_registrations - .write() - .unwrap() - .insert(id.to_owned(), yaml.to_owned()); Ok(id.to_owned()) } @@ -26,33 +22,18 @@ impl service::appservice::Data for KeyValueDatabase { fn unregister_appservice(&self, service_name: &str) -> Result<()> { self.id_appserviceregistrations .remove(service_name.as_bytes())?; - self.cached_registrations - .write() - .unwrap() - .remove(service_name); Ok(()) } fn get_registration(&self, id: &str) -> Result> { - self.cached_registrations - .read() - .unwrap() - .get(id) - .map_or_else( - || { - self.id_appserviceregistrations - .get(id.as_bytes())? - .map(|bytes| { - serde_yaml::from_slice(&bytes).map_err(|_| { - Error::bad_database( - "Invalid registration bytes in id_appserviceregistrations.", - ) - }) - }) - .transpose() - }, - |r| Ok(Some(r.clone())), - ) + self.id_appserviceregistrations + .get(id.as_bytes())? + .map(|bytes| { + serde_yaml::from_slice(&bytes).map_err(|_| { + Error::bad_database("Invalid registration bytes in id_appserviceregistrations.") + }) + }) + .transpose() } fn iter_ids<'a>(&'a self) -> Result> + 'a>> { diff --git a/src/database/mod.rs b/src/database/mod.rs index 5b8588cf..190e7e12 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -10,7 +10,6 @@ use directories::ProjectDirs; use lru_cache::LruCache; use ruma::{ - api::appservice::Registration, events::{ push_rules::{PushRulesEvent, PushRulesEventContent}, room::message::RoomMessageEventContent, @@ -164,7 +163,6 @@ pub struct KeyValueDatabase { //pub pusher: pusher::PushData, pub(super) senderkey_pusher: Arc, - pub(super) cached_registrations: Arc>>, pub(super) pdu_cache: Mutex>>, pub(super) shorteventid_cache: Mutex>>, pub(super) auth_chain_cache: Mutex, Arc>>>, @@ -374,7 +372,6 @@ impl KeyValueDatabase { global: builder.open_tree("global")?, server_signingkeys: builder.open_tree("server_signingkeys")?, - cached_registrations: Arc::new(RwLock::new(HashMap::new())), pdu_cache: Mutex::new(LruCache::new( config .pdu_cache_capacity @@ -969,22 +966,6 @@ impl KeyValueDatabase { ); } - // Inserting registrations into cache - for appservice in services().appservice.all()? { - services() - .appservice - .registration_info - .write() - .await - .insert( - appservice.0, - appservice - .1 - .try_into() - .expect("Should be validated on registration"), - ); - } - // This data is probably outdated db.presenceid_presence.clear()?; diff --git a/src/service/appservice/mod.rs b/src/service/appservice/mod.rs index 40fa3ee8..6b9e21f1 100644 --- a/src/service/appservice/mod.rs +++ b/src/service/appservice/mod.rs @@ -10,7 +10,8 @@ use tokio::sync::RwLock; use crate::{services, Result}; -/// Compiled regular expressions for a namespace +/// Compiled regular expressions for a namespace. +#[derive(Clone, Debug)] pub struct NamespaceRegex { pub exclusive: Option, pub non_exclusive: Option, @@ -72,7 +73,8 @@ impl TryFrom> for NamespaceRegex { type Error = regex::Error; } -/// Compiled regular expressions for an appservice +/// Appservice registration combined with its compiled regular expressions. +#[derive(Clone, Debug)] pub struct RegistrationInfo { pub registration: Registration, pub users: NamespaceRegex, @@ -95,11 +97,29 @@ impl TryFrom for RegistrationInfo { pub struct Service { pub db: &'static dyn Data, - pub registration_info: RwLock>, + registration_info: RwLock>, } impl Service { - /// Registers an appservice and returns the ID to the caller + pub fn build(db: &'static dyn Data) -> Result { + let mut registration_info = HashMap::new(); + // Inserting registrations into cache + for appservice in db.all()? { + registration_info.insert( + appservice.0, + appservice + .1 + .try_into() + .expect("Should be validated on registration"), + ); + } + + Ok(Self { + db, + registration_info: RwLock::new(registration_info), + }) + } + /// Registers an appservice and returns the ID to the caller. pub async fn register_appservice(&self, yaml: Registration) -> Result { services() .appservice @@ -111,7 +131,7 @@ impl Service { self.db.register_appservice(yaml) } - /// Remove an appservice registration + /// Removes an appservice registration. /// /// # Arguments /// @@ -135,7 +155,12 @@ impl Service { self.db.iter_ids() } - pub fn all(&self) -> Result> { - self.db.all() + pub async fn all(&self) -> Vec { + self.registration_info + .read() + .await + .values() + .cloned() + .collect() } } diff --git a/src/service/mod.rs b/src/service/mod.rs index 045ccd10..0cbe6a82 100644 --- a/src/service/mod.rs +++ b/src/service/mod.rs @@ -4,7 +4,7 @@ use std::{ }; use lru_cache::LruCache; -use tokio::sync::{Mutex, RwLock}; +use tokio::sync::Mutex; use crate::{Config, Result}; @@ -56,10 +56,7 @@ impl Services { config: Config, ) -> Result { Ok(Self { - appservice: appservice::Service { - db, - registration_info: RwLock::new(HashMap::new()), - }, + appservice: appservice::Service::build(db)?, pusher: pusher::Service { db }, rooms: rooms::Service { alias: rooms::alias::Service { db }, diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 1df1db50..035513d6 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -524,17 +524,11 @@ impl Service { } } - for appservice in services() - .appservice - .registration_info - .read() - .await - .values() - { + for appservice in services().appservice.all().await { if services() .rooms .state_cache - .appservice_in_room(&pdu.room_id, appservice)? + .appservice_in_room(&pdu.room_id, &appservice)? { services() .sending From 5c650bb67e0f21a9080f54fc443695c7da0783af Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Fri, 22 Mar 2024 17:51:15 +0000 Subject: [PATCH 118/129] refactor: use BTreeMap for cached registration info --- src/service/appservice/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/service/appservice/mod.rs b/src/service/appservice/mod.rs index 6b9e21f1..d9ab9eb1 100644 --- a/src/service/appservice/mod.rs +++ b/src/service/appservice/mod.rs @@ -1,6 +1,6 @@ mod data; -use std::collections::HashMap; +use std::collections::BTreeMap; pub use data::Data; @@ -97,12 +97,12 @@ impl TryFrom for RegistrationInfo { pub struct Service { pub db: &'static dyn Data, - registration_info: RwLock>, + registration_info: RwLock>, } impl Service { pub fn build(db: &'static dyn Data) -> Result { - let mut registration_info = HashMap::new(); + let mut registration_info = BTreeMap::new(); // Inserting registrations into cache for appservice in db.all()? { registration_info.insert( From b20483aa13399822fe047349d1af7678f6777259 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Fri, 22 Mar 2024 18:27:14 +0000 Subject: [PATCH 119/129] refactor(appservices): avoid cloning frequently --- src/api/appservice_server.rs | 4 +--- src/api/client_server/alias.rs | 2 +- src/api/ruma_wrapper/axum.rs | 9 +++++---- src/service/admin/mod.rs | 26 +++++++----------------- src/service/appservice/mod.rs | 33 +++++++++++++++++++++++-------- src/service/rooms/timeline/mod.rs | 4 ++-- src/service/sending/mod.rs | 2 +- 7 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/api/appservice_server.rs b/src/api/appservice_server.rs index 841c32a1..213e4c09 100644 --- a/src/api/appservice_server.rs +++ b/src/api/appservice_server.rs @@ -17,9 +17,7 @@ pub(crate) async fn send_request( where T: Debug, { - let Some(destination) = registration.url else { - return None; - }; + let destination = registration.url?; let hs_token = registration.hs_token.as_str(); diff --git a/src/api/client_server/alias.rs b/src/api/client_server/alias.rs index 00ee6c85..bc3a5e25 100644 --- a/src/api/client_server/alias.rs +++ b/src/api/client_server/alias.rs @@ -100,7 +100,7 @@ pub(crate) async fn get_alias_helper( match services().rooms.alias.resolve_local_alias(&room_alias)? { Some(r) => room_id = Some(r), None => { - for appservice in services().appservice.all().await { + for appservice in services().appservice.read().await.values() { if appservice.aliases.is_match(room_alias.as_str()) && if let Some(opt_result) = services() .sending diff --git a/src/api/ruma_wrapper/axum.rs b/src/api/ruma_wrapper/axum.rs index 6411ab9d..8ba9fa52 100644 --- a/src/api/ruma_wrapper/axum.rs +++ b/src/api/ruma_wrapper/axum.rs @@ -80,10 +80,11 @@ where let mut json_body = serde_json::from_slice::(&body).ok(); - let appservices = services().appservice.all().await; - let appservice_registration = appservices - .iter() - .find(|info| Some(info.registration.as_token.as_str()) == token); + let appservice_registration = if let Some(token) = token { + services().appservice.find_from_token(token).await + } else { + None + }; let (sender_user, sender_device, sender_servername, from_appservice) = if let Some(info) = appservice_registration { diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index 12bc1cf6..f2f60a7a 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -369,25 +369,13 @@ impl Service { )), }, AdminCommand::ListAppservices => { - if let Ok(appservices) = services() - .appservice - .iter_ids() - .map(|ids| ids.collect::>()) - { - let count = appservices.len(); - let output = format!( - "Appservices ({}): {}", - count, - appservices - .into_iter() - .filter_map(|r| r.ok()) - .collect::>() - .join(", ") - ); - RoomMessageEventContent::text_plain(output) - } else { - RoomMessageEventContent::text_plain("Failed to get appservices.") - } + let appservices = services().appservice.iter_ids().await; + let output = format!( + "Appservices ({}): {}", + appservices.len(), + appservices.join(", ") + ); + RoomMessageEventContent::text_plain(output) } AdminCommand::ListRooms => { let room_ids = services().rooms.metadata.iter_ids(); diff --git a/src/service/appservice/mod.rs b/src/service/appservice/mod.rs index d9ab9eb1..4bda8961 100644 --- a/src/service/appservice/mod.rs +++ b/src/service/appservice/mod.rs @@ -4,6 +4,7 @@ use std::collections::BTreeMap; pub use data::Data; +use futures_util::Future; use regex::RegexSet; use ruma::api::appservice::{Namespace, Registration}; use tokio::sync::RwLock; @@ -147,20 +148,36 @@ impl Service { self.db.unregister_appservice(service_name) } - pub fn get_registration(&self, id: &str) -> Result> { - self.db.get_registration(id) - } - - pub fn iter_ids(&self) -> Result> + '_> { - self.db.iter_ids() + pub async fn get_registration(&self, id: &str) -> Option { + self.registration_info + .read() + .await + .get(id) + .cloned() + .map(|info| info.registration) } - pub async fn all(&self) -> Vec { + pub async fn iter_ids(&self) -> Vec { self.registration_info .read() .await - .values() + .keys() .cloned() .collect() } + + pub async fn find_from_token(&self, token: &str) -> Option { + self.read() + .await + .values() + .find(|info| info.registration.as_token == token) + .cloned() + } + + pub fn read( + &self, + ) -> impl Future>> + { + self.registration_info.read() + } } diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 035513d6..379d97fe 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -524,11 +524,11 @@ impl Service { } } - for appservice in services().appservice.all().await { + for appservice in services().appservice.read().await.values() { if services() .rooms .state_cache - .appservice_in_room(&pdu.room_id, &appservice)? + .appservice_in_room(&pdu.room_id, appservice)? { services() .sending diff --git a/src/service/sending/mod.rs b/src/service/sending/mod.rs index bbacfdec..45cca173 100644 --- a/src/service/sending/mod.rs +++ b/src/service/sending/mod.rs @@ -488,7 +488,7 @@ impl Service { services() .appservice .get_registration(id) - .map_err(|e| (kind.clone(), e))? + .await .ok_or_else(|| { ( kind.clone(), From 8d70f69e621496796341eacf760918941728f0de Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sat, 30 Mar 2024 12:40:58 +0000 Subject: [PATCH 120/129] fix: reject /register requests when there is no token and the type is appservice --- src/api/client_server/account.rs | 10 +++++++++- src/api/client_server/session.rs | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/api/client_server/account.rs b/src/api/client_server/account.rs index d4529a40..9f98369b 100644 --- a/src/api/client_server/account.rs +++ b/src/api/client_server/account.rs @@ -3,7 +3,8 @@ use crate::{api::client_server, services, utils, Error, Result, Ruma}; use ruma::{ api::client::{ account::{ - change_password, deactivate, get_3pids, get_username_availability, register, + change_password, deactivate, get_3pids, get_username_availability, + register::{self, LoginType}, request_3pid_management_token_via_email, request_3pid_management_token_via_msisdn, whoami, ThirdPartyIdRemovalStatus, }, @@ -84,6 +85,13 @@ pub async fn register_route(body: Ruma) -> Result) -> Result { if !body.from_appservice { return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Forbidden login type.", + ErrorKind::MissingToken, + "Missing appservice token.", )); }; if let Some(UserIdentifier::UserIdOrLocalpart(user_id)) = identifier { From 5c634ceb6b755eaddeb1b854542d9e4a16d763f8 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sat, 30 Mar 2024 11:02:39 +0000 Subject: [PATCH 121/129] fix: reject requests with authentication when not used --- Cargo.lock | 36 ++-- Cargo.toml | 2 +- src/api/ruma_wrapper/axum.rs | 322 +++++++++++++++++++---------------- 3 files changed, 198 insertions(+), 162 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d294c08..bd83f2d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1992,7 +1992,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.9.4" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "assign", "js_int", @@ -2011,7 +2011,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "js_int", "ruma-common", @@ -2023,7 +2023,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.17.4" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "as_variant", "assign", @@ -2042,7 +2042,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.12.1" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "as_variant", "base64", @@ -2061,16 +2061,18 @@ dependencies = [ "serde_html_form", "serde_json", "thiserror", + "time", "tracing", "url", "uuid", + "web-time", "wildmatch", ] [[package]] name = "ruma-events" version = "0.27.11" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "as_variant", "indexmap 2.2.5", @@ -2092,7 +2094,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "js_int", "ruma-common", @@ -2104,7 +2106,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.3" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "js_int", "thiserror", @@ -2113,7 +2115,7 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "js_int", "ruma-common", @@ -2123,7 +2125,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.12.0" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "once_cell", "proc-macro-crate", @@ -2138,7 +2140,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "js_int", "ruma-common", @@ -2150,7 +2152,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.14.0" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "base64", "ed25519-dalek", @@ -2166,7 +2168,7 @@ dependencies = [ [[package]] name = "ruma-state-res" version = "0.10.0" -source = "git+https://github.com/ruma/ruma?rev=1a1c61ee1e8f0936e956a3b69c931ce12ee28475#1a1c61ee1e8f0936e956a3b69c931ce12ee28475" +source = "git+https://github.com/ruma/ruma?rev=5495b85aa311c2805302edb0a7de40399e22b397#5495b85aa311c2805302edb0a7de40399e22b397" dependencies = [ "itertools 0.11.0", "js_int", @@ -3276,6 +3278,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "weezl" version = "0.1.8" diff --git a/Cargo.toml b/Cargo.toml index ac334728..d2b828ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ tower-http = { version = "0.4.1", features = ["add-extension", "cors", "sensitiv # 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 = "1a1c61ee1e8f0936e956a3b69c931ce12ee28475", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "5495b85aa311c2805302edb0a7de40399e22b397", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "4ec9c69bb7e09391add2382b3ebac97b6e8f4c64", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-msc3575", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } diff --git a/src/api/ruma_wrapper/axum.rs b/src/api/ruma_wrapper/axum.rs index a5ef7f7e..43e73c66 100644 --- a/src/api/ruma_wrapper/axum.rs +++ b/src/api/ruma_wrapper/axum.rs @@ -15,13 +15,20 @@ use bytes::{Buf, BufMut, Bytes, BytesMut}; use http::{Request, StatusCode}; use ruma::{ api::{client::error::ErrorKind, AuthScheme, IncomingRequest, OutgoingResponse}, - CanonicalJsonValue, OwnedDeviceId, OwnedServerName, UserId, + CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId, }; use serde::Deserialize; use tracing::{debug, error, warn}; use super::{Ruma, RumaResponse}; -use crate::{services, Error, Result}; +use crate::{service::appservice::RegistrationInfo, services, Error, Result}; + +enum Token { + Appservice(Box), + User((OwnedUserId, OwnedDeviceId)), + Invalid, + None, +} #[async_trait] impl FromRequest for Ruma @@ -78,177 +85,194 @@ where None => query_params.access_token.as_deref(), }; - let mut json_body = serde_json::from_slice::(&body).ok(); - - let appservice_registration = if let Some(token) = token { - services().appservice.find_from_token(token).await + let token = if let Some(token) = token { + if let Some(reg_info) = services().appservice.find_from_token(token).await { + Token::Appservice(Box::new(reg_info.clone())) + } else if let Some((user_id, device_id)) = services().users.find_from_token(token)? { + Token::User((user_id, OwnedDeviceId::from(device_id))) + } else { + Token::Invalid + } } else { - None + Token::None }; + let mut json_body = serde_json::from_slice::(&body).ok(); + let (sender_user, sender_device, sender_servername, from_appservice) = - if let Some(info) = appservice_registration { - match metadata.authentication { - AuthScheme::AccessToken => { - let user_id = query_params.user_id.map_or_else( + match (metadata.authentication, token) { + (_, Token::Invalid) => { + return Err(Error::BadRequest( + ErrorKind::UnknownToken { soft_logout: false }, + "Unknown access token.", + )) + } + ( + AuthScheme::AccessToken + | AuthScheme::AppserviceToken + | AuthScheme::AccessTokenOptional, + Token::Appservice(info), + ) => { + let user_id = query_params + .user_id + .map_or_else( || { UserId::parse_with_server_name( info.registration.sender_localpart.as_str(), services().globals.server_name(), ) - .unwrap() }, - |s| UserId::parse(s).unwrap(), - ); + UserId::parse, + ) + .map_err(|_| { + Error::BadRequest(ErrorKind::InvalidUsername, "Username is invalid.") + })?; + if !services().users.exists(&user_id)? { + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "User does not exist.", + )); + } - if !services().users.exists(&user_id).unwrap() { + // TODO: Check if appservice is allowed to be that user + (Some(user_id), None, None, true) + } + (AuthScheme::AccessToken, Token::None) => { + return Err(Error::BadRequest( + ErrorKind::MissingToken, + "Missing access token.", + )); + } + ( + AuthScheme::AccessToken | AuthScheme::AccessTokenOptional, + Token::User((user_id, device_id)), + ) => (Some(user_id), Some(device_id), None, false), + (AuthScheme::ServerSignatures, Token::None) => { + if !services().globals.allow_federation() { + return Err(Error::bad_config("Federation is disabled.")); + } + + let TypedHeader(Authorization(x_matrix)) = parts + .extract::>>() + .await + .map_err(|e| { + warn!("Missing or invalid Authorization header: {}", e); + + let msg = match e.reason() { + TypedHeaderRejectionReason::Missing => { + "Missing Authorization header." + } + TypedHeaderRejectionReason::Error(_) => { + "Invalid X-Matrix signatures." + } + _ => "Unknown header-related error", + }; + + Error::BadRequest(ErrorKind::Forbidden, msg) + })?; + + let origin_signatures = BTreeMap::from_iter([( + x_matrix.key.clone(), + CanonicalJsonValue::String(x_matrix.sig), + )]); + + let signatures = BTreeMap::from_iter([( + x_matrix.origin.as_str().to_owned(), + CanonicalJsonValue::Object(origin_signatures), + )]); + + let mut request_map = BTreeMap::from_iter([ + ( + "method".to_owned(), + CanonicalJsonValue::String(parts.method.to_string()), + ), + ( + "uri".to_owned(), + CanonicalJsonValue::String(parts.uri.to_string()), + ), + ( + "origin".to_owned(), + CanonicalJsonValue::String(x_matrix.origin.as_str().to_owned()), + ), + ( + "destination".to_owned(), + CanonicalJsonValue::String( + services().globals.server_name().as_str().to_owned(), + ), + ), + ( + "signatures".to_owned(), + CanonicalJsonValue::Object(signatures), + ), + ]); + + if let Some(json_body) = &json_body { + request_map.insert("content".to_owned(), json_body.clone()); + }; + + let keys_result = services() + .rooms + .event_handler + .fetch_signing_keys(&x_matrix.origin, vec![x_matrix.key.to_owned()]) + .await; + + let keys = match keys_result { + Ok(b) => b, + Err(e) => { + warn!("Failed to fetch signing keys: {}", e); return Err(Error::BadRequest( ErrorKind::Forbidden, - "User does not exist.", + "Failed to fetch signing keys.", )); } + }; - // TODO: Check if appservice is allowed to be that user - (Some(user_id), None, None, true) - } - AuthScheme::ServerSignatures => (None, None, None, true), - AuthScheme::None => (None, None, None, true), - } - } else { - match metadata.authentication { - AuthScheme::AccessToken => { - let token = match token { - Some(token) => token, - _ => { - return Err(Error::BadRequest( - ErrorKind::MissingToken, - "Missing access token.", - )) - } - }; - - match services().users.find_from_token(token).unwrap() { - None => { - return Err(Error::BadRequest( - ErrorKind::UnknownToken { soft_logout: false }, - "Unknown access token.", - )) - } - Some((user_id, device_id)) => ( - Some(user_id), - Some(OwnedDeviceId::from(device_id)), - None, - false, - ), - } - } - AuthScheme::ServerSignatures => { - if !services().globals.allow_federation() { - return Err(Error::bad_config("Federation is disabled.")); - } - - let TypedHeader(Authorization(x_matrix)) = parts - .extract::>>() - .await - .map_err(|e| { - warn!("Missing or invalid Authorization header: {}", e); - - let msg = match e.reason() { - TypedHeaderRejectionReason::Missing => { - "Missing Authorization header." - } - TypedHeaderRejectionReason::Error(_) => { - "Invalid X-Matrix signatures." - } - _ => "Unknown header-related error", - }; - - Error::BadRequest(ErrorKind::Forbidden, msg) - })?; - - let origin_signatures = BTreeMap::from_iter([( - x_matrix.key.clone(), - CanonicalJsonValue::String(x_matrix.sig), - )]); - - let signatures = BTreeMap::from_iter([( - x_matrix.origin.as_str().to_owned(), - CanonicalJsonValue::Object(origin_signatures), - )]); - - let mut request_map = BTreeMap::from_iter([ - ( - "method".to_owned(), - CanonicalJsonValue::String(parts.method.to_string()), - ), - ( - "uri".to_owned(), - CanonicalJsonValue::String(parts.uri.to_string()), - ), - ( - "origin".to_owned(), - CanonicalJsonValue::String(x_matrix.origin.as_str().to_owned()), - ), - ( - "destination".to_owned(), - CanonicalJsonValue::String( - services().globals.server_name().as_str().to_owned(), - ), - ), - ( - "signatures".to_owned(), - CanonicalJsonValue::Object(signatures), - ), - ]); - - if let Some(json_body) = &json_body { - request_map.insert("content".to_owned(), json_body.clone()); - }; - - let keys_result = services() - .rooms - .event_handler - .fetch_signing_keys(&x_matrix.origin, vec![x_matrix.key.to_owned()]) - .await; - - let keys = match keys_result { - Ok(b) => b, - Err(e) => { - warn!("Failed to fetch signing keys: {}", e); - return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Failed to fetch signing keys.", - )); - } - }; + let pub_key_map = + BTreeMap::from_iter([(x_matrix.origin.as_str().to_owned(), keys)]); - let pub_key_map = - BTreeMap::from_iter([(x_matrix.origin.as_str().to_owned(), keys)]); + match ruma::signatures::verify_json(&pub_key_map, &request_map) { + Ok(()) => (None, None, Some(x_matrix.origin), false), + Err(e) => { + warn!( + "Failed to verify json request from {}: {}\n{:?}", + x_matrix.origin, e, request_map + ); - match ruma::signatures::verify_json(&pub_key_map, &request_map) { - Ok(()) => (None, None, Some(x_matrix.origin), false), - Err(e) => { + if parts.uri.to_string().contains('@') { warn!( - "Failed to verify json request from {}: {}\n{:?}", - x_matrix.origin, e, request_map - ); - - if parts.uri.to_string().contains('@') { - warn!( - "Request uri contained '@' character. Make sure your \ + "Request uri contained '@' character. Make sure your \ reverse proxy gives Conduit the raw uri (apache: use \ nocanon)" - ); - } - - return Err(Error::BadRequest( - ErrorKind::Forbidden, - "Failed to verify X-Matrix signatures.", - )); + ); } + + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Failed to verify X-Matrix signatures.", + )); } } - AuthScheme::None => (None, None, None, false), + } + ( + AuthScheme::None + | AuthScheme::AppserviceToken + | AuthScheme::AccessTokenOptional, + Token::None, + ) => (None, None, None, false), + ( + AuthScheme::ServerSignatures | AuthScheme::None, + Token::Appservice(_) | Token::User(_), + ) => { + return Err(Error::BadRequest( + ErrorKind::Unauthorized, + "Access tokens should not be used on this endpoint.", + )); + } + (AuthScheme::AppserviceToken, Token::User(_)) => { + return Err(Error::BadRequest( + ErrorKind::Unauthorized, + "Only appservice access tokens should be used on this endpoint.", + )); } }; From 11612e347d01788fec0a6f524f899724341b3293 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sun, 31 Mar 2024 13:25:04 +0100 Subject: [PATCH 122/129] fix: return error when trying to unregister unknown appservice id --- src/service/appservice/mod.rs | 3 ++- src/utils/error.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/service/appservice/mod.rs b/src/service/appservice/mod.rs index 4bda8961..7d2d46bd 100644 --- a/src/service/appservice/mod.rs +++ b/src/service/appservice/mod.rs @@ -143,7 +143,8 @@ impl Service { .registration_info .write() .await - .remove(service_name); + .remove(service_name) + .ok_or_else(|| crate::Error::AdminCommand("Appservice not found"))?; self.db.unregister_appservice(service_name) } diff --git a/src/utils/error.rs b/src/utils/error.rs index 04390283..899dfde6 100644 --- a/src/utils/error.rs +++ b/src/utils/error.rs @@ -85,6 +85,8 @@ pub enum Error { #[cfg(feature = "conduit_bin")] #[error("{0}")] PathError(#[from] axum::extract::rejection::PathRejection), + #[error("{0}")] + AdminCommand(&'static str), } impl Error { From 3ce3d13378dcb523c06ed914527ccc190c1d9457 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Sun, 31 Mar 2024 21:30:26 +0100 Subject: [PATCH 123/129] fix: do not expect that all http requests are valid reqwest requests --- src/api/appservice_server.rs | 18 +++++++++++------- src/api/client_server/alias.rs | 26 ++++++++++++-------------- src/api/server_server.rs | 3 +-- src/service/pusher/mod.rs | 3 +-- src/service/sending/mod.rs | 8 +++----- 5 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/api/appservice_server.rs b/src/api/appservice_server.rs index 213e4c09..3ec7a66e 100644 --- a/src/api/appservice_server.rs +++ b/src/api/appservice_server.rs @@ -13,11 +13,16 @@ use tracing::warn; pub(crate) async fn send_request( registration: Registration, request: T, -) -> Option> +) -> Result> where T: Debug, { - let destination = registration.url?; + let destination = match registration.url { + Some(url) => url, + None => { + return Ok(None); + } + }; let hs_token = registration.hs_token.as_str(); @@ -45,8 +50,7 @@ where ); *http_request.uri_mut() = parts.try_into().expect("our manipulation is always valid"); - let mut reqwest_request = reqwest::Request::try_from(http_request) - .expect("all http requests are valid reqwest requests"); + let mut reqwest_request = reqwest::Request::try_from(http_request)?; *reqwest_request.timeout_mut() = Some(Duration::from_secs(30)); @@ -63,7 +67,7 @@ where "Could not send request to appservice {:?} at {}: {}", registration.id, destination, e ); - return Some(Err(e.into())); + return Err(e.into()); } }; @@ -100,11 +104,11 @@ where .expect("reqwest body is valid http body"), ); - Some(response.map_err(|_| { + response.map(Some).map_err(|_| { warn!( "Appservice returned invalid response bytes {}\n{}", destination, url ); Error::BadServerResponse("Server returned bad response.") - })) + }) } diff --git a/src/api/client_server/alias.rs b/src/api/client_server/alias.rs index bc3a5e25..b84c7c4e 100644 --- a/src/api/client_server/alias.rs +++ b/src/api/client_server/alias.rs @@ -102,20 +102,18 @@ pub(crate) async fn get_alias_helper( None => { for appservice in services().appservice.read().await.values() { if appservice.aliases.is_match(room_alias.as_str()) - && if let Some(opt_result) = services() - .sending - .send_appservice_request( - appservice.registration.clone(), - appservice::query::query_room_alias::v1::Request { - room_alias: room_alias.clone(), - }, - ) - .await - { - opt_result.is_ok() - } else { - false - } + && matches!( + services() + .sending + .send_appservice_request( + appservice.registration.clone(), + appservice::query::query_room_alias::v1::Request { + room_alias: room_alias.clone(), + }, + ) + .await, + Ok(Some(_opt_result)) + ) { room_id = Some( services() diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 0fdf22fc..c116e796 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -233,8 +233,7 @@ where } } - let reqwest_request = reqwest::Request::try_from(http_request) - .expect("all http requests are valid reqwest requests"); + let reqwest_request = reqwest::Request::try_from(http_request)?; let url = reqwest_request.url().clone(); diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index 418b7a8f..6ca86be7 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -66,8 +66,7 @@ impl Service { })? .map(|body| body.freeze()); - let reqwest_request = reqwest::Request::try_from(http_request) - .expect("all http requests are valid reqwest requests"); + let reqwest_request = reqwest::Request::try_from(http_request)?; // TODO: we could keep this very short and let expo backoff do it's thing... //*reqwest_request.timeout_mut() = Some(Duration::from_secs(5)); diff --git a/src/service/sending/mod.rs b/src/service/sending/mod.rs index 45cca173..7e54e8b4 100644 --- a/src/service/sending/mod.rs +++ b/src/service/sending/mod.rs @@ -512,10 +512,8 @@ impl Service { ) .await { - None => Ok(kind.clone()), - Some(op_resp) => op_resp - .map(|_response| kind.clone()) - .map_err(|e| (kind.clone(), e)), + Ok(_) => Ok(kind.clone()), + Err(e) => Err((kind.clone(), e)), }; drop(permit); @@ -710,7 +708,7 @@ impl Service { &self, registration: Registration, request: T, - ) -> Option> + ) -> Result> where T: Debug, { From 1c529529aa4c7f1f8d08f60b44487c0032cead62 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Mon, 1 Apr 2024 13:36:38 +0100 Subject: [PATCH 124/129] chore: upgrade nix to 0.28 needed for musl targets on s390x --- Cargo.lock | 24 ++++++++++-------------- Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd83f2d2..cc614a77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,6 +314,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "clang-sys" version = "1.7.0" @@ -1388,15 +1394,6 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - [[package]] name = "mime" version = "0.3.17" @@ -1432,15 +1429,14 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.4" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.2", "cfg-if", + "cfg_aliases", "libc", - "memoffset", - "pin-utils", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index d2b828ae..636f32e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -125,7 +125,7 @@ features = [ ] [target.'cfg(unix)'.dependencies] -nix = { version = "0.26.2", features = ["resource"] } +nix = { version = "0.28", features = ["resource"] } [features] default = ["conduit_bin", "backend_sqlite", "backend_rocksdb", "systemd"] From e38af9b7fc069a8929ead6542a8a16d2f1a48286 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Mon, 1 Apr 2024 20:55:13 +0100 Subject: [PATCH 125/129] feat: use _matrix-fed._tcp SRV record, fallback to _matrix._tcp --- src/api/server_server.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 0fdf22fc..fb0d31a6 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -476,12 +476,11 @@ async fn find_actual_destination(destination: &'_ ServerName) -> (FedDest, FedDe (actual_destination, hostname) } -async fn query_srv_record(hostname: &'_ str) -> Option { - let hostname = hostname.trim_end_matches('.'); - if let Ok(Some(host_port)) = services() +async fn query_given_srv_record(record: &str) -> Option { + services() .globals .dns_resolver() - .srv_lookup(format!("_matrix._tcp.{hostname}.")) + .srv_lookup(record) .await .map(|srv| { srv.iter().next().map(|result| { @@ -491,10 +490,17 @@ async fn query_srv_record(hostname: &'_ str) -> Option { ) }) }) + .unwrap_or(None) +} + +async fn query_srv_record(hostname: &'_ str) -> Option { + let hostname = hostname.trim_end_matches('.'); + + if let Some(host_port) = query_given_srv_record(&format!("_matrix-fed._tcp.{hostname}.")).await { Some(host_port) } else { - None + query_given_srv_record(&format!("_matrix._tcp.{hostname}.")).await } } From 0d62c9de7ce96d90356210084dc36449df59af0d Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Tue, 2 Apr 2024 17:19:59 +0100 Subject: [PATCH 126/129] fix: ignore access tokens where they are not needed --- src/api/ruma_wrapper/axum.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/api/ruma_wrapper/axum.rs b/src/api/ruma_wrapper/axum.rs index 43e73c66..895b601d 100644 --- a/src/api/ruma_wrapper/axum.rs +++ b/src/api/ruma_wrapper/axum.rs @@ -110,7 +110,8 @@ where ( AuthScheme::AccessToken | AuthScheme::AppserviceToken - | AuthScheme::AccessTokenOptional, + | AuthScheme::AccessTokenOptional + | AuthScheme::None, Token::Appservice(info), ) => { let user_id = query_params @@ -144,7 +145,7 @@ where )); } ( - AuthScheme::AccessToken | AuthScheme::AccessTokenOptional, + AuthScheme::AccessToken | AuthScheme::AccessTokenOptional | AuthScheme::None, Token::User((user_id, device_id)), ) => (Some(user_id), Some(device_id), None, false), (AuthScheme::ServerSignatures, Token::None) => { @@ -259,13 +260,10 @@ where | AuthScheme::AccessTokenOptional, Token::None, ) => (None, None, None, false), - ( - AuthScheme::ServerSignatures | AuthScheme::None, - Token::Appservice(_) | Token::User(_), - ) => { + (AuthScheme::ServerSignatures, Token::Appservice(_) | Token::User(_)) => { return Err(Error::BadRequest( ErrorKind::Unauthorized, - "Access tokens should not be used on this endpoint.", + "Only server signatures should be used on this endpoint.", )); } (AuthScheme::AppserviceToken, Token::User(_)) => { From 0f6b771cdd55633af3bcdb706d48139532106412 Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Wed, 3 Apr 2024 22:42:14 +0100 Subject: [PATCH 127/129] fix(membership): remove join_authorized_via_users_server field on state update --- src/api/client_server/membership.rs | 2 ++ src/api/client_server/profile.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index bc84b262..86ac5950 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -270,6 +270,7 @@ pub async fn ban_user_route(body: Ruma) -> Result Date: Mon, 1 Apr 2024 13:04:36 +0100 Subject: [PATCH 128/129] fix: do not allow administration of remote users --- src/service/admin/mod.rs | 91 +++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 15 deletions(-) diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index f2f60a7a..408adf6f 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -555,6 +555,13 @@ impl Service { } }; + // Checks if user is local + if user_id.server_name() != services().globals.server_name() { + return Ok(RoomMessageEventContent::text_plain( + "The specified user is not from this server!", + )); + }; + // Check if the specified user is valid if !services().users.exists(&user_id)? || user_id @@ -658,7 +665,15 @@ impl Service { user_id, } => { let user_id = Arc::::from(user_id); - if services().users.exists(&user_id)? { + if !services().users.exists(&user_id)? { + RoomMessageEventContent::text_plain(format!( + "User {user_id} doesn't exist on this server" + )) + } else if user_id.server_name() != services().globals.server_name() { + RoomMessageEventContent::text_plain(format!( + "User {user_id} is not from this server" + )) + } else { RoomMessageEventContent::text_plain(format!( "Making {user_id} leave all rooms before deactivation..." )); @@ -672,30 +687,76 @@ impl Service { RoomMessageEventContent::text_plain(format!( "User {user_id} has been deactivated" )) - } else { - RoomMessageEventContent::text_plain(format!( - "User {user_id} doesn't exist on this server" - )) } } AdminCommand::DeactivateAll { leave_rooms, force } => { if body.len() > 2 && body[0].trim() == "```" && body.last().unwrap().trim() == "```" { - let usernames = body.clone().drain(1..body.len() - 1).collect::>(); - - let mut user_ids: Vec<&UserId> = Vec::new(); - - for &username in &usernames { - match <&UserId>::try_from(username) { - Ok(user_id) => user_ids.push(user_id), + let users = body.clone().drain(1..body.len() - 1).collect::>(); + + let mut user_ids = Vec::new(); + let mut remote_ids = Vec::new(); + let mut non_existant_ids = Vec::new(); + let mut invalid_users = Vec::new(); + + for &user in &users { + match <&UserId>::try_from(user) { + Ok(user_id) => { + if user_id.server_name() != services().globals.server_name() { + remote_ids.push(user_id) + } else if !services().users.exists(user_id)? { + non_existant_ids.push(user_id) + } else { + user_ids.push(user_id) + } + } Err(_) => { - return Ok(RoomMessageEventContent::text_plain(format!( - "{username} is not a valid username" - ))) + invalid_users.push(user); } } } + let mut markdown_message = String::new(); + let mut html_message = String::new(); + if !invalid_users.is_empty() { + markdown_message.push_str("The following user ids are not valid:\n```\n"); + html_message.push_str("The following user ids are not valid:\n
\n");
+                        for invalid_user in invalid_users {
+                            markdown_message.push_str(&format!("{invalid_user}\n"));
+                            html_message.push_str(&format!("{invalid_user}\n"));
+                        }
+                        markdown_message.push_str("```\n\n");
+                        html_message.push_str("
\n\n"); + } + if !remote_ids.is_empty() { + markdown_message + .push_str("The following users are not from this server:\n```\n"); + html_message + .push_str("The following users are not from this server:\n
\n");
+                        for remote_id in remote_ids {
+                            markdown_message.push_str(&format!("{remote_id}\n"));
+                            html_message.push_str(&format!("{remote_id}\n"));
+                        }
+                        markdown_message.push_str("```\n\n");
+                        html_message.push_str("
\n\n"); + } + if !non_existant_ids.is_empty() { + markdown_message.push_str("The following users do not exist:\n```\n"); + html_message.push_str("The following users do not exist:\n
\n");
+                        for non_existant_id in non_existant_ids {
+                            markdown_message.push_str(&format!("{non_existant_id}\n"));
+                            html_message.push_str(&format!("{non_existant_id}\n"));
+                        }
+                        markdown_message.push_str("```\n\n");
+                        html_message.push_str("
\n\n"); + } + if !markdown_message.is_empty() { + return Ok(RoomMessageEventContent::text_html( + markdown_message, + html_message, + )); + } + let mut deactivation_count = 0; let mut admins = Vec::new(); From fe78cc8262d009a94efe8cdf11b2ad8fe10c48ad Mon Sep 17 00:00:00 2001 From: Matthias Ahouansou Date: Thu, 4 Apr 2024 02:00:08 +0100 Subject: [PATCH 129/129] refactor(state_accessor): add method to check if a user can invite another user --- src/service/rooms/state_accessor/mod.rs | 40 +++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/service/rooms/state_accessor/mod.rs b/src/service/rooms/state_accessor/mod.rs index 903ad47b..c287edc5 100644 --- a/src/service/rooms/state_accessor/mod.rs +++ b/src/service/rooms/state_accessor/mod.rs @@ -18,9 +18,10 @@ use ruma::{ }, EventId, JsOption, OwnedServerName, OwnedUserId, RoomId, ServerName, UserId, }; -use tracing::error; +use serde_json::value::to_raw_value; +use tracing::{error, warn}; -use crate::{services, Error, PduEvent, Result}; +use crate::{service::pdu::PduBuilder, services, Error, PduEvent, Result}; pub struct Service { pub db: &'static dyn Data, @@ -301,6 +302,41 @@ impl Service { }) } + pub async fn user_can_invite( + &self, + room_id: &RoomId, + sender: &UserId, + target_user: &UserId, + ) -> Result { + let content = to_raw_value(&RoomMemberEventContent::new(MembershipState::Invite)) + .expect("Event content always serializes"); + + let new_event = PduBuilder { + event_type: ruma::events::TimelineEventType::RoomMember, + content, + unsigned: None, + state_key: Some(target_user.into()), + redacts: None, + }; + + let mutex_state = Arc::clone( + services() + .globals + .roomid_mutex_state + .write() + .await + .entry(room_id.to_owned()) + .or_default(), + ); + let state_lock = mutex_state.lock().await; + + Ok(services() + .rooms + .timeline + .create_hash_and_sign_event(new_event, sender, room_id, &state_lock) + .is_ok()) + } + pub fn get_member( &self, room_id: &RoomId,