From f53ecaa97db45e8ab749bd65195a3eaf85a28a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Sun, 26 Feb 2023 16:29:06 +0100 Subject: [PATCH 1/4] Bump Ruma --- Cargo.lock | 143 +++++++++++++++++++++------- Cargo.toml | 4 +- src/api/client_server/config.rs | 8 +- src/api/client_server/membership.rs | 18 ++-- src/api/client_server/message.rs | 12 +-- src/api/client_server/profile.rs | 6 +- src/api/client_server/redact.rs | 4 +- src/api/client_server/room.rs | 30 +++--- src/api/client_server/sync.rs | 10 +- src/api/client_server/to_device.rs | 7 +- src/api/ruma_wrapper/axum.rs | 2 +- src/api/server_server.rs | 27 ++++-- src/service/admin/mod.rs | 30 +++--- src/service/pdu.rs | 18 ++-- src/service/pusher/mod.rs | 7 +- src/service/rooms/state/mod.rs | 4 +- src/service/rooms/timeline/mod.rs | 44 ++++----- 17 files changed, 228 insertions(+), 146 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 505c71c..385d8f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,9 +183,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" [[package]] name = "base64ct" @@ -412,6 +412,7 @@ dependencies = [ "rust-argon2", "sd-notify", "serde", + "serde_html_form", "serde_json", "serde_yaml", "sha-1", @@ -669,7 +670,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", - "sha2", + "sha2 0.9.9", "zeroize", ] @@ -721,7 +722,7 @@ dependencies = [ "atomic", "pear", "serde", - "toml", + "toml 0.5.9", "uncased", "version_check", ] @@ -1819,7 +1820,7 @@ checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" dependencies = [ "once_cell", "thiserror", - "toml", + "toml 0.5.9", ] [[package]] @@ -2075,8 +2076,8 @@ dependencies = [ [[package]] name = "ruma" -version = "0.7.4" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.8.2" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ "assign", "js_int", @@ -2093,8 +2094,8 @@ dependencies = [ [[package]] name = "ruma-appservice-api" -version = "0.7.0" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.8.1" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ "js_int", "ruma-common", @@ -2104,8 +2105,8 @@ dependencies = [ [[package]] name = "ruma-client-api" -version = "0.15.3" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.16.2" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ "assign", "bytes", @@ -2113,23 +2114,22 @@ dependencies = [ "js_int", "js_option", "maplit", - "percent-encoding", "ruma-common", "serde", + "serde_html_form", "serde_json", ] [[package]] name = "ruma-common" -version = "0.10.5" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.11.3" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ - "base64 0.20.0", + "base64 0.21.0", "bytes", "form_urlencoded", "http", "indexmap", - "itoa", "js_int", "js_option", "konst", @@ -2139,6 +2139,7 @@ dependencies = [ "ruma-identifiers-validation", "ruma-macros", "serde", + "serde_html_form", "serde_json", "thiserror", "tracing", @@ -2149,8 +2150,8 @@ dependencies = [ [[package]] name = "ruma-federation-api" -version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.7.1" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ "js_int", "ruma-common", @@ -2160,8 +2161,8 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" -version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.9.1" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ "js_int", "thiserror", @@ -2169,8 +2170,8 @@ dependencies = [ [[package]] name = "ruma-identity-service-api" -version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.7.1" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ "js_int", "ruma-common", @@ -2179,8 +2180,8 @@ dependencies = [ [[package]] name = "ruma-macros" -version = "0.10.5" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.11.3" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ "once_cell", "proc-macro-crate", @@ -2189,13 +2190,13 @@ dependencies = [ "ruma-identifiers-validation", "serde", "syn", - "toml", + "toml 0.7.2", ] [[package]] name = "ruma-push-gateway-api" -version = "0.6.0" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.7.1" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ "js_int", "ruma-common", @@ -2205,24 +2206,24 @@ dependencies = [ [[package]] name = "ruma-signatures" -version = "0.12.0" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.13.1" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ - "base64 0.20.0", + "base64 0.21.0", "ed25519-dalek", "pkcs8", "rand 0.7.3", "ruma-common", "serde_json", - "sha2", + "sha2 0.10.6", "subslice", "thiserror", ] [[package]] name = "ruma-state-res" -version = "0.8.0" -source = "git+https://github.com/ruma/ruma?rev=67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26#67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26" +version = "0.9.1" +source = "git+https://github.com/ruma/ruma?rev=8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5#8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5" dependencies = [ "itertools", "js_int", @@ -2388,6 +2389,19 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_html_form" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53192e38d5c88564b924dbe9b60865ecbb71b81d38c4e61c817cffd3e36ef696" +dependencies = [ + "form_urlencoded", + "indexmap", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_json" version = "1.0.89" @@ -2399,6 +2413,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2459,6 +2482,17 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + [[package]] name = "sharded-slab" version = "0.1.4" @@ -2807,6 +2841,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1eb0622d28f4b9c90adc4ea4b2b46b47663fde9ac5fafcb14a1369d5508825" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -3343,6 +3411,15 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +[[package]] +name = "winnow" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf09497b8f8b5ac5d3bb4d05c0a99be20f26fd3d5f2db7b0716e946d5103658" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index 36ffb13..7c7df7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ tower-http = { version = "0.3.4", features = ["add-extension", "cors", "compress # Used for matrix spec type definitions and helpers #ruma = { version = "0.4.0", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } -ruma = { git = "https://github.com/ruma/ruma", rev = "67d0f3cc04a8d1dc4a8a1ec947519967ce11ce26", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } +ruma = { git = "https://github.com/ruma/ruma", rev = "8eea3e05490fa9a318f9ed66c3a75272e6ef0ee5", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-msc2448", "unstable-exhaustive-types", "ring-compat", "unstable-unspecified" ] } #ruma = { git = "https://github.com/timokoesters/ruma", rev = "50c1db7e0a3a21fc794b0cce3b64285a4c750c71", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } @@ -83,6 +83,8 @@ num_cpus = "1.13.0" threadpool = "1.8.1" heed = { git = "https://github.com/timokoesters/heed.git", rev = "f6f825da7fb2c758867e05ad973ef800a6fe1d5d", optional = true } rocksdb = { version = "0.17.0", default-features = true, features = ["multi-threaded-cf", "zstd"], optional = true } +# Used for ruma wrapper +serde_html_form = "0.2.0" thread_local = "1.1.3" # used for TURN server authentication diff --git a/src/api/client_server/config.rs b/src/api/client_server/config.rs index 12f9aea..37279e3 100644 --- a/src/api/client_server/config.rs +++ b/src/api/client_server/config.rs @@ -75,7 +75,7 @@ pub async fn get_global_account_data_route( let event: Box = services() .account_data - .get(None, sender_user, body.event_type.clone().into())? + .get(None, sender_user, body.event_type.to_string().into())? .ok_or(Error::BadRequest(ErrorKind::NotFound, "Data not found."))?; let account_data = serde_json::from_str::(event.get()) @@ -95,11 +95,7 @@ pub async fn get_room_account_data_route( let event: Box = services() .account_data - .get( - Some(&body.room_id), - sender_user, - body.event_type.clone().into(), - )? + .get(Some(&body.room_id), sender_user, body.event_type.clone())? .ok_or(Error::BadRequest(ErrorKind::NotFound, "Data not found."))?; let account_data = serde_json::from_str::(event.get()) diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs index b9b1756..cd26372 100644 --- a/src/api/client_server/membership.rs +++ b/src/api/client_server/membership.rs @@ -17,7 +17,7 @@ use ruma::{ member::{MembershipState, RoomMemberEventContent}, power_levels::RoomPowerLevelsEventContent, }, - RoomEventType, StateEventType, + StateEventType, TimelineEventType, }, serde::Base64, state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, @@ -209,7 +209,7 @@ pub async fn kick_user_route( services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomMember, + 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()), @@ -273,7 +273,7 @@ pub async fn ban_user_route(body: Ruma) -> Result( let (pdu, pdu_json) = services().rooms.timeline.create_hash_and_sign_event( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content, unsigned: None, state_key: Some(user_id.to_string()), @@ -1295,7 +1297,7 @@ pub(crate) async fn invite_helper<'a>( services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content: to_raw_value(&RoomMemberEventContent { membership: MembershipState::Invite, displayname: services().users.displayname(user_id)?, @@ -1420,7 +1422,7 @@ pub async fn leave_room(user_id: &UserId, room_id: &RoomId, reason: Option PduCount::try_from_string(&from)?, None => match body.dir { - ruma::api::client::Direction::Forward => PduCount::min(), - ruma::api::client::Direction::Backward => PduCount::max(), + ruma::api::Direction::Forward => PduCount::min(), + ruma::api::Direction::Backward => PduCount::max(), }, }; @@ -143,7 +143,7 @@ pub async fn get_message_events_route( let mut lazy_loaded = HashSet::new(); match body.dir { - ruma::api::client::Direction::Forward => { + ruma::api::Direction::Forward => { let events_after: Vec<_> = services() .rooms .timeline @@ -187,7 +187,7 @@ pub async fn get_message_events_route( resp.end = next_token.map(|count| count.stringify()); resp.chunk = events_after; } - ruma::api::client::Direction::Backward => { + ruma::api::Direction::Backward => { services() .rooms .timeline diff --git a/src/api/client_server/profile.rs b/src/api/client_server/profile.rs index 6400e89..8fb38b5 100644 --- a/src/api/client_server/profile.rs +++ b/src/api/client_server/profile.rs @@ -9,7 +9,7 @@ use ruma::{ }, federation::{self, query::get_profile_information::v1::ProfileField}, }, - events::{room::member::RoomMemberEventContent, RoomEventType, StateEventType}, + events::{room::member::RoomMemberEventContent, StateEventType, TimelineEventType}, }; use serde_json::value::to_raw_value; use std::sync::Arc; @@ -37,7 +37,7 @@ pub async fn set_displayname_route( .map(|room_id| { Ok::<_, Error>(( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content: to_raw_value(&RoomMemberEventContent { displayname: body.displayname.clone(), ..serde_json::from_str( @@ -172,7 +172,7 @@ pub async fn set_avatar_url_route( .map(|room_id| { Ok::<_, Error>(( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content: to_raw_value(&RoomMemberEventContent { avatar_url: body.avatar_url.clone(), ..serde_json::from_str( diff --git a/src/api/client_server/redact.rs b/src/api/client_server/redact.rs index a29a561..20f7e91 100644 --- a/src/api/client_server/redact.rs +++ b/src/api/client_server/redact.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use crate::{service::pdu::PduBuilder, services, Result, Ruma}; use ruma::{ api::client::redact::redact_event, - events::{room::redaction::RoomRedactionEventContent, RoomEventType}, + events::{room::redaction::RoomRedactionEventContent, TimelineEventType}, }; use serde_json::value::to_raw_value; @@ -32,7 +32,7 @@ pub async fn redact_event_route( let event_id = services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomRedaction, + event_type: TimelineEventType::RoomRedaction, content: to_raw_value(&RoomRedactionEventContent { reason: body.reason.clone(), }) diff --git a/src/api/client_server/room.rs b/src/api/client_server/room.rs index aa6fa5f..8c39b78 100644 --- a/src/api/client_server/room.rs +++ b/src/api/client_server/room.rs @@ -19,7 +19,7 @@ use ruma::{ tombstone::RoomTombstoneEventContent, topic::RoomTopicEventContent, }, - RoomEventType, StateEventType, + StateEventType, TimelineEventType, }, int, serde::JsonObject, @@ -175,7 +175,7 @@ pub async fn create_room_route( // 1. The room create event services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomCreate, + event_type: TimelineEventType::RoomCreate, content: to_raw_value(&content).expect("event is valid, we just created it"), unsigned: None, state_key: Some("".to_owned()), @@ -189,7 +189,7 @@ pub async fn create_room_route( // 2. Let the room creator join services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content: to_raw_value(&RoomMemberEventContent { membership: MembershipState::Join, displayname: services().users.displayname(sender_user)?, @@ -247,7 +247,7 @@ pub async fn create_room_route( services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomPowerLevels, + event_type: TimelineEventType::RoomPowerLevels, content: to_raw_value(&power_levels_content) .expect("to_raw_value always works on serde_json::Value"), unsigned: None, @@ -263,7 +263,7 @@ pub async fn create_room_route( if let Some(room_alias_id) = &alias { services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomCanonicalAlias, + event_type: TimelineEventType::RoomCanonicalAlias, content: to_raw_value(&RoomCanonicalAliasEventContent { alias: Some(room_alias_id.to_owned()), alt_aliases: vec![], @@ -284,7 +284,7 @@ pub async fn create_room_route( // 5.1 Join Rules services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomJoinRules, + event_type: TimelineEventType::RoomJoinRules, content: to_raw_value(&RoomJoinRulesEventContent::new(match preset { RoomPreset::PublicChat => JoinRule::Public, // according to spec "invite" is the default @@ -303,7 +303,7 @@ pub async fn create_room_route( // 5.2 History Visibility services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomHistoryVisibility, + event_type: TimelineEventType::RoomHistoryVisibility, content: to_raw_value(&RoomHistoryVisibilityEventContent::new( HistoryVisibility::Shared, )) @@ -320,7 +320,7 @@ pub async fn create_room_route( // 5.3 Guest Access services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomGuestAccess, + event_type: TimelineEventType::RoomGuestAccess, content: to_raw_value(&RoomGuestAccessEventContent::new(match preset { RoomPreset::PublicChat => GuestAccess::Forbidden, _ => GuestAccess::CanJoin, @@ -346,7 +346,7 @@ pub async fn create_room_route( pdu_builder.state_key.get_or_insert_with(|| "".to_owned()); // Silently skip encryption events if they are not allowed - if pdu_builder.event_type == RoomEventType::RoomEncryption + if pdu_builder.event_type == TimelineEventType::RoomEncryption && !services().globals.allow_encryption() { continue; @@ -364,7 +364,7 @@ pub async fn create_room_route( if let Some(name) = &body.name { services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomName, + event_type: TimelineEventType::RoomName, content: to_raw_value(&RoomNameEventContent::new(Some(name.clone()))) .expect("event is valid, we just created it"), unsigned: None, @@ -380,7 +380,7 @@ pub async fn create_room_route( if let Some(topic) = &body.topic { services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomTopic, + event_type: TimelineEventType::RoomTopic, content: to_raw_value(&RoomTopicEventContent { topic: topic.clone(), }) @@ -526,7 +526,7 @@ pub async fn upgrade_room_route( // Fail if the sender does not have the required permissions let tombstone_event_id = services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomTombstone, + event_type: TimelineEventType::RoomTombstone, content: to_raw_value(&RoomTombstoneEventContent { body: "This room has been replaced".to_owned(), replacement_room: replacement_room.clone(), @@ -608,7 +608,7 @@ pub async fn upgrade_room_route( services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomCreate, + event_type: TimelineEventType::RoomCreate, content: to_raw_value(&create_event_content) .expect("event is valid, we just created it"), unsigned: None, @@ -623,7 +623,7 @@ pub async fn upgrade_room_route( // Join the new room services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content: to_raw_value(&RoomMemberEventContent { membership: MembershipState::Join, displayname: services().users.displayname(sender_user)?, @@ -716,7 +716,7 @@ pub async fn upgrade_room_route( // 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: RoomEventType::RoomPowerLevels, + event_type: TimelineEventType::RoomPowerLevels, content: to_raw_value(&power_levels_event_content) .expect("event is valid, we just created it"), unsigned: None, diff --git a/src/api/client_server/sync.rs b/src/api/client_server/sync.rs index 5eb820c..b4baec1 100644 --- a/src/api/client_server/sync.rs +++ b/src/api/client_server/sync.rs @@ -14,7 +14,7 @@ use ruma::{ }, events::{ room::member::{MembershipState, RoomMemberEventContent}, - RoomEventType, StateEventType, + StateEventType, TimelineEventType, }, serde::Raw, DeviceId, OwnedDeviceId, OwnedUserId, RoomId, UserId, @@ -678,7 +678,7 @@ async fn load_joined_room( .timeline .all_pdus(&sender_user, &room_id)? .filter_map(|pdu| pdu.ok()) // Ignore all broken pdus - .filter(|(_, pdu)| pdu.kind == RoomEventType::RoomMember) + .filter(|(_, pdu)| pdu.kind == TimelineEventType::RoomMember) .map(|(_, pdu)| { let content: RoomMemberEventContent = serde_json::from_str(pdu.content.get()) .map_err(|_| { @@ -868,7 +868,7 @@ async fn load_joined_room( } }; - if pdu.kind == RoomEventType::RoomMember { + if pdu.kind == TimelineEventType::RoomMember { match UserId::parse( pdu.state_key .as_ref() @@ -936,11 +936,11 @@ async fn load_joined_room( let send_member_count = state_events .iter() - .any(|event| event.kind == RoomEventType::RoomMember); + .any(|event| event.kind == TimelineEventType::RoomMember); if encrypted_room { for state_event in &state_events { - if state_event.kind != RoomEventType::RoomMember { + if state_event.kind != TimelineEventType::RoomMember { continue; } diff --git a/src/api/client_server/to_device.rs b/src/api/client_server/to_device.rs index 26db4e4..31590fc 100644 --- a/src/api/client_server/to_device.rs +++ b/src/api/client_server/to_device.rs @@ -1,4 +1,3 @@ -use ruma::events::ToDeviceEventType; use std::collections::BTreeMap; use crate::{services, Error, Result, Ruma}; @@ -42,7 +41,7 @@ pub async fn send_event_to_device_route( serde_json::to_vec(&federation::transactions::edu::Edu::DirectToDevice( DirectDeviceContent { sender: sender_user.clone(), - ev_type: ToDeviceEventType::from(&*body.event_type), + ev_type: body.event_type.clone(), message_id: count.to_string().into(), messages, }, @@ -60,7 +59,7 @@ pub async fn send_event_to_device_route( sender_user, target_user_id, target_device_id, - &body.event_type, + &body.event_type.to_string(), event.deserialize_as().map_err(|_| { Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid") })?, @@ -73,7 +72,7 @@ pub async fn send_event_to_device_route( sender_user, target_user_id, &target_device_id?, - &body.event_type, + &body.event_type.to_string(), event.deserialize_as().map_err(|_| { Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid") })?, diff --git a/src/api/ruma_wrapper/axum.rs b/src/api/ruma_wrapper/axum.rs index 74f506f..2d2af70 100644 --- a/src/api/ruma_wrapper/axum.rs +++ b/src/api/ruma_wrapper/axum.rs @@ -47,7 +47,7 @@ where let path_params = Path::>::from_request(req).await?; let query = req.uri().query().unwrap_or_default(); - let query_params: QueryParams = match ruma::serde::urlencoded::from_str(query) { + let query_params: QueryParams = match serde_html_form::from_str(query) { Ok(params) => params, Err(e) => { error!(%query, "Failed to deserialize query parameters: {}", e); diff --git a/src/api/server_server.rs b/src/api/server_server.rs index 852e59a..961b658 100644 --- a/src/api/server_server.rs +++ b/src/api/server_server.rs @@ -18,11 +18,7 @@ use ruma::{ discovery::{get_server_keys, get_server_version, ServerSigningKeys, VerifyKey}, event::{get_event, get_missing_events, get_room_state, get_room_state_ids}, keys::{claim_keys, get_keys}, - membership::{ - create_invite, - create_join_event::{self, RoomState}, - prepare_join_event, - }, + membership::{create_invite, create_join_event, prepare_join_event}, query::{get_profile_information, get_room_information}, transactions::{ edu::{DeviceListUpdateContent, DirectDeviceContent, Edu, SigningKeyUpdateContent}, @@ -39,7 +35,7 @@ use ruma::{ join_rules::{JoinRule, RoomJoinRulesEventContent}, member::{MembershipState, RoomMemberEventContent}, }, - RoomEventType, StateEventType, + StateEventType, TimelineEventType, }, serde::{Base64, JsonObject, Raw}, to_device::DeviceIdOrAllDevices, @@ -1440,7 +1436,7 @@ pub async fn create_join_event_template_route( let (_pdu, mut pdu_json) = services().rooms.timeline.create_hash_and_sign_event( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content, unsigned: None, state_key: Some(body.user_id.to_string()), @@ -1465,7 +1461,7 @@ async fn create_join_event( sender_servername: &ServerName, room_id: &RoomId, pdu: &RawJsonValue, -) -> Result { +) -> Result { if !services().globals.allow_federation() { return Err(Error::bad_config("Federation is disabled.")); } @@ -1587,7 +1583,7 @@ async fn create_join_event( services().sending.send_pdu(servers, &pdu_id)?; - Ok(RoomState { + Ok(create_join_event::v1::RoomState { auth_chain: auth_chain_ids .filter_map(|id| services().rooms.timeline.get_pdu_json(&id).ok().flatten()) .map(PduEvent::convert_to_outgoing_federation_event) @@ -1628,7 +1624,18 @@ pub async fn create_join_event_v2_route( .as_ref() .expect("server is authenticated"); - let room_state = create_join_event(sender_servername, &body.room_id, &body.pdu).await?; + let create_join_event::v1::RoomState { + auth_chain, + state, + event, + } = create_join_event(sender_servername, &body.room_id, &body.pdu).await?; + let room_state = create_join_event::v2::RoomState { + members_omitted: false, + auth_chain, + state, + event, + servers_in_room: None, + }; Ok(create_join_event::v2::Response { room_state }) } diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs index b6609e1..d37ec69 100644 --- a/src/service/admin/mod.rs +++ b/src/service/admin/mod.rs @@ -21,7 +21,7 @@ use ruma::{ power_levels::RoomPowerLevelsEventContent, topic::RoomTopicEventContent, }, - RoomEventType, + TimelineEventType, }, EventId, OwnedRoomAliasId, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId, }; @@ -212,7 +212,7 @@ impl Service { .timeline .build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomMessage, + event_type: TimelineEventType::RoomMessage, content: to_raw_value(&message) .expect("event is valid, we just created it"), unsigned: None, @@ -854,7 +854,7 @@ impl Service { // 1. The room create event services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomCreate, + event_type: TimelineEventType::RoomCreate, content: to_raw_value(&content).expect("event is valid, we just created it"), unsigned: None, state_key: Some("".to_owned()), @@ -868,7 +868,7 @@ impl Service { // 2. Make conduit bot join services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content: to_raw_value(&RoomMemberEventContent { membership: MembershipState::Join, displayname: None, @@ -895,7 +895,7 @@ impl Service { services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomPowerLevels, + event_type: TimelineEventType::RoomPowerLevels, content: to_raw_value(&RoomPowerLevelsEventContent { users, ..Default::default() @@ -913,7 +913,7 @@ impl Service { // 4.1 Join Rules services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomJoinRules, + event_type: TimelineEventType::RoomJoinRules, content: to_raw_value(&RoomJoinRulesEventContent::new(JoinRule::Invite)) .expect("event is valid, we just created it"), unsigned: None, @@ -928,7 +928,7 @@ impl Service { // 4.2 History Visibility services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomHistoryVisibility, + event_type: TimelineEventType::RoomHistoryVisibility, content: to_raw_value(&RoomHistoryVisibilityEventContent::new( HistoryVisibility::Shared, )) @@ -945,7 +945,7 @@ impl Service { // 4.3 Guest Access services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomGuestAccess, + event_type: TimelineEventType::RoomGuestAccess, content: to_raw_value(&RoomGuestAccessEventContent::new(GuestAccess::Forbidden)) .expect("event is valid, we just created it"), unsigned: None, @@ -961,7 +961,7 @@ impl Service { let room_name = format!("{} Admin Room", services().globals.server_name()); services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomName, + event_type: TimelineEventType::RoomName, content: to_raw_value(&RoomNameEventContent::new(Some(room_name))) .expect("event is valid, we just created it"), unsigned: None, @@ -975,7 +975,7 @@ impl Service { services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomTopic, + event_type: TimelineEventType::RoomTopic, content: to_raw_value(&RoomTopicEventContent { topic: format!("Manage {}", services().globals.server_name()), }) @@ -996,7 +996,7 @@ impl Service { services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomCanonicalAlias, + event_type: TimelineEventType::RoomCanonicalAlias, content: to_raw_value(&RoomCanonicalAliasEventContent { alias: Some(alias.clone()), alt_aliases: Vec::new(), @@ -1053,7 +1053,7 @@ impl Service { // Invite and join the real user services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content: to_raw_value(&RoomMemberEventContent { membership: MembershipState::Invite, displayname: None, @@ -1075,7 +1075,7 @@ impl Service { )?; services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomMember, + event_type: TimelineEventType::RoomMember, content: to_raw_value(&RoomMemberEventContent { membership: MembershipState::Join, displayname: Some(displayname), @@ -1103,7 +1103,7 @@ impl Service { services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomPowerLevels, + event_type: TimelineEventType::RoomPowerLevels, content: to_raw_value(&RoomPowerLevelsEventContent { users, ..Default::default() @@ -1121,7 +1121,7 @@ impl Service { // Send welcome message services().rooms.timeline.build_and_append_pdu( PduBuilder { - event_type: RoomEventType::RoomMessage, + event_type: TimelineEventType::RoomMessage, content: to_raw_value(&RoomMessageEventContent::text_html( format!("## Thank you for trying out Conduit!\n\nConduit is currently in Beta. This means you can join and participate in most Matrix rooms, but not all features are supported and you might run into bugs from time to time.\n\nHelpful links:\n> Website: https://conduit.rs\n> Git and Documentation: https://gitlab.com/famedly/conduit\n> Report issues: https://gitlab.com/famedly/conduit/-/issues\n\nFor a list of available commands, send the following message in this room: `@conduit:{}: --help`\n\nHere are some rooms you can join (by typing the command):\n\nConduit room (Ask questions and get notified on updates):\n`/join #conduit:fachschaften.org`\n\nConduit lounge (Off-topic, only Conduit users are allowed to join)\n`/join #conduit-lounge:conduit.rs`", services().globals.server_name()), format!("

Thank you for trying out Conduit!

\n

Conduit is currently in Beta. This means you can join and participate in most Matrix rooms, but not all features are supported and you might run into bugs from time to time.

\n

Helpful links:

\n
\n

Website: https://conduit.rs
Git and Documentation: https://gitlab.com/famedly/conduit
Report issues: https://gitlab.com/famedly/conduit/-/issues

\n
\n

For a list of available commands, send the following message in this room: @conduit:{}: --help

\n

Here are some rooms you can join (by typing the command):

\n

Conduit room (Ask questions and get notified on updates):
/join #conduit:fachschaften.org

\n

Conduit lounge (Off-topic, only Conduit users are allowed to join)
/join #conduit-lounge:conduit.rs

\n", services().globals.server_name()), diff --git a/src/service/pdu.rs b/src/service/pdu.rs index 5b5cbd0..a497b11 100644 --- a/src/service/pdu.rs +++ b/src/service/pdu.rs @@ -3,7 +3,7 @@ use ruma::{ events::{ room::member::RoomMemberEventContent, AnyEphemeralRoomEvent, AnyStateEvent, AnyStrippedStateEvent, AnySyncStateEvent, AnySyncTimelineEvent, AnyTimelineEvent, - RoomEventType, StateEvent, + StateEvent, TimelineEventType, }, serde::Raw, state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, MilliSecondsSinceUnixEpoch, @@ -31,7 +31,7 @@ pub struct PduEvent { pub sender: OwnedUserId, pub origin_server_ts: UInt, #[serde(rename = "type")] - pub kind: RoomEventType, + pub kind: TimelineEventType, pub content: Box, #[serde(skip_serializing_if = "Option::is_none")] pub state_key: Option, @@ -53,10 +53,10 @@ impl PduEvent { self.unsigned = None; let allowed: &[&str] = match self.kind { - RoomEventType::RoomMember => &["join_authorised_via_users_server", "membership"], - RoomEventType::RoomCreate => &["creator"], - RoomEventType::RoomJoinRules => &["join_rule"], - RoomEventType::RoomPowerLevels => &[ + TimelineEventType::RoomMember => &["join_authorised_via_users_server", "membership"], + TimelineEventType::RoomCreate => &["creator"], + TimelineEventType::RoomJoinRules => &["join_rule"], + TimelineEventType::RoomPowerLevels => &[ "ban", "events", "events_default", @@ -66,7 +66,7 @@ impl PduEvent { "users", "users_default", ], - RoomEventType::RoomHistoryVisibility => &["history_visibility"], + TimelineEventType::RoomHistoryVisibility => &["history_visibility"], _ => &[], }; @@ -296,7 +296,7 @@ impl state_res::Event for PduEvent { &self.sender } - fn event_type(&self) -> &RoomEventType { + fn event_type(&self) -> &TimelineEventType { &self.kind } @@ -372,7 +372,7 @@ pub(crate) fn gen_event_id_canonical_json( #[derive(Debug, Deserialize)] pub struct PduBuilder { #[serde(rename = "type")] - pub event_type: RoomEventType, + pub event_type: TimelineEventType, pub content: Box, pub unsigned: Option>, pub state_key: Option, diff --git a/src/service/pusher/mod.rs b/src/service/pusher/mod.rs index ba096a2..5933c03 100644 --- a/src/service/pusher/mod.rs +++ b/src/service/pusher/mod.rs @@ -15,7 +15,7 @@ use ruma::{ }, events::{ room::{name::RoomNameEventContent, power_levels::RoomPowerLevelsEventContent}, - RoomEventType, StateEventType, + StateEventType, TimelineEventType, }, push::{Action, PushConditionRoomCtx, PushFormat, Ruleset, Tweak}, serde::Raw, @@ -169,6 +169,7 @@ impl Service { tweaks.push(tweak.clone()); continue; } + _ => false, }; if notify.is_some() { @@ -248,7 +249,7 @@ impl Service { // TODO: missed calls notifi.counts = NotificationCounts::new(unread, uint!(0)); - if event.kind == RoomEventType::RoomEncrypted + if event.kind == TimelineEventType::RoomEncrypted || tweaks .iter() .any(|t| matches!(t, Tweak::Highlight(true) | Tweak::Sound(_))) @@ -264,7 +265,7 @@ impl Service { notifi.event_type = Some(event.kind.clone()); notifi.content = serde_json::value::to_raw_value(&event.content).ok(); - if event.kind == RoomEventType::RoomMember { + if event.kind == TimelineEventType::RoomMember { notifi.user_is_target = event.state_key.as_deref() == Some(event.sender.as_str()); } diff --git a/src/service/rooms/state/mod.rs b/src/service/rooms/state/mod.rs index 3072b80..21ad2f9 100644 --- a/src/service/rooms/state/mod.rs +++ b/src/service/rooms/state/mod.rs @@ -8,7 +8,7 @@ pub use data::Data; use ruma::{ events::{ room::{create::RoomCreateEventContent, member::MembershipState}, - AnyStrippedStateEvent, RoomEventType, StateEventType, + AnyStrippedStateEvent, StateEventType, TimelineEventType, }, serde::Raw, state_res::{self, StateMap}, @@ -358,7 +358,7 @@ impl Service { pub fn get_auth_events( &self, room_id: &RoomId, - kind: &RoomEventType, + kind: &TimelineEventType, sender: &UserId, state_key: Option<&str>, content: &serde_json::value::RawValue, diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 47f4c65..99c5876 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -1,20 +1,19 @@ mod data; -use std::cmp::Ordering; -use std::collections::{BTreeMap, HashMap}; +use std::{ + cmp::Ordering, + collections::{BTreeMap, HashMap}, +}; -use std::sync::RwLock; use std::{ collections::HashSet, - sync::{Arc, Mutex}, + sync::{Arc, Mutex, RwLock}, }; pub use data::Data; use regex::Regex; -use ruma::api::federation; -use ruma::serde::Base64; use ruma::{ - api::client::error::ErrorKind, + api::{client::error::ErrorKind, federation}, canonical_json::to_canonical_value, events::{ push_rules::PushRulesEvent, @@ -22,23 +21,22 @@ use ruma::{ create::RoomCreateEventContent, member::MembershipState, power_levels::RoomPowerLevelsEventContent, }, - GlobalAccountDataEventType, RoomEventType, StateEventType, + GlobalAccountDataEventType, StateEventType, TimelineEventType, }, push::{Action, Ruleset, Tweak}, + serde::Base64, state_res, - state_res::Event, - state_res::RoomVersion, - uint, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, - OwnedServerName, RoomAliasId, RoomId, UserId, + state_res::{Event, RoomVersion}, + uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId, + OwnedServerName, RoomAliasId, RoomId, ServerName, UserId, }; -use ruma::{user_id, ServerName}; use serde::Deserialize; use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; use tokio::sync::MutexGuard; use tracing::{error, info, warn}; -use crate::api::server_server; use crate::{ + api::server_server, service::pdu::{EventHash, PduBuilder}, services, utils, Error, PduEvent, Result, }; @@ -381,12 +379,12 @@ impl Service { .increment_notification_counts(&pdu.room_id, notifies, highlights)?; match pdu.kind { - RoomEventType::RoomRedaction => { + TimelineEventType::RoomRedaction => { if let Some(redact_id) = &pdu.redacts { self.redact_pdu(redact_id, pdu)?; } } - RoomEventType::RoomMember => { + TimelineEventType::RoomMember => { if let Some(state_key) = &pdu.state_key { #[derive(Deserialize)] struct ExtractMembership { @@ -420,7 +418,7 @@ impl Service { )?; } } - RoomEventType::RoomMessage => { + TimelineEventType::RoomMessage => { #[derive(Deserialize)] struct ExtractBody { body: Option, @@ -472,7 +470,7 @@ impl Service { // If the RoomMember event has a non-empty state_key, it is targeted at someone. // If it is our appservice user, we send this PDU to it. - if pdu.kind == RoomEventType::RoomMember { + if pdu.kind == TimelineEventType::RoomMember { if let Some(state_key_uid) = &pdu .state_key .as_ref() @@ -522,7 +520,7 @@ impl Service { let matching_users = |users: &Regex| { users.is_match(pdu.sender.as_str()) - || pdu.kind == RoomEventType::RoomMember + || pdu.kind == TimelineEventType::RoomMember && pdu .state_key .as_ref() @@ -756,14 +754,14 @@ impl Service { )?; if admin_room.filter(|v| v == room_id).is_some() { match pdu.event_type() { - RoomEventType::RoomEncryption => { + 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.", )); } - RoomEventType::RoomMember => { + TimelineEventType::RoomMember => { #[derive(Deserialize)] struct ExtractMembership { membership: MembershipState, @@ -862,7 +860,7 @@ impl Service { .collect(); // In case we are kicking or banning a user, we need to inform their server of the change - if pdu.kind == RoomEventType::RoomMember { + if pdu.kind == TimelineEventType::RoomMember { if let Some(state_key_uid) = &pdu .state_key .as_ref() @@ -1100,7 +1098,7 @@ impl Service { drop(insert_lock); match pdu.kind { - RoomEventType::RoomMessage => { + TimelineEventType::RoomMessage => { #[derive(Deserialize)] struct ExtractBody { body: Option, From 4635644e21cfdefd076d011d4f747b37d10da5b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Sun, 26 Feb 2023 16:55:42 +0100 Subject: [PATCH 2/4] Use the ruma methods for managing rulesets --- src/api/client_server/push.rs | 316 +++++++++------------------------- 1 file changed, 80 insertions(+), 236 deletions(-) diff --git a/src/api/client_server/push.rs b/src/api/client_server/push.rs index b044138..ab7c686 100644 --- a/src/api/client_server/push.rs +++ b/src/api/client_server/push.rs @@ -5,11 +5,11 @@ use ruma::{ push::{ delete_pushrule, get_pushers, get_pushrule, get_pushrule_actions, get_pushrule_enabled, get_pushrules_all, set_pusher, set_pushrule, set_pushrule_actions, - set_pushrule_enabled, RuleKind, RuleScope, + set_pushrule_enabled, RuleScope, }, }, events::{push_rules::PushRulesEvent, GlobalAccountDataEventType}, - push::{ConditionalPushRuleInit, NewPushRule, PatternedPushRuleInit, SimplePushRuleInit}, + push::{InsertPushRuleError, RemovePushRuleError}, }; /// # `GET /_matrix/client/r0/pushrules` @@ -65,30 +65,10 @@ pub async fn get_pushrule_route( .map_err(|_| Error::bad_database("Invalid account data event in db."))? .content; - let global = account_data.global; - let rule = match body.kind { - RuleKind::Override => global - .override_ - .get(body.rule_id.as_str()) - .map(|rule| rule.clone().into()), - RuleKind::Underride => global - .underride - .get(body.rule_id.as_str()) - .map(|rule| rule.clone().into()), - RuleKind::Sender => global - .sender - .get(body.rule_id.as_str()) - .map(|rule| rule.clone().into()), - RuleKind::Room => global - .room - .get(body.rule_id.as_str()) - .map(|rule| rule.clone().into()), - RuleKind::Content => global - .content - .get(body.rule_id.as_str()) - .map(|rule| rule.clone().into()), - _ => None, - }; + let rule = account_data + .global + .get(body.kind.clone(), &body.rule_id) + .map(Into::into); if let Some(rule) = rule { Ok(get_pushrule::v3::Response { rule }) @@ -131,66 +111,36 @@ pub async fn set_pushrule_route( let mut account_data = serde_json::from_str::(event.get()) .map_err(|_| Error::bad_database("Invalid account data event in db."))?; - let global = &mut account_data.content.global; - match body.rule { - NewPushRule::Override(rule) => { - global.override_.replace( - ConditionalPushRuleInit { - actions: rule.actions, - default: false, - enabled: true, - rule_id: rule.rule_id, - conditions: rule.conditions, - } - .into(), - ); - } - NewPushRule::Underride(rule) => { - global.underride.replace( - ConditionalPushRuleInit { - actions: rule.actions, - default: false, - enabled: true, - rule_id: rule.rule_id, - conditions: rule.conditions, - } - .into(), - ); - } - NewPushRule::Sender(rule) => { - global.sender.replace( - SimplePushRuleInit { - actions: rule.actions, - default: false, - enabled: true, - rule_id: rule.rule_id, - } - .into(), - ); - } - NewPushRule::Room(rule) => { - global.room.replace( - SimplePushRuleInit { - actions: rule.actions, - default: false, - enabled: true, - rule_id: rule.rule_id, - } - .into(), - ); - } - NewPushRule::Content(rule) => { - global.content.replace( - PatternedPushRuleInit { - actions: rule.actions, - default: false, - enabled: true, - rule_id: rule.rule_id, - pattern: rule.pattern, - } - .into(), - ); - } + if let Err(error) = account_data.content.global.insert( + body.rule.clone(), + body.after.as_deref(), + body.before.as_deref(), + ) { + let err = match error { + InsertPushRuleError::ServerDefaultRuleId => Error::BadRequest( + ErrorKind::InvalidParam, + "Rule IDs starting with a dot are reserved for server-default rules.", + ), + InsertPushRuleError::InvalidRuleId => Error::BadRequest( + ErrorKind::InvalidParam, + "Rule ID containing invalid characters.", + ), + InsertPushRuleError::RelativeToServerDefaultRule => Error::BadRequest( + ErrorKind::InvalidParam, + "Can't place a push rule relatively to a server-default rule.", + ), + InsertPushRuleError::UnknownRuleId => Error::BadRequest( + ErrorKind::NotFound, + "The before or after rule could not be found.", + ), + InsertPushRuleError::BeforeHigherThanAfter => Error::BadRequest( + ErrorKind::InvalidParam, + "The before rule has a higher priority than the after rule.", + ), + _ => Error::BadRequest(ErrorKind::InvalidParam, "Invalid data."), + }; + + return Err(err); } services().account_data.update( @@ -235,29 +185,9 @@ pub async fn get_pushrule_actions_route( .content; let global = account_data.global; - let actions = match body.kind { - RuleKind::Override => global - .override_ - .get(body.rule_id.as_str()) - .map(|rule| rule.actions.clone()), - RuleKind::Underride => global - .underride - .get(body.rule_id.as_str()) - .map(|rule| rule.actions.clone()), - RuleKind::Sender => global - .sender - .get(body.rule_id.as_str()) - .map(|rule| rule.actions.clone()), - RuleKind::Room => global - .room - .get(body.rule_id.as_str()) - .map(|rule| rule.actions.clone()), - RuleKind::Content => global - .content - .get(body.rule_id.as_str()) - .map(|rule| rule.actions.clone()), - _ => None, - }; + let actions = global + .get(body.kind.clone(), &body.rule_id) + .map(|rule| rule.actions().to_owned()); Ok(get_pushrule_actions::v3::Response { actions: actions.unwrap_or_default(), @@ -294,40 +224,17 @@ pub async fn set_pushrule_actions_route( let mut account_data = serde_json::from_str::(event.get()) .map_err(|_| Error::bad_database("Invalid account data event in db."))?; - let global = &mut account_data.content.global; - match body.kind { - RuleKind::Override => { - if let Some(mut rule) = global.override_.get(body.rule_id.as_str()).cloned() { - rule.actions = body.actions.clone(); - global.override_.replace(rule); - } - } - RuleKind::Underride => { - if let Some(mut rule) = global.underride.get(body.rule_id.as_str()).cloned() { - rule.actions = body.actions.clone(); - global.underride.replace(rule); - } - } - RuleKind::Sender => { - if let Some(mut rule) = global.sender.get(body.rule_id.as_str()).cloned() { - rule.actions = body.actions.clone(); - global.sender.replace(rule); - } - } - RuleKind::Room => { - if let Some(mut rule) = global.room.get(body.rule_id.as_str()).cloned() { - rule.actions = body.actions.clone(); - global.room.replace(rule); - } - } - RuleKind::Content => { - if let Some(mut rule) = global.content.get(body.rule_id.as_str()).cloned() { - rule.actions = body.actions.clone(); - global.content.replace(rule); - } - } - _ => {} - }; + if account_data + .content + .global + .set_actions(body.kind.clone(), &body.rule_id, body.actions.clone()) + .is_err() + { + return Err(Error::BadRequest( + ErrorKind::NotFound, + "Push rule not found.", + )); + } services().account_data.update( None, @@ -370,34 +277,10 @@ pub async fn get_pushrule_enabled_route( .map_err(|_| Error::bad_database("Invalid account data event in db."))?; let global = account_data.content.global; - let enabled = match body.kind { - RuleKind::Override => global - .override_ - .iter() - .find(|rule| rule.rule_id == body.rule_id) - .map_or(false, |rule| rule.enabled), - RuleKind::Underride => global - .underride - .iter() - .find(|rule| rule.rule_id == body.rule_id) - .map_or(false, |rule| rule.enabled), - RuleKind::Sender => global - .sender - .iter() - .find(|rule| rule.rule_id == body.rule_id) - .map_or(false, |rule| rule.enabled), - RuleKind::Room => global - .room - .iter() - .find(|rule| rule.rule_id == body.rule_id) - .map_or(false, |rule| rule.enabled), - RuleKind::Content => global - .content - .iter() - .find(|rule| rule.rule_id == body.rule_id) - .map_or(false, |rule| rule.enabled), - _ => false, - }; + let enabled = global + .get(body.kind.clone(), &body.rule_id) + .map(|r| r.enabled()) + .unwrap_or_default(); Ok(get_pushrule_enabled::v3::Response { enabled }) } @@ -432,44 +315,16 @@ pub async fn set_pushrule_enabled_route( let mut account_data = serde_json::from_str::(event.get()) .map_err(|_| Error::bad_database("Invalid account data event in db."))?; - let global = &mut account_data.content.global; - match body.kind { - RuleKind::Override => { - if let Some(mut rule) = global.override_.get(body.rule_id.as_str()).cloned() { - global.override_.remove(&rule); - rule.enabled = body.enabled; - global.override_.insert(rule); - } - } - RuleKind::Underride => { - if let Some(mut rule) = global.underride.get(body.rule_id.as_str()).cloned() { - global.underride.remove(&rule); - rule.enabled = body.enabled; - global.underride.insert(rule); - } - } - RuleKind::Sender => { - if let Some(mut rule) = global.sender.get(body.rule_id.as_str()).cloned() { - global.sender.remove(&rule); - rule.enabled = body.enabled; - global.sender.insert(rule); - } - } - RuleKind::Room => { - if let Some(mut rule) = global.room.get(body.rule_id.as_str()).cloned() { - global.room.remove(&rule); - rule.enabled = body.enabled; - global.room.insert(rule); - } - } - RuleKind::Content => { - if let Some(mut rule) = global.content.get(body.rule_id.as_str()).cloned() { - global.content.remove(&rule); - rule.enabled = body.enabled; - global.content.insert(rule); - } - } - _ => {} + if account_data + .content + .global + .set_enabled(body.kind.clone(), &body.rule_id, body.enabled) + .is_err() + { + return Err(Error::BadRequest( + ErrorKind::NotFound, + "Push rule not found.", + )); } services().account_data.update( @@ -512,34 +367,23 @@ pub async fn delete_pushrule_route( let mut account_data = serde_json::from_str::(event.get()) .map_err(|_| Error::bad_database("Invalid account data event in db."))?; - let global = &mut account_data.content.global; - match body.kind { - RuleKind::Override => { - if let Some(rule) = global.override_.get(body.rule_id.as_str()).cloned() { - global.override_.remove(&rule); + if let Err(error) = account_data + .content + .global + .remove(body.kind.clone(), &body.rule_id) + { + let err = match error { + RemovePushRuleError::ServerDefault => Error::BadRequest( + ErrorKind::InvalidParam, + "Cannot delete a server-default pushrule.", + ), + RemovePushRuleError::NotFound => { + Error::BadRequest(ErrorKind::NotFound, "Push rule not found.") } - } - RuleKind::Underride => { - if let Some(rule) = global.underride.get(body.rule_id.as_str()).cloned() { - global.underride.remove(&rule); - } - } - RuleKind::Sender => { - if let Some(rule) = global.sender.get(body.rule_id.as_str()).cloned() { - global.sender.remove(&rule); - } - } - RuleKind::Room => { - if let Some(rule) = global.room.get(body.rule_id.as_str()).cloned() { - global.room.remove(&rule); - } - } - RuleKind::Content => { - if let Some(rule) = global.content.get(body.rule_id.as_str()).cloned() { - global.content.remove(&rule); - } - } - _ => {} + _ => Error::BadRequest(ErrorKind::InvalidParam, "Invalid data."), + }; + + return Err(err); } services().account_data.update( From 88c6bf75954ead182fffc900585b418b018e98e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Sun, 26 Feb 2023 17:49:42 +0100 Subject: [PATCH 3/4] Always return an error if a push rule is not found --- src/api/client_server/push.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/api/client_server/push.rs b/src/api/client_server/push.rs index ab7c686..7276866 100644 --- a/src/api/client_server/push.rs +++ b/src/api/client_server/push.rs @@ -187,11 +187,13 @@ pub async fn get_pushrule_actions_route( let global = account_data.global; let actions = global .get(body.kind.clone(), &body.rule_id) - .map(|rule| rule.actions().to_owned()); + .map(|rule| rule.actions().to_owned()) + .ok_or(Error::BadRequest( + ErrorKind::NotFound, + "Push rule not found.", + ))?; - Ok(get_pushrule_actions::v3::Response { - actions: actions.unwrap_or_default(), - }) + Ok(get_pushrule_actions::v3::Response { actions }) } /// # `PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/actions` @@ -280,7 +282,10 @@ pub async fn get_pushrule_enabled_route( let enabled = global .get(body.kind.clone(), &body.rule_id) .map(|r| r.enabled()) - .unwrap_or_default(); + .ok_or(Error::BadRequest( + ErrorKind::NotFound, + "Push rule not found.", + ))?; Ok(get_pushrule_enabled::v3::Response { enabled }) } From 1929ca5d9d8d8b43a2f3fcce7af19e197f93f562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Commaille?= Date: Sun, 26 Feb 2023 17:57:44 +0100 Subject: [PATCH 4/4] Add a database migration to fix and update the default pushrules --- src/database/mod.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index e05991d..1415f68 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -411,7 +411,7 @@ impl KeyValueDatabase { } // If the database has any data, perform data migrations before starting - let latest_database_version = 12; + let latest_database_version = 13; if services().users.count()? > 0 { // MIGRATIONS @@ -880,6 +880,52 @@ impl KeyValueDatabase { warn!("Migration: 11 -> 12 finished"); } + // This migration can be reused as-is anytime the server-default rules are updated. + if services().globals.database_version()? < 13 { + for username in services().users.list_local_users()? { + let user = match UserId::parse_with_server_name( + username.clone(), + services().globals.server_name(), + ) { + Ok(u) => u, + Err(e) => { + warn!("Invalid username {username}: {e}"); + continue; + } + }; + + let raw_rules_list = services() + .account_data + .get( + None, + &user, + GlobalAccountDataEventType::PushRules.to_string().into(), + ) + .unwrap() + .expect("Username is invalid"); + + let mut account_data = + serde_json::from_str::(raw_rules_list.get()).unwrap(); + + let user_default_rules = ruma::push::Ruleset::server_default(&user); + account_data + .content + .global + .update_with_server_default(user_default_rules); + + services().account_data.update( + None, + &user, + GlobalAccountDataEventType::PushRules.to_string().into(), + &serde_json::to_value(account_data).expect("to json value always works"), + )?; + } + + services().globals.bump_database_version(13)?; + + warn!("Migration: 12 -> 13 finished"); + } + assert_eq!( services().globals.database_version().unwrap(), latest_database_version