From 489cbc0a930ab632a96e7fde6432875976f4d912 Mon Sep 17 00:00:00 2001 From: timokoesters Date: Mon, 27 Jul 2020 17:36:54 +0200 Subject: [PATCH] refactor: use <_> instead of <_parameter_name> --- Cargo.lock | 28 +- Cargo.toml | 7 +- src/client_server.rs | 670 ++++++++++++++++++------------------------ src/database.rs | 77 ++++- src/database/rooms.rs | 20 +- src/main.rs | 2 +- src/ruma_wrapper.rs | 6 +- 7 files changed, 407 insertions(+), 403 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45a5edd..37a620b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -275,6 +275,7 @@ dependencies = [ "serde_json", "sled", "thiserror", + "tokio", ] [[package]] @@ -1484,7 +1485,6 @@ dependencies = [ [[package]] name = "rocket" version = "0.5.0-dev" -source = "git+https://github.com/SergioBenitez/Rocket.git?rev=8d779caa22c63b15a6c3ceb75d8f6d4971b2eb67#8d779caa22c63b15a6c3ceb75d8f6d4971b2eb67" dependencies = [ "async-trait", "atomic", @@ -1509,7 +1509,6 @@ dependencies = [ [[package]] name = "rocket_codegen" version = "0.5.0-dev" -source = "git+https://github.com/SergioBenitez/Rocket.git?rev=8d779caa22c63b15a6c3ceb75d8f6d4971b2eb67#8d779caa22c63b15a6c3ceb75d8f6d4971b2eb67" dependencies = [ "devise", "glob", @@ -1521,7 +1520,6 @@ dependencies = [ [[package]] name = "rocket_http" version = "0.5.0-dev" -source = "git+https://github.com/SergioBenitez/Rocket.git?rev=8d779caa22c63b15a6c3ceb75d8f6d4971b2eb67#8d779caa22c63b15a6c3ceb75d8f6d4971b2eb67" dependencies = [ "cookie", "http", @@ -1543,7 +1541,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.1.0" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "ruma-api", "ruma-client-api", @@ -1558,7 +1556,7 @@ dependencies = [ [[package]] name = "ruma-api" version = "0.16.1" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "http", "percent-encoding", @@ -1573,7 +1571,7 @@ dependencies = [ [[package]] name = "ruma-api-macros" version = "0.16.1" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "proc-macro2", "quote", @@ -1583,7 +1581,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "http", "js_int", @@ -1600,7 +1598,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.2.0" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "js_int", "ruma-serde", @@ -1612,7 +1610,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.21.3" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "js_int", "ruma-common", @@ -1627,7 +1625,7 @@ dependencies = [ [[package]] name = "ruma-events-macros" version = "0.21.3" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "proc-macro2", "quote", @@ -1637,7 +1635,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.0.2" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "js_int", "ruma-api", @@ -1652,7 +1650,7 @@ dependencies = [ [[package]] name = "ruma-identifiers" version = "0.17.1" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "rand", "serde", @@ -1662,7 +1660,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-macros" version = "0.17.1" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "proc-macro2", "quote", @@ -1673,7 +1671,7 @@ dependencies = [ [[package]] name = "ruma-serde" version = "0.2.2" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "form_urlencoded", "itoa", @@ -1685,7 +1683,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.6.0-dev.1" -source = "git+https://github.com/ruma/ruma?rev=e047c647ddcb368e7eb1e05ae8823a9494273457#e047c647ddcb368e7eb1e05ae8823a9494273457" +source = "git+https://github.com/ruma/ruma?rev=d5d2d1d893fa12d27960e4c58d6c09b215d06e95#d5d2d1d893fa12d27960e4c58d6c09b215d06e95" dependencies = [ "base64 0.12.3", "ring", diff --git a/Cargo.toml b/Cargo.toml index 02a90cd..e5df8dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,8 +13,11 @@ edition = "2018" [dependencies] # TODO: This can become optional as soon as proper configs are supported -rocket = { git = "https://github.com/SergioBenitez/Rocket.git", rev = "8d779caa22c63b15a6c3ceb75d8f6d4971b2eb67", features = ["tls"], optional = false } # Used to handle requests -ruma = { git = "https://github.com/ruma/ruma", features = ["rand", "client-api", "federation-api", "unstable-pre-spec", "unstable-synapse-quirks"], rev = "e047c647ddcb368e7eb1e05ae8823a9494273457" } # Used for matrix spec type definitions and helpers +#rocket = { git = "https://github.com/SergioBenitez/Rocket.git", rev = "8d779caa22c63b15a6c3ceb75d8f6d4971b2eb67", features = ["tls"] } # Used to handle requests +rocket = { path = "../rocket/core/lib", features = ["tls"] } + +tokio = "0.2.22" # Used for long polling +ruma = { git = "https://github.com/ruma/ruma", features = ["rand", "client-api", "federation-api", "unstable-pre-spec", "unstable-synapse-quirks"], rev = "d5d2d1d893fa12d27960e4c58d6c09b215d06e95" } # Used for matrix spec type definitions and helpers sled = "0.32.0" # Used for storing data permanently log = "0.4.8" # Used for emitting log entries http = "0.2.1" # Used for rocket<->ruma conversions diff --git a/src/client_server.rs b/src/client_server.rs index c5bba03..baeb839 100644 --- a/src/client_server.rs +++ b/src/client_server.rs @@ -11,7 +11,7 @@ use log::warn; #[cfg(not(feature = "conduit_bin"))] use super::State; #[cfg(feature = "conduit_bin")] -use rocket::{delete, get, options, post, put, State}; +use rocket::{delete, get, options, post, put, State, tokio}; use ruma::{ api::client::{ @@ -312,10 +312,10 @@ pub fn logout_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let device_id = body.device_id.as_ref().expect("user is authenticated"); - db.users.remove_device(&user_id, device_id)?; + db.users.remove_device(&sender_id, device_id)?; Ok(logout::Response.into()) } @@ -328,11 +328,11 @@ pub fn logout_all_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - for device_id in db.users.all_device_ids(user_id) { + for device_id in db.users.all_device_ids(sender_id) { if let Ok(device_id) = device_id { - db.users.remove_device(&user_id, &device_id)?; + db.users.remove_device(&sender_id, &device_id)?; } } @@ -347,7 +347,7 @@ pub fn change_password_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let device_id = body.device_id.as_ref().expect("user is authenticated"); let mut uiaainfo = UiaaInfo { @@ -363,29 +363,29 @@ pub fn change_password_route( if let Some(auth) = &body.auth { let (worked, uiaainfo) = db.uiaa - .try_auth(&user_id, device_id, auth, &uiaainfo, &db.users, &db.globals)?; + .try_auth(&sender_id, device_id, auth, &uiaainfo, &db.users, &db.globals)?; if !worked { return Err(Error::Uiaa(uiaainfo)); } // Success! } else { uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH)); - db.uiaa.create(&user_id, &device_id, &uiaainfo)?; + db.uiaa.create(&sender_id, &device_id, &uiaainfo)?; return Err(Error::Uiaa(uiaainfo)); } - db.users.set_password(&user_id, &body.new_password)?; + db.users.set_password(&sender_id, &body.new_password)?; // TODO: Read logout_devices field when it's available and respect that, currently not supported in Ruma // See: https://github.com/ruma/ruma/issues/107 // Logout all devices except the current one for id in db .users - .all_device_ids(&user_id) + .all_device_ids(&sender_id) .filter_map(|id| id.ok()) .filter(|id| id != device_id) { - db.users.remove_device(&user_id, &id)?; + db.users.remove_device(&sender_id, &id)?; } Ok(change_password::Response.into()) @@ -399,7 +399,7 @@ pub fn deactivate_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let device_id = body.device_id.as_ref().expect("user is authenticated"); let mut uiaainfo = UiaaInfo { @@ -414,7 +414,7 @@ pub fn deactivate_route( if let Some(auth) = &body.auth { let (worked, uiaainfo) = db.uiaa.try_auth( - &user_id, + &sender_id, &device_id, auth, &uiaainfo, @@ -427,15 +427,15 @@ pub fn deactivate_route( // Success! } else { uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH)); - db.uiaa.create(&user_id, &device_id, &uiaainfo)?; + db.uiaa.create(&sender_id, &device_id, &uiaainfo)?; return Err(Error::Uiaa(uiaainfo)); } // Leave all joined rooms and reject all invitations for room_id in db .rooms - .rooms_joined(&user_id) - .chain(db.rooms.rooms_invited(&user_id)) + .rooms_joined(&sender_id) + .chain(db.rooms.rooms_invited(&sender_id)) { let room_id = room_id?; let event = member::MemberEventContent { @@ -448,18 +448,18 @@ pub fn deactivate_route( db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomMember, serde_json::to_value(event).expect("event is valid, we just created it"), None, - Some(user_id.to_string()), + Some(sender_id.to_string()), None, &db.globals, )?; } // Remove devices and mark account as deactivated - db.users.deactivate_account(&user_id)?; + db.users.deactivate_account(&sender_id)?; Ok(deactivate::Response { id_server_unbind_result: ThirdPartyIdRemovalStatus::NoSupport, @@ -500,11 +500,11 @@ pub fn get_pushrules_all_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let event = db .account_data - .get::(None, &user_id, EventType::PushRules)? + .get::(None, &sender_id, EventType::PushRules)? .ok_or(Error::BadRequest( ErrorKind::NotFound, "PushRules event not found.", @@ -517,15 +517,12 @@ pub fn get_pushrules_all_route( } #[cfg_attr(feature = "conduit_bin", put( - "/_matrix/client/r0/pushrules/<_scope>/<_kind>/<_rule_id>", + "/_matrix/client/r0/pushrules/<_>/<_>/<_>", //data = "" ))] pub fn set_pushrule_route( //db: State<'_, Database>, //body: Ruma, - _scope: String, - _kind: String, - _rule_id: String, ) -> ConduitResult { // TODO warn!("TODO: set_pushrule_route"); @@ -534,12 +531,9 @@ pub fn set_pushrule_route( #[cfg_attr( feature = "conduit_bin", - put("/_matrix/client/r0/pushrules/<_scope>/<_kind>/<_rule_id>/enabled") + put("/_matrix/client/r0/pushrules/<_>/<_>/<_>/enabled") )] pub fn set_pushrule_enabled_route( - _scope: String, - _kind: String, - _rule_id: String, ) -> ConduitResult { // TODO warn!("TODO: set_pushrule_enabled_route"); @@ -548,11 +542,9 @@ pub fn set_pushrule_enabled_route( #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/user/<_user_id>/filter/<_filter_id>") + get("/_matrix/client/r0/user/<_>/filter/<_>") )] pub fn get_filter_route( - _user_id: String, - _filter_id: String, ) -> ConduitResult { // TODO Ok(get_filter::Response { @@ -569,9 +561,9 @@ pub fn get_filter_route( #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/user/<_user_id>/filter") + post("/_matrix/client/r0/user/<_>/filter") )] -pub fn create_filter_route(_user_id: String) -> ConduitResult { +pub fn create_filter_route() -> ConduitResult { // TODO Ok(create_filter::Response { filter_id: utils::random_string(10), @@ -582,17 +574,15 @@ pub fn create_filter_route(_user_id: String) -> ConduitResult/account_data/<_type>", + "/_matrix/client/r0/user/<_>/account_data/<_>", data = "" ) )] pub fn set_global_account_data_route( db: State<'_, Database>, body: Ruma, - _user_id: String, - _type: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let content = serde_json::from_str::(body.data.get()) .map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Data is invalid."))?; @@ -601,7 +591,7 @@ pub fn set_global_account_data_route( db.account_data.update( None, - user_id, + sender_id, event_type.clone().into(), &BasicEvent { content: CustomEventContent { @@ -618,23 +608,21 @@ pub fn set_global_account_data_route( #[cfg_attr( feature = "conduit_bin", get( - "/_matrix/client/r0/user/<_user_id>/account_data/<_type>", + "/_matrix/client/r0/user/<_>/account_data/<_>", data = "" ) )] pub fn get_global_account_data_route( db: State<'_, Database>, body: Ruma, - _user_id: String, - _type: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let data = db .account_data .get::( None, - user_id, + sender_id, EventType::try_from(&body.event_type).expect("EventType::try_from can never fail"), )? .ok_or(Error::BadRequest(ErrorKind::NotFound, "Data not found."))?; @@ -647,30 +635,29 @@ pub fn get_global_account_data_route( #[cfg_attr( feature = "conduit_bin", - put("/_matrix/client/r0/profile/<_user_id>/displayname", data = "") + put("/_matrix/client/r0/profile/<_>/displayname", data = "") )] pub fn set_displayname_route( db: State<'_, Database>, body: Ruma, - _user_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); db.users - .set_displayname(&user_id, body.displayname.clone())?; + .set_displayname(&sender_id, body.displayname.clone())?; // Send a new membership event into all joined rooms - for room_id in db.rooms.rooms_joined(&user_id) { + for room_id in db.rooms.rooms_joined(&sender_id) { let room_id = room_id?; db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomMember, serde_json::to_value(ruma::events::room::member::MemberEventContent { displayname: body.displayname.clone(), ..serde_json::from_value::>( db.rooms - .room_state_get(&room_id, &EventType::RoomMember, &user_id.to_string())? + .room_state_get(&room_id, &EventType::RoomMember, &sender_id.to_string())? .ok_or_else(|| { Error::bad_database( "Tried to send displayname update for user not in the room.", @@ -685,7 +672,7 @@ pub fn set_displayname_route( }) .expect("event is valid, we just created it"), None, - Some(user_id.to_string()), + Some(sender_id.to_string()), None, &db.globals, )?; @@ -695,9 +682,9 @@ pub fn set_displayname_route( db.global_edus.update_presence( ruma::events::presence::PresenceEvent { content: ruma::events::presence::PresenceEventContent { - avatar_url: db.users.avatar_url(&user_id)?, + avatar_url: db.users.avatar_url(&sender_id)?, currently_active: None, - displayname: db.users.displayname(&user_id)?, + displayname: db.users.displayname(&sender_id)?, last_active_ago: Some( utils::millis_since_unix_epoch() .try_into() @@ -706,7 +693,7 @@ pub fn set_displayname_route( presence: ruma::presence::PresenceState::Online, status_msg: None, }, - sender: user_id.clone(), + sender: sender_id.clone(), }, &db.globals, )?; @@ -716,30 +703,27 @@ pub fn set_displayname_route( #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/profile/<_user_id>/displayname", data = "") + get("/_matrix/client/r0/profile/<_>/displayname", data = "") )] pub fn get_displayname_route( db: State<'_, Database>, body: Ruma, - _user_id: String, ) -> ConduitResult { - let user_id = body.body.user_id.clone(); Ok(get_display_name::Response { - displayname: db.users.displayname(&user_id)?, + displayname: db.users.displayname(&body.user_id)?, } .into()) } #[cfg_attr( feature = "conduit_bin", - put("/_matrix/client/r0/profile/<_user_id>/avatar_url", data = "") + put("/_matrix/client/r0/profile/<_>/avatar_url", data = "") )] pub fn set_avatar_url_route( db: State<'_, Database>, body: Ruma, - _user_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); if let Some(avatar_url) = &body.avatar_url { if !avatar_url.starts_with("mxc://") { @@ -753,20 +737,20 @@ pub fn set_avatar_url_route( // TODO also make sure this is valid mxc:// format (not only starting with it) } - db.users.set_avatar_url(&user_id, body.avatar_url.clone())?; + db.users.set_avatar_url(&sender_id, body.avatar_url.clone())?; // Send a new membership event into all joined rooms - for room_id in db.rooms.rooms_joined(&user_id) { + for room_id in db.rooms.rooms_joined(&sender_id) { let room_id = room_id?; db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomMember, serde_json::to_value(ruma::events::room::member::MemberEventContent { avatar_url: body.avatar_url.clone(), ..serde_json::from_value::>( db.rooms - .room_state_get(&room_id, &EventType::RoomMember, &user_id.to_string())? + .room_state_get(&room_id, &EventType::RoomMember, &sender_id.to_string())? .ok_or_else(|| { Error::bad_database( "Tried to send avatar url update for user not in the room.", @@ -781,7 +765,7 @@ pub fn set_avatar_url_route( }) .expect("event is valid, we just created it"), None, - Some(user_id.to_string()), + Some(sender_id.to_string()), None, &db.globals, )?; @@ -791,9 +775,9 @@ pub fn set_avatar_url_route( db.global_edus.update_presence( ruma::events::presence::PresenceEvent { content: ruma::events::presence::PresenceEventContent { - avatar_url: db.users.avatar_url(&user_id)?, + avatar_url: db.users.avatar_url(&sender_id)?, currently_active: None, - displayname: db.users.displayname(&user_id)?, + displayname: db.users.displayname(&sender_id)?, last_active_ago: Some( utils::millis_since_unix_epoch() .try_into() @@ -802,7 +786,7 @@ pub fn set_avatar_url_route( presence: ruma::presence::PresenceState::Online, status_msg: None, }, - sender: user_id.clone(), + sender: sender_id.clone(), }, &db.globals, )?; @@ -812,32 +796,28 @@ pub fn set_avatar_url_route( #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/profile/<_user_id>/avatar_url", data = "") + get("/_matrix/client/r0/profile/<_>/avatar_url", data = "") )] pub fn get_avatar_url_route( db: State<'_, Database>, body: Ruma, - _user_id: String, ) -> ConduitResult { - let user_id = body.body.user_id.clone(); Ok(get_avatar_url::Response { - avatar_url: db.users.avatar_url(&user_id)?, + avatar_url: db.users.avatar_url(&body.user_id)?, } .into()) } #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/profile/<_user_id>", data = "") + get("/_matrix/client/r0/profile/<_>", data = "") )] pub fn get_profile_route( db: State<'_, Database>, body: Ruma, - _user_id: String, ) -> ConduitResult { - let user_id = body.body.user_id.clone(); - let avatar_url = db.users.avatar_url(&user_id)?; - let displayname = db.users.displayname(&user_id)?; + let avatar_url = db.users.avatar_url(&body.user_id)?; + let displayname = db.users.displayname(&body.user_id)?; if avatar_url.is_none() && displayname.is_none() { // Return 404 if we don't have a profile for this id @@ -856,21 +836,20 @@ pub fn get_profile_route( #[cfg_attr( feature = "conduit_bin", - put("/_matrix/client/r0/presence/<_user_id>/status", data = "") + put("/_matrix/client/r0/presence/<_>/status", data = "") )] pub fn set_presence_route( db: State<'_, Database>, body: Ruma, - _user_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); db.global_edus.update_presence( ruma::events::presence::PresenceEvent { content: ruma::events::presence::PresenceEventContent { - avatar_url: db.users.avatar_url(&user_id)?, + avatar_url: db.users.avatar_url(&sender_id)?, currently_active: None, - displayname: db.users.displayname(&user_id)?, + displayname: db.users.displayname(&sender_id)?, last_active_ago: Some( utils::millis_since_unix_epoch() .try_into() @@ -879,7 +858,7 @@ pub fn set_presence_route( presence: body.presence, status_msg: body.status_msg.clone(), }, - sender: user_id.clone(), + sender: sender_id.clone(), }, &db.globals, )?; @@ -895,26 +874,26 @@ pub fn upload_keys_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let device_id = body.device_id.as_ref().expect("user is authenticated"); if let Some(one_time_keys) = &body.one_time_keys { for (key_key, key_value) in one_time_keys { db.users - .add_one_time_key(user_id, device_id, key_key, key_value)?; + .add_one_time_key(sender_id, device_id, key_key, key_value)?; } } if let Some(device_keys) = &body.device_keys { // This check is needed to assure that signatures are kept - if db.users.get_device_keys(user_id, device_id)?.is_none() { + if db.users.get_device_keys(sender_id, device_id)?.is_none() { db.users - .add_device_keys(user_id, device_id, device_keys, &db.globals)?; + .add_device_keys(sender_id, device_id, device_keys, &db.globals)?; } } Ok(upload_keys::Response { - one_time_key_counts: db.users.count_one_time_keys(user_id, device_id)?, + one_time_key_counts: db.users.count_one_time_keys(sender_id, device_id)?, } .into()) } @@ -927,7 +906,7 @@ pub fn get_keys_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let sender_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let mut master_keys = BTreeMap::new(); let mut self_signing_keys = BTreeMap::new(); @@ -1038,10 +1017,10 @@ pub fn create_backup_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let version = db .key_backups - .create_backup(&user_id, &body.algorithm, &db.globals)?; + .create_backup(&sender_id, &body.algorithm, &db.globals)?; Ok(create_backup::Response { version }.into()) } @@ -1049,18 +1028,17 @@ pub fn create_backup_route( #[cfg_attr( feature = "conduit_bin", put( - "/_matrix/client/unstable/room_keys/version/<_version>", + "/_matrix/client/unstable/room_keys/version/<_>", data = "" ) )] pub fn update_backup_route( db: State<'_, Database>, body: Ruma, - _version: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); db.key_backups - .update_backup(&user_id, &body.version, &body.algorithm, &db.globals)?; + .update_backup(&sender_id, &body.version, &body.algorithm, &db.globals)?; Ok(update_backup::Response.into()) } @@ -1073,11 +1051,11 @@ pub fn get_latest_backup_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let (version, algorithm) = db.key_backups - .get_latest_backup(&user_id)? + .get_latest_backup(&sender_id)? .ok_or(Error::BadRequest( ErrorKind::NotFound, "Key backup does not exist.", @@ -1085,8 +1063,8 @@ pub fn get_latest_backup_route( Ok(get_latest_backup::Response { algorithm, - count: (db.key_backups.count_keys(user_id, &version)? as u32).into(), - etag: db.key_backups.get_etag(user_id, &version)?, + count: (db.key_backups.count_keys(sender_id, &version)? as u32).into(), + etag: db.key_backups.get_etag(sender_id, &version)?, version, } .into()) @@ -1095,19 +1073,18 @@ pub fn get_latest_backup_route( #[cfg_attr( feature = "conduit_bin", get( - "/_matrix/client/unstable/room_keys/version/<_version>", + "/_matrix/client/unstable/room_keys/version/<_>", data = "" ) )] pub fn get_backup_route( db: State<'_, Database>, body: Ruma, - _version: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let algorithm = db.key_backups - .get_backup(&user_id, &body.version)? + .get_backup(&sender_id, &body.version)? .ok_or(Error::BadRequest( ErrorKind::NotFound, "Key backup does not exist.", @@ -1115,8 +1092,8 @@ pub fn get_backup_route( Ok(get_backup::Response { algorithm, - count: (db.key_backups.count_keys(user_id, &body.version)? as u32).into(), - etag: db.key_backups.get_etag(user_id, &body.version)?, + count: (db.key_backups.count_keys(sender_id, &body.version)? as u32).into(), + etag: db.key_backups.get_etag(sender_id, &body.version)?, version: body.version.clone(), } .into()) @@ -1131,12 +1108,12 @@ pub fn add_backup_keys_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); for (room_id, room) in &body.rooms { for (session_id, key_data) in &room.sessions { db.key_backups.add_key( - &user_id, + &sender_id, &body.version, &room_id, &session_id, @@ -1147,8 +1124,8 @@ pub fn add_backup_keys_route( } Ok(add_backup_keys::Response { - count: (db.key_backups.count_keys(user_id, &body.version)? as u32).into(), - etag: db.key_backups.get_etag(user_id, &body.version)?, + count: (db.key_backups.count_keys(sender_id, &body.version)? as u32).into(), + etag: db.key_backups.get_etag(sender_id, &body.version)?, } .into()) } @@ -1161,23 +1138,22 @@ pub fn get_backup_keys_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - let rooms = db.key_backups.get_all(&user_id, &body.version)?; + let rooms = db.key_backups.get_all(&sender_id, &body.version)?; Ok(get_backup_keys::Response { rooms }.into()) } #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/rooms/<_room_id>/read_markers", data = "") + post("/_matrix/client/r0/rooms/<_>/read_markers", data = "") )] pub fn set_read_marker_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let fully_read_event = ruma::events::fully_read::FullyReadEvent { content: ruma::events::fully_read::FullyReadEventContent { @@ -1187,7 +1163,7 @@ pub fn set_read_marker_route( }; db.account_data.update( Some(&body.room_id), - &user_id, + &sender_id, EventType::FullyRead, &fully_read_event, &db.globals, @@ -1196,7 +1172,7 @@ pub fn set_read_marker_route( if let Some(event) = &body.read_receipt { db.rooms.edus.room_read_set( &body.room_id, - &user_id, + &sender_id, db.rooms.get_pdu_count(event)?.ok_or(Error::BadRequest( ErrorKind::InvalidParam, "Event does not exist.", @@ -1205,7 +1181,7 @@ pub fn set_read_marker_route( let mut user_receipts = BTreeMap::new(); user_receipts.insert( - user_id.clone(), + sender_id.clone(), ruma::events::receipt::Receipt { ts: Some(SystemTime::now()), }, @@ -1219,7 +1195,7 @@ pub fn set_read_marker_route( ); db.rooms.edus.roomlatest_update( - &user_id, + &sender_id, &body.room_id, AnyEvent::Ephemeral(AnyEphemeralRoomEvent::Receipt( ruma::events::receipt::ReceiptEvent { @@ -1236,21 +1212,19 @@ pub fn set_read_marker_route( #[cfg_attr( feature = "conduit_bin", put( - "/_matrix/client/r0/rooms/<_room_id>/typing/<_user_id>", + "/_matrix/client/r0/rooms/<_>/typing/<_>", data = "" ) )] pub fn create_typing_event_route( db: State<'_, Database>, body: Ruma, - _room_id: String, - _user_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); if body.typing { db.rooms.edus.roomactive_add( - &user_id, + &sender_id, &body.room_id, body.timeout.map(|d| d.as_millis() as u64).unwrap_or(30000) + utils::millis_since_unix_epoch(), @@ -1259,7 +1233,7 @@ pub fn create_typing_event_route( } else { db.rooms .edus - .roomactive_remove(&user_id, &body.room_id, &db.globals)?; + .roomactive_remove(&sender_id, &body.room_id, &db.globals)?; } Ok(create_typing_event::Response.into()) @@ -1273,7 +1247,7 @@ pub fn create_room_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let room_id = RoomId::new(db.globals.server_name()); @@ -1296,7 +1270,7 @@ pub fn create_room_route( } })?; - let mut content = ruma::events::room::create::CreateEventContent::new(user_id.clone()); + let mut content = ruma::events::room::create::CreateEventContent::new(sender_id.clone()); content.federate = body.creation_content.as_ref().map_or(true, |c| c.federate); content.predecessor = body .creation_content @@ -1307,7 +1281,7 @@ pub fn create_room_route( // 1. The room create event db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomCreate, serde_json::to_value(content).expect("event is valid, we just created it"), None, @@ -1319,18 +1293,18 @@ pub fn create_room_route( // 2. Let the room creator join db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomMember, serde_json::to_value(member::MemberEventContent { membership: member::MembershipState::Join, - displayname: db.users.displayname(&user_id)?, - avatar_url: db.users.avatar_url(&user_id)?, + displayname: db.users.displayname(&sender_id)?, + avatar_url: db.users.avatar_url(&sender_id)?, is_direct: body.is_direct, third_party_invite: None, }) .expect("event is valid, we just created it"), None, - Some(user_id.to_string()), + Some(sender_id.to_string()), None, &db.globals, )?; @@ -1344,9 +1318,9 @@ pub fn create_room_route( // 3. Power levels let mut users = BTreeMap::new(); - users.insert(user_id.clone(), 100.into()); - for invite_user_id in &body.invite { - users.insert(invite_user_id.clone(), 100.into()); + users.insert(sender_id.clone(), 100.into()); + for invite_ in &body.invite { + users.insert(invite_.clone(), 100.into()); } let power_levels_content = if let Some(power_levels) = &body.power_level_content_override { @@ -1372,7 +1346,7 @@ pub fn create_room_route( }; db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomPowerLevels, power_levels_content, None, @@ -1385,7 +1359,7 @@ pub fn create_room_route( // 4.1 Join Rules db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomJoinRules, match preset { create_room::RoomPreset::PublicChat => serde_json::to_value( @@ -1407,7 +1381,7 @@ pub fn create_room_route( // 4.2 History Visibility db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomHistoryVisibility, serde_json::to_value(history_visibility::HistoryVisibilityEventContent::new( history_visibility::HistoryVisibility::Shared, @@ -1422,7 +1396,7 @@ pub fn create_room_route( // 4.3 Guest Access db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomGuestAccess, match preset { create_room::RoomPreset::PublicChat => serde_json::to_value( @@ -1454,7 +1428,7 @@ pub fn create_room_route( db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), event_type.clone(), serde_json::from_str(content.get()).map_err(|_| { Error::BadRequest(ErrorKind::BadJson, "Invalid initial_state content.") @@ -1470,7 +1444,7 @@ pub fn create_room_route( if let Some(name) = &body.name { db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomName, serde_json::to_value( name::NameEventContent::new(name.clone()) @@ -1487,7 +1461,7 @@ pub fn create_room_route( if let Some(topic) = &body.topic { db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomTopic, serde_json::to_value(topic::TopicEventContent { topic: topic.clone(), @@ -1504,7 +1478,7 @@ pub fn create_room_route( for user in &body.invite { db.rooms.append_pdu( room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomMember, serde_json::to_value(member::MemberEventContent { membership: member::MembershipState::Invite, @@ -1541,12 +1515,12 @@ pub fn joined_rooms_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); Ok(joined_rooms::Response { joined_rooms: db .rooms - .rooms_joined(&user_id) + .rooms_joined(&sender_id) .filter_map(|r| r.ok()) .collect(), } @@ -1556,22 +1530,19 @@ pub fn joined_rooms_route( #[cfg_attr( feature = "conduit_bin", put( - "/_matrix/client/r0/rooms/<_room_id>/redact/<_event_id>/<_txn_id>", + "/_matrix/client/r0/rooms/<_>/redact/<_>/<_>", data = "" ) )] pub fn redact_event_route( db: State<'_, Database>, body: Ruma, - _room_id: String, - _event_id: String, - _txn_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let event_id = db.rooms.append_pdu( body.room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomRedaction, serde_json::to_value(redaction::RedactionEventContent { reason: body.reason.clone(), @@ -1588,12 +1559,11 @@ pub fn redact_event_route( #[cfg_attr( feature = "conduit_bin", - put("/_matrix/client/r0/directory/room/<_room_alias>", data = "") + put("/_matrix/client/r0/directory/room/<_>", data = "") )] pub fn create_alias_route( db: State<'_, Database>, body: Ruma, - _room_alias: String, ) -> ConduitResult { if db.rooms.id_from_alias(&body.room_alias)?.is_some() { return Err(Error::Conflict("Alias already exists.")); @@ -1607,12 +1577,11 @@ pub fn create_alias_route( #[cfg_attr( feature = "conduit_bin", - delete("/_matrix/client/r0/directory/room/<_room_alias>", data = "") + delete("/_matrix/client/r0/directory/room/<_>", data = "") )] pub fn delete_alias_route( db: State<'_, Database>, body: Ruma, - _room_alias: String, ) -> ConduitResult { db.rooms.set_alias(&body.room_alias, None, &db.globals)?; @@ -1621,12 +1590,11 @@ pub fn delete_alias_route( #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/directory/room/<_room_alias>", data = "") + get("/_matrix/client/r0/directory/room/<_>", data = "") )] pub fn get_alias_route( db: State<'_, Database>, body: Ruma, - _room_alias: String, ) -> ConduitResult { if body.room_alias.server_name() != db.globals.server_name() { todo!("ask remote server"); @@ -1649,32 +1617,31 @@ pub fn get_alias_route( #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/rooms/<_room_id>/join", data = "") + post("/_matrix/client/r0/rooms/<_>/join", data = "") )] pub fn join_room_by_id_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); // TODO: Ask a remote server if we don't have this room let event = member::MemberEventContent { membership: member::MembershipState::Join, - displayname: db.users.displayname(&user_id)?, - avatar_url: db.users.avatar_url(&user_id)?, + displayname: db.users.displayname(&sender_id)?, + avatar_url: db.users.avatar_url(&sender_id)?, is_direct: None, third_party_invite: None, }; db.rooms.append_pdu( body.room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomMember, serde_json::to_value(event).expect("event is valid, we just created it"), None, - Some(user_id.to_string()), + Some(sender_id.to_string()), None, &db.globals, )?; @@ -1687,12 +1654,11 @@ pub fn join_room_by_id_route( #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/join/<_room_id_or_alias>", data = "") + post("/_matrix/client/r0/join/<_>", data = "") )] pub fn join_room_by_id_or_alias_route( db: State<'_, Database>, body: Ruma, - _room_id_or_alias: String, ) -> ConduitResult { let room_id = RoomId::try_from(body.room_id_or_alias.clone()).or_else(|alias| { Ok::<_, Error>(db.rooms.id_from_alias(&alias)?.ok_or(Error::BadRequest( @@ -1702,7 +1668,7 @@ pub fn join_room_by_id_or_alias_route( })?; let body = Ruma { - user_id: body.user_id.clone(), + sender_id: body.sender_id.clone(), device_id: body.device_id.clone(), json_body: None, body: join_room_by_id::Request { @@ -1712,25 +1678,24 @@ pub fn join_room_by_id_or_alias_route( }; Ok(join_room_by_id_or_alias::Response { - room_id: join_room_by_id_route(db, body, "".to_owned())?.0.room_id, + room_id: join_room_by_id_route(db, body)?.0.room_id, } .into()) } #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/rooms/<_room_id>/leave", data = "") + post("/_matrix/client/r0/rooms/<_>/leave", data = "") )] pub fn leave_room_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let mut event = serde_json::from_value::>( db.rooms - .room_state_get(&body.room_id, &EventType::RoomMember, &user_id.to_string())? + .room_state_get(&body.room_id, &EventType::RoomMember, &sender_id.to_string())? .ok_or(Error::BadRequest( ErrorKind::BadState, "Cannot leave a room you are not a member of.", @@ -1746,11 +1711,11 @@ pub fn leave_room_route( db.rooms.append_pdu( body.room_id.clone(), - user_id.clone(), + sender_id.clone(), EventType::RoomMember, serde_json::to_value(event).expect("event is valid, we just created it"), None, - Some(user_id.to_string()), + Some(sender_id.to_string()), None, &db.globals, )?; @@ -1760,18 +1725,17 @@ pub fn leave_room_route( #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/rooms/<_room_id>/kick", data = "") + post("/_matrix/client/r0/rooms/<_>/kick", data = "") )] pub fn kick_user_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let mut event = serde_json::from_value::>( db.rooms - .room_state_get(&body.room_id, &EventType::RoomMember, &user_id.to_string())? + .room_state_get(&body.room_id, &EventType::RoomMember, &body.user_id.to_string())? .ok_or(Error::BadRequest( ErrorKind::BadState, "Cannot kick member that's not in the room.", @@ -1779,7 +1743,7 @@ pub fn kick_user_route( .content .clone(), ) - .map_err(|_| Error::bad_database("Invalid member event in database."))? + .expect("Raw::from_value always works") .deserialize() .map_err(|_| Error::bad_database("Invalid member event in database."))?; @@ -1788,11 +1752,11 @@ pub fn kick_user_route( db.rooms.append_pdu( body.room_id.clone(), - user_id.clone(), // Sender + sender_id.clone(), EventType::RoomMember, serde_json::to_value(event).expect("event is valid, we just created it"), None, - Some(body.body.user_id.to_string()), + Some(body.user_id.to_string()), None, &db.globals, )?; @@ -1802,16 +1766,15 @@ pub fn kick_user_route( #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/rooms/<_room_id>/joined_members", data = "") + get("/_matrix/client/r0/rooms/<_>/joined_members", data = "") )] pub fn joined_members_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - if !db.rooms.is_joined(&user_id, &body.room_id).unwrap_or(false) { + if !db.rooms.is_joined(&sender_id, &body.room_id).unwrap_or(false) { return Err(Error::BadRequest( ErrorKind::Forbidden, "You aren't a member of the room.", @@ -1837,25 +1800,24 @@ pub fn joined_members_route( #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/rooms/<_room_id>/ban", data = "") + post("/_matrix/client/r0/rooms/<_>/ban", data = "") )] pub fn ban_user_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); // TODO: reason let event = db .rooms - .room_state_get(&body.room_id, &EventType::RoomMember, &user_id.to_string())? + .room_state_get(&body.room_id, &EventType::RoomMember, &body.user_id.to_string())? .map_or( Ok::<_, Error>(member::MemberEventContent { membership: member::MembershipState::Ban, - displayname: db.users.displayname(&user_id)?, - avatar_url: db.users.avatar_url(&user_id)?, + displayname: db.users.displayname(&body.user_id)?, + avatar_url: db.users.avatar_url(&body.user_id)?, is_direct: None, third_party_invite: None, }), @@ -1863,7 +1825,7 @@ pub fn ban_user_route( let mut event = serde_json::from_value::>( event.content.clone(), ) - .map_err(|_| Error::bad_database("Invalid member event in database."))? + .expect("Raw::from_value always works") .deserialize() .map_err(|_| Error::bad_database("Invalid member event in database."))?; event.membership = ruma::events::room::member::MembershipState::Ban; @@ -1873,11 +1835,11 @@ pub fn ban_user_route( db.rooms.append_pdu( body.room_id.clone(), - user_id.clone(), // Sender + sender_id.clone(), EventType::RoomMember, serde_json::to_value(event).expect("event is valid, we just created it"), None, - Some(body.body.user_id.to_string()), + Some(body.user_id.to_string()), None, &db.globals, )?; @@ -1887,18 +1849,17 @@ pub fn ban_user_route( #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/rooms/<_room_id>/unban", data = "") + post("/_matrix/client/r0/rooms/<_>/unban", data = "") )] pub fn unban_user_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let mut event = serde_json::from_value::>( db.rooms - .room_state_get(&body.room_id, &EventType::RoomMember, &user_id.to_string())? + .room_state_get(&body.room_id, &EventType::RoomMember, &body.user_id.to_string())? .ok_or(Error::BadRequest( ErrorKind::BadState, "Cannot unban a user who is not banned.", @@ -1914,11 +1875,11 @@ pub fn unban_user_route( db.rooms.append_pdu( body.room_id.clone(), - user_id.clone(), // Sender + sender_id.clone(), EventType::RoomMember, serde_json::to_value(event).expect("event is valid, we just created it"), None, - Some(body.body.user_id.to_string()), + Some(body.user_id.to_string()), None, &db.globals, )?; @@ -1928,33 +1889,33 @@ pub fn unban_user_route( #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/rooms/<_room_id>/forget", data = "") + post("/_matrix/client/r0/rooms/<_>/forget", data = "") )] pub fn forget_room_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - db.rooms.forget(&body.room_id, &user_id)?; + db.rooms.forget(&body.room_id, &sender_id)?; Ok(forget_room::Response.into()) } #[cfg_attr( feature = "conduit_bin", - post("/_matrix/client/r0/rooms/<_room_id>/invite", data = "") + post("/_matrix/client/r0/rooms/<_>/invite", data = "") )] pub fn invite_user_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); + if let invite_user::InvitationRecipient::UserId { user_id } = &body.recipient { db.rooms.append_pdu( body.room_id.clone(), - body.user_id.clone().expect("user is authenticated"), + sender_id.clone(), EventType::RoomMember, serde_json::to_value(member::MemberEventContent { membership: member::MembershipState::Invite, @@ -1978,12 +1939,11 @@ pub fn invite_user_route( #[cfg_attr( feature = "conduit_bin", - put("/_matrix/client/r0/directory/list/room/<_room_id>", data = "") + put("/_matrix/client/r0/directory/list/room/<_>", data = "") )] pub async fn set_room_visibility_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { match body.visibility { room::Visibility::Public => db.rooms.set_public(&body.room_id, true)?, @@ -1995,12 +1955,11 @@ pub async fn set_room_visibility_route( #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/directory/list/room/<_room_id>", data = "") + get("/_matrix/client/r0/directory/list/room/<_>", data = "") )] pub async fn get_room_visibility_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { Ok(get_room_visibility::Response { visibility: if db.rooms.is_public_room(&body.room_id)? { @@ -2027,7 +1986,7 @@ pub async fn get_public_rooms_route( server, since, }, - user_id, + sender_id, device_id, json_body, } = body; @@ -2047,7 +2006,7 @@ pub async fn get_public_rooms_route( server, since, }, - user_id, + sender_id, device_id, json_body, }, @@ -2224,16 +2183,15 @@ pub fn search_users_route( #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/rooms/<_room_id>/members", data = "") + get("/_matrix/client/r0/rooms/<_>/members", data = "") )] pub fn get_member_events_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - if !db.rooms.is_joined(user_id, &body.room_id)? { + if !db.rooms.is_joined(sender_id, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, "You don't have permission to view this room.", @@ -2266,19 +2224,17 @@ pub fn get_protocols_route() -> ConduitResult { #[cfg_attr( feature = "conduit_bin", get( - "/_matrix/client/r0/rooms/<_room_id>/event/<_event_id>", + "/_matrix/client/r0/rooms/<_>/event/<_>", data = "" ) )] pub fn get_room_event_route( db: State<'_, Database>, body: Ruma, - _room_id: String, - _event_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - if !db.rooms.is_joined(user_id, &body.room_id)? { + if !db.rooms.is_joined(sender_id, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, "You don't have permission to view this room.", @@ -2298,25 +2254,22 @@ pub fn get_room_event_route( #[cfg_attr( feature = "conduit_bin", put( - "/_matrix/client/r0/rooms/<_room_id>/send/<_event_type>/<_txn_id>", + "/_matrix/client/r0/rooms/<_>/send/<_>/<_>", data = "" ) )] pub fn create_message_event_route( db: State<'_, Database>, body: Ruma, - _room_id: String, - _event_type: String, - _txn_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let mut unsigned = serde_json::Map::new(); unsigned.insert("transaction_id".to_owned(), body.txn_id.clone().into()); let event_id = db.rooms.append_pdu( body.room_id.clone(), - user_id.clone(), + sender_id.clone(), body.event_type.clone(), serde_json::from_str( body.json_body @@ -2336,18 +2289,15 @@ pub fn create_message_event_route( #[cfg_attr( feature = "conduit_bin", put( - "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>/<_state_key>", + "/_matrix/client/r0/rooms/<_>/state/<_>/<_>", data = "" ) )] pub fn create_state_event_for_key_route( db: State<'_, Database>, body: Ruma, - _room_id: String, - _event_type: String, - _state_key: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let content = serde_json::from_str::( body.json_body @@ -2386,7 +2336,7 @@ pub fn create_state_event_for_key_route( let event_id = db.rooms.append_pdu( body.room_id.clone(), - user_id.clone(), + sender_id.clone(), body.event_type.clone(), content, None, @@ -2401,15 +2351,13 @@ pub fn create_state_event_for_key_route( #[cfg_attr( feature = "conduit_bin", put( - "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>", + "/_matrix/client/r0/rooms/<_>/state/<_>", data = "" ) )] pub fn create_state_event_for_empty_key_route( db: State<'_, Database>, body: Ruma, - _room_id: String, - _event_type: String, ) -> ConduitResult { // This just calls create_state_event_for_key_route let Ruma { @@ -2419,7 +2367,7 @@ pub fn create_state_event_for_empty_key_route( event_type, data, }, - user_id, + sender_id, device_id, json_body, } = body; @@ -2434,13 +2382,10 @@ pub fn create_state_event_for_empty_key_route( data, state_key: "".to_owned(), }, - user_id, + sender_id, device_id, json_body, }, - _room_id, - _event_type, - "".to_owned(), )? .0 .event_id, @@ -2450,16 +2395,15 @@ pub fn create_state_event_for_empty_key_route( #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/rooms/<_room_id>/state", data = "") + get("/_matrix/client/r0/rooms/<_>/state", data = "") )] pub fn get_state_events_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - if !db.rooms.is_joined(user_id, &body.room_id)? { + if !db.rooms.is_joined(sender_id, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, "You don't have permission to view the room state.", @@ -2480,20 +2424,17 @@ pub fn get_state_events_route( #[cfg_attr( feature = "conduit_bin", get( - "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>/<_state_key>", + "/_matrix/client/r0/rooms/<_>/state/<_>/<_>", data = "" ) )] pub fn get_state_events_for_key_route( db: State<'_, Database>, body: Ruma, - _room_id: String, - _event_type: String, - _state_key: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - if !db.rooms.is_joined(user_id, &body.room_id)? { + if !db.rooms.is_joined(sender_id, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, "You don't have permission to view the room state.", @@ -2518,19 +2459,17 @@ pub fn get_state_events_for_key_route( #[cfg_attr( feature = "conduit_bin", get( - "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>", + "/_matrix/client/r0/rooms/<_>/state/<_>", data = "" ) )] pub fn get_state_events_for_empty_key_route( db: State<'_, Database>, body: Ruma, - _room_id: String, - _event_type: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - if !db.rooms.is_joined(user_id, &body.room_id)? { + if !db.rooms.is_joined(sender_id, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, "You don't have permission to view the room state.", @@ -2556,14 +2495,16 @@ pub fn get_state_events_for_empty_key_route( feature = "conduit_bin", get("/_matrix/client/r0/sync", data = "") )] -pub fn sync_route( +pub async fn sync_events_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - std::thread::sleep(Duration::from_millis(1000)); - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let device_id = body.device_id.as_ref().expect("user is authenticated"); + // Setup watchers, so if there's no response, we can wait for them + let watcher = db.watch(sender_id, device_id); + let next_batch = db.globals.current_count()?.to_string(); let mut joined_rooms = BTreeMap::new(); @@ -2573,12 +2514,12 @@ pub fn sync_route( .and_then(|string| string.parse().ok()) .unwrap_or(0); - for room_id in db.rooms.rooms_joined(&user_id) { + for room_id in db.rooms.rooms_joined(&sender_id) { let room_id = room_id?; let mut pdus = db .rooms - .pdus_since(&user_id, &room_id, since)? + .pdus_since(&sender_id, &room_id, since)? .filter_map(|r| r.ok()) // Filter out buggy events .collect::>(); @@ -2589,7 +2530,7 @@ pub fn sync_route( send_notification_counts = true; if pdu.kind == EventType::RoomMember { send_member_count = true; - if !joined_since_last_sync && pdu.state_key == Some(user_id.to_string()) { + if !joined_since_last_sync && pdu.state_key == Some(sender_id.to_string()) { let content = serde_json::from_value::< Raw, >(pdu.content.clone()) @@ -2621,7 +2562,7 @@ pub fn sync_route( for hero in db .rooms - .all_pdus(&user_id, &room_id)? + .all_pdus(&sender_id, &room_id)? .filter_map(|pdu| pdu.ok()) // Ignore all broken pdus .filter(|pdu| pdu.kind == EventType::RoomMember) .map(|pdu| { @@ -2674,7 +2615,7 @@ pub fn sync_route( // Filter for possible heroes .filter_map(|u| u) { - if heroes.contains(&hero) || hero == user_id.to_string() { + if heroes.contains(&hero) || hero == sender_id.to_string() { continue; } @@ -2692,10 +2633,10 @@ pub fn sync_route( }; let notification_count = if send_notification_counts { - if let Some(last_read) = db.rooms.edus.room_read_get(&room_id, &user_id)? { + if let Some(last_read) = db.rooms.edus.room_read_get(&room_id, &sender_id)? { Some( (db.rooms - .pdus_since(&user_id, &room_id, last_read)? + .pdus_since(&sender_id, &room_id, last_read)? .filter_map(|pdu| pdu.ok()) // Filter out buggy events .filter(|pdu| { matches!( @@ -2763,7 +2704,7 @@ pub fn sync_route( account_data: sync_events::AccountData { events: db .account_data - .changes_since(Some(&room_id), &user_id, since)? + .changes_since(Some(&room_id), &sender_id, since)? .into_iter() .filter_map(|(_, v)| { serde_json::from_str(v.json().get()) @@ -2807,9 +2748,9 @@ pub fn sync_route( } let mut left_rooms = BTreeMap::new(); - for room_id in db.rooms.rooms_left(&user_id) { + for room_id in db.rooms.rooms_left(&sender_id) { let room_id = room_id?; - let pdus = db.rooms.pdus_since(&user_id, &room_id, since)?; + let pdus = db.rooms.pdus_since(&sender_id, &room_id, since)?; let room_events = pdus .filter_map(|pdu| pdu.ok()) // Filter out buggy events .map(|pdu| pdu.to_sync_room_event()) @@ -2856,7 +2797,7 @@ pub fn sync_route( } let mut invited_rooms = BTreeMap::new(); - for room_id in db.rooms.rooms_invited(&user_id) { + for room_id in db.rooms.rooms_invited(&sender_id) { let room_id = room_id?; let invited_room = sync_events::InvitedRoom { @@ -2877,9 +2818,9 @@ pub fn sync_route( // Remove all to-device events the device received *last time* db.users - .remove_to_device_events(user_id, device_id, since)?; + .remove_to_device_events(sender_id, device_id, since)?; - Ok(sync_events::Response { + let response = sync_events::Response { next_batch, rooms: sync_events::Rooms { leave: left_rooms, @@ -2909,7 +2850,7 @@ pub fn sync_route( account_data: sync_events::AccountData { events: db .account_data - .changes_since(None, &user_id, since)? + .changes_since(None, &sender_id, since)? .into_iter() .filter_map(|(_, v)| { serde_json::from_str(v.json().get()) @@ -2931,28 +2872,48 @@ pub fn sync_route( }, device_one_time_keys_count: Default::default(), // TODO to_device: sync_events::ToDevice { - events: db.users.get_to_device_events(user_id, device_id)?, + events: db.users.get_to_device_events(sender_id, device_id)?, }, + }; + + // TODO: Retry the endpoint instead of returning (waiting for #118) + if !body.full_state && response.rooms.is_empty() + && response.presence.is_empty() + && response.account_data.is_empty() + && response.device_lists.is_empty() + && response.device_one_time_keys_count.is_empty() + && response.to_device.is_empty() + { + // Hang a few seconds so requests are not spammed + // Stop hanging if new info arrives + let mut duration = body.timeout.unwrap_or(Duration::default()); + if duration.as_secs() > 10 { + duration = Duration::from_secs(10); + } + let mut delay = tokio::time::delay_for(duration); + tokio::select! { + _ = &mut delay => {} + _ = watcher => {} + } } - .into()) + + Ok(response.into()) } #[cfg_attr( feature = "conduit_bin", get( - "/_matrix/client/r0/rooms/<_room_id>/context/<_event_id>", + "/_matrix/client/r0/rooms/<_>/context/<_>", data = "" ) )] pub fn get_context_route( db: State<'_, Database>, body: Ruma, - _room_id: String, - _event_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - if !db.rooms.is_joined(user_id, &body.room_id)? { + if !db.rooms.is_joined(sender_id, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, "You don't have permission to view this room.", @@ -2975,7 +2936,7 @@ pub fn get_context_route( let events_before = db .rooms - .pdus_until(&user_id, &body.room_id, base_token) + .pdus_until(&sender_id, &body.room_id, base_token) .take( u32::try_from(body.limit).map_err(|_| { Error::BadRequest(ErrorKind::InvalidParam, "Limit value is invalid.") @@ -2985,14 +2946,7 @@ pub fn get_context_route( .filter_map(|r| r.ok()) // Remove buggy events .collect::>(); - let start_token = events_before.last().map_or(Ok(None), |(_, e)| { - Ok::<_, Error>(Some( - db.rooms - .get_pdu_count(&e.event_id)? - .ok_or_else(|| Error::bad_database("Can't find count from event in db."))? - .to_string(), - )) - })?; + let start_token = events_before.last().map(|(count, _)| count.to_string()); let events_before = events_before .into_iter() @@ -3001,7 +2955,7 @@ pub fn get_context_route( let events_after = db .rooms - .pdus_after(&user_id, &body.room_id, base_token) + .pdus_after(&sender_id, &body.room_id, base_token) .take( u32::try_from(body.limit).map_err(|_| { Error::BadRequest(ErrorKind::InvalidParam, "Limit value is invalid.") @@ -3011,15 +2965,7 @@ pub fn get_context_route( .filter_map(|r| r.ok()) // Remove buggy events .collect::>(); - let end_token = if let Some(last_event) = events_after.last() { - Some( - utils::u64_from_bytes(&last_event.0) - .map_err(|_| Error::bad_database("Invalid pdu id in db."))? - .to_string(), - ) - } else { - None - }; + let end_token = events_after.last().map(|(count, _)| count.to_string()); let events_after = events_after .into_iter() @@ -3044,16 +2990,15 @@ pub fn get_context_route( #[cfg_attr( feature = "conduit_bin", - get("/_matrix/client/r0/rooms/<_room_id>/messages", data = "") + get("/_matrix/client/r0/rooms/<_>/messages", data = "") )] pub fn get_message_events_route( db: State<'_, Database>, body: Ruma, - _room_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); - if !db.rooms.is_joined(user_id, &body.room_id)? { + if !db.rooms.is_joined(sender_id, &body.room_id)? { return Err(Error::BadRequest( ErrorKind::Forbidden, "You don't have permission to view this room.", @@ -3066,7 +3011,7 @@ pub fn get_message_events_route( .parse() .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid `from` value."))?; - let to = body.to.as_ref().map(|t| t.as_bytes()); + let to = body.to.as_ref().map(|t| t.parse()); // Use limit or else 10 let limit = body @@ -3078,21 +3023,13 @@ pub fn get_message_events_route( get_message_events::Direction::Forward => { let events_after = db .rooms - .pdus_after(&user_id, &body.room_id, from) + .pdus_after(&sender_id, &body.room_id, from) .take(limit) .filter_map(|r| r.ok()) // Filter out buggy events - .take_while(|(k, _)| Some(&**k) != to) // Stop at `to` + .take_while(|&(k, _)| Some(Ok(k)) != to) // Stop at `to` .collect::>(); - let end_token = if let Some(last_event) = events_after.last() { - Some( - utils::u64_from_bytes(&last_event.0) - .map_err(|_| Error::bad_database("Invalid pdu id in db."))? - .to_string(), - ) - } else { - None - }; + let end_token = events_after.last().map(|(count, _)| count.to_string()); let events_after = events_after .into_iter() @@ -3110,21 +3047,13 @@ pub fn get_message_events_route( get_message_events::Direction::Backward => { let events_before = db .rooms - .pdus_until(&user_id, &body.room_id, from) + .pdus_until(&sender_id, &body.room_id, from) .take(limit) .filter_map(|r| r.ok()) // Filter out buggy events - .take_while(|(k, _)| Some(&**k) != to) // Stop at `to` + .take_while(|&(k, _)| Some(Ok(k)) != to) // Stop at `to` .collect::>(); - let start_token = if let Some(last_event) = events_before.last() { - Some( - utils::u64_from_bytes(&last_event.0) - .map_err(|_| Error::bad_database("Invalid pdu id in db."))? - .to_string(), - ) - } else { - None - }; + let start_token = events_before.last().map(|(count, _)| count.to_string()); let events_before = events_before .into_iter() @@ -3161,24 +3090,22 @@ pub fn publicised_groups_route() -> ConduitResult/<_txn_id>", + "/_matrix/client/r0/sendToDevice/<_>/<_>", data = "" ) )] pub fn send_event_to_device_route( db: State<'_, Database>, body: Ruma, - _event_type: String, - _txn_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); for (target_user_id, map) in &body.messages { for (target_device_id_maybe, event) in map { match target_device_id_maybe { to_device::DeviceIdOrAllDevices::DeviceId(target_device_id) => { db.users.add_to_device_event( - user_id, + sender_id, &target_user_id, &target_device_id, &body.event_type, @@ -3192,7 +3119,7 @@ pub fn send_event_to_device_route( to_device::DeviceIdOrAllDevices::AllDevices => { for target_device_id in db.users.all_device_ids(&target_user_id) { db.users.add_to_device_event( - user_id, + sender_id, &target_user_id, &target_device_id?, &body.event_type, @@ -3307,11 +3234,11 @@ pub fn get_devices_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let devices = db .users - .all_devices_metadata(user_id) + .all_devices_metadata(sender_id) .filter_map(|r| r.ok()) // Filter out buggy devices .collect::>(); @@ -3327,11 +3254,11 @@ pub fn get_device_route( body: Ruma, _device_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let device = db .users - .get_device_metadata(&user_id, &body.body.device_id)? + .get_device_metadata(&sender_id, &body.body.device_id)? .ok_or(Error::BadRequest(ErrorKind::NotFound, "Device not found."))?; Ok(get_device::Response { device }.into()) @@ -3346,17 +3273,17 @@ pub fn update_device_route( body: Ruma, _device_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let mut device = db .users - .get_device_metadata(&user_id, &body.body.device_id)? + .get_device_metadata(&sender_id, &body.body.device_id)? .ok_or(Error::BadRequest(ErrorKind::NotFound, "Device not found."))?; device.display_name = body.display_name.clone(); db.users - .update_device_metadata(&user_id, &body.body.device_id, &device)?; + .update_device_metadata(&sender_id, &body.body.device_id, &device)?; Ok(update_device::Response.into()) } @@ -3370,7 +3297,7 @@ pub fn delete_device_route( body: Ruma, _device_id: String, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let device_id = body.device_id.as_ref().expect("user is authenticated"); // UIAA @@ -3386,7 +3313,7 @@ pub fn delete_device_route( if let Some(auth) = &body.auth { let (worked, uiaainfo) = db.uiaa.try_auth( - &user_id, + &sender_id, &device_id, auth, &uiaainfo, @@ -3399,11 +3326,11 @@ pub fn delete_device_route( // Success! } else { uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH)); - db.uiaa.create(&user_id, &device_id, &uiaainfo)?; + db.uiaa.create(&sender_id, &device_id, &uiaainfo)?; return Err(Error::Uiaa(uiaainfo)); } - db.users.remove_device(&user_id, &body.body.device_id)?; + db.users.remove_device(&sender_id, &body.body.device_id)?; Ok(delete_device::Response.into()) } @@ -3416,7 +3343,7 @@ pub fn delete_devices_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let device_id = body.device_id.as_ref().expect("user is authenticated"); // UIAA @@ -3432,7 +3359,7 @@ pub fn delete_devices_route( if let Some(auth) = &body.auth { let (worked, uiaainfo) = db.uiaa.try_auth( - &user_id, + &sender_id, &device_id, auth, &uiaainfo, @@ -3445,12 +3372,12 @@ pub fn delete_devices_route( // Success! } else { uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH)); - db.uiaa.create(&user_id, &device_id, &uiaainfo)?; + db.uiaa.create(&sender_id, &device_id, &uiaainfo)?; return Err(Error::Uiaa(uiaainfo)); } for device_id in &body.devices { - db.users.remove_device(&user_id, &device_id)? + db.users.remove_device(&sender_id, &device_id)? } Ok(delete_devices::Response.into()) @@ -3464,7 +3391,7 @@ pub fn upload_signing_keys_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let device_id = body.device_id.as_ref().expect("user is authenticated"); // UIAA @@ -3480,7 +3407,7 @@ pub fn upload_signing_keys_route( if let Some(auth) = &body.auth { let (worked, uiaainfo) = db.uiaa.try_auth( - &user_id, + &sender_id, &device_id, auth, &uiaainfo, @@ -3493,13 +3420,13 @@ pub fn upload_signing_keys_route( // Success! } else { uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH)); - db.uiaa.create(&user_id, &device_id, &uiaainfo)?; + db.uiaa.create(&sender_id, &device_id, &uiaainfo)?; return Err(Error::Uiaa(uiaainfo)); } if let Some(master_key) = &body.master_key { db.users.add_cross_signing_keys( - user_id, + sender_id, &master_key, &body.self_signing_key, &body.user_signing_key, @@ -3518,7 +3445,7 @@ pub fn upload_signatures_route( db: State<'_, Database>, body: Ruma, ) -> ConduitResult { - let sender_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); for (user_id, signed_keys) in &body.signed_keys { for (key_id, signed_key) in signed_keys { @@ -3581,22 +3508,19 @@ pub fn set_pushers_route() -> ConduitResult { #[cfg_attr( feature = "conduit_bin", put( - "/_matrix/client/r0/user/<_user_id>/rooms/<_room_id>/tags/<_tag>", + "/_matrix/client/r0/user/<_>/rooms/<_>/tags/<_>", data = "" ) )] pub fn update_tag_route( db: State<'_, Database>, - _user_id: String, - _room_id: String, - _tag: String, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let mut tags_event = db .account_data - .get::(Some(&body.room_id), user_id, EventType::Tag)? + .get::(Some(&body.room_id), sender_id, EventType::Tag)? .unwrap_or_else(|| ruma::events::tag::TagEvent { content: ruma::events::tag::TagEventContent { tags: BTreeMap::new(), @@ -3609,7 +3533,7 @@ pub fn update_tag_route( db.account_data.update( Some(&body.room_id), - user_id, + sender_id, EventType::Tag, &tags_event, &db.globals, @@ -3621,22 +3545,19 @@ pub fn update_tag_route( #[cfg_attr( feature = "conduit_bin", delete( - "/_matrix/client/r0/user/<_user_id>/rooms/<_room_id>/tags/<_tag>", + "/_matrix/client/r0/user/<_>/rooms/<_>/tags/<_>", data = "" ) )] pub fn delete_tag_route( db: State<'_, Database>, - _user_id: String, - _room_id: String, - _tag: String, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); let mut tags_event = db .account_data - .get::(Some(&body.room_id), user_id, EventType::Tag)? + .get::(Some(&body.room_id), sender_id, EventType::Tag)? .unwrap_or_else(|| ruma::events::tag::TagEvent { content: ruma::events::tag::TagEventContent { tags: BTreeMap::new(), @@ -3646,7 +3567,7 @@ pub fn delete_tag_route( db.account_data.update( Some(&body.room_id), - user_id, + sender_id, EventType::Tag, &tags_event, &db.globals, @@ -3658,22 +3579,20 @@ pub fn delete_tag_route( #[cfg_attr( feature = "conduit_bin", get( - "/_matrix/client/r0/user/<_user_id>/rooms/<_room_id>/tags", + "/_matrix/client/r0/user/<_>/rooms/<_>/tags", data = "" ) )] pub fn get_tags_route( db: State<'_, Database>, - _user_id: String, - _room_id: String, body: Ruma, ) -> ConduitResult { - let user_id = body.user_id.as_ref().expect("user is authenticated"); + let sender_id = body.sender_id.as_ref().expect("user is authenticated"); Ok(get_tags::Response { tags: db .account_data - .get::(Some(&body.room_id), user_id, EventType::Tag)? + .get::(Some(&body.room_id), sender_id, EventType::Tag)? .unwrap_or_else(|| ruma::events::tag::TagEvent { content: ruma::events::tag::TagEventContent { tags: BTreeMap::new(), @@ -3686,9 +3605,8 @@ pub fn get_tags_route( } #[cfg(feature = "conduit_bin")] -#[options("/<_segments..>")] +#[options("/<_..>")] pub fn options_route( - _segments: rocket::http::uri::Segments<'_>, ) -> ConduitResult { Ok(send_event_to_device::Response.into()) } diff --git a/src/database.rs b/src/database.rs index 370fde7..250de23 100644 --- a/src/database.rs +++ b/src/database.rs @@ -12,7 +12,9 @@ use directories::ProjectDirs; use log::info; use std::fs::remove_dir_all; -use rocket::Config; +use futures::StreamExt; +use rocket::{futures, Config}; +use ruma::{DeviceId, UserId}; pub struct Database { pub globals: globals::Globals, @@ -124,4 +126,77 @@ impl Database { _db: db, }) } + + pub async fn watch(&self, user_id: &UserId, device_id: &DeviceId) -> () { + let mut userid_prefix = user_id.to_string().as_bytes().to_vec(); + userid_prefix.push(0xff); + let mut userdeviceid_prefix = userid_prefix.clone(); + userdeviceid_prefix.extend_from_slice(device_id.as_bytes()); + userdeviceid_prefix.push(0xff); + + let mut futures = futures::stream::FuturesUnordered::new(); + + futures.push(self.users.keychangeid_userid.watch_prefix(b"")); + + // Return when *any* user changed his key + // TODO: only send for user they share a room with + futures.push( + self.users + .todeviceid_events + .watch_prefix(&userdeviceid_prefix), + ); + + // TODO: only send for user they share a room with + futures.push(self.global_edus.presenceid_presence.watch_prefix(b"")); + + futures.push(self.rooms.userroomid_joined.watch_prefix(&userid_prefix)); + futures.push(self.rooms.userroomid_invited.watch_prefix(&userid_prefix)); + futures.push(self.rooms.userroomid_left.watch_prefix(&userid_prefix)); + + // Events for rooms we are in + for room_id in self.rooms.rooms_joined(user_id).filter_map(|r| r.ok()) { + let mut roomid_prefix = room_id.to_string().as_bytes().to_vec(); + roomid_prefix.push(0xff); + + // PDUs + futures.push(self.rooms.pduid_pdu.watch_prefix(&roomid_prefix)); + + // EDUs + futures.push( + self.rooms + .edus + .roomid_lastroomactiveupdate + .watch_prefix(&roomid_prefix), + ); + + futures.push( + self.rooms + .edus + .roomlatestid_roomlatest + .watch_prefix(&roomid_prefix), + ); + + // Room account data + let mut roomuser_prefix = roomid_prefix.clone(); + roomuser_prefix.extend_from_slice(&userid_prefix); + + futures.push( + self.account_data + .roomuserdataid_accountdata + .watch_prefix(&roomuser_prefix), + ); + } + + let mut globaluserdata_prefix = vec![0xff]; + globaluserdata_prefix.extend_from_slice(&userid_prefix); + + futures.push( + self.account_data + .roomuserdataid_accountdata + .watch_prefix(&globaluserdata_prefix), + ); + + // Wait until one of them finds something + futures.next().await; + } } diff --git a/src/database/rooms.rs b/src/database/rooms.rs index 0395cc2..fe5721c 100644 --- a/src/database/rooms.rs +++ b/src/database/rooms.rs @@ -666,7 +666,7 @@ impl Rooms { user_id: &UserId, room_id: &RoomId, until: u64, - ) -> impl Iterator> { + ) -> impl Iterator> { // Create the first part of the full pdu id let mut prefix = room_id.to_string().as_bytes().to_vec(); prefix.push(0xff); @@ -677,6 +677,7 @@ impl Rooms { let current: &[u8] = ¤t; let user_id = user_id.clone(); + let prefixlen = prefix.len(); self.pduid_pdu .range(..current) .rev() @@ -688,7 +689,11 @@ impl Rooms { if pdu.sender != user_id { pdu.unsigned.remove("transaction_id"); } - Ok((k, pdu)) + Ok(( + utils::u64_from_bytes(&k[prefixlen..]) + .map_err(|_| Error::bad_database("Invalid pdu id in db."))?, + pdu, + )) }) } @@ -699,7 +704,7 @@ impl Rooms { user_id: &UserId, room_id: &RoomId, from: u64, - ) -> impl Iterator> { + ) -> impl Iterator> { // Create the first part of the full pdu id let mut prefix = room_id.to_string().as_bytes().to_vec(); prefix.push(0xff); @@ -710,6 +715,7 @@ impl Rooms { let current: &[u8] = ¤t; let user_id = user_id.clone(); + let prefixlen = prefix.len(); self.pduid_pdu .range(current..) .filter_map(|r| r.ok()) @@ -720,7 +726,11 @@ impl Rooms { if pdu.sender != user_id { pdu.unsigned.remove("transaction_id"); } - Ok((k, pdu)) + Ok(( + utils::u64_from_bytes(&k[prefixlen..]) + .map_err(|_| Error::bad_database("Invalid pdu id in db."))?, + pdu, + )) }) } @@ -919,7 +929,7 @@ impl Rooms { }) } - /// Returns an iterator over all left members of a room. + /// Returns an iterator over all rooms this user joined. pub fn rooms_joined(&self, user_id: &UserId) -> impl Iterator> { self.userroomid_joined .scan_prefix(user_id.to_string()) diff --git a/src/main.rs b/src/main.rs index 1feee4d..2caee4c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -86,7 +86,7 @@ fn setup_rocket() -> rocket::Rocket { client_server::get_state_events_route, client_server::get_state_events_for_key_route, client_server::get_state_events_for_empty_key_route, - client_server::sync_route, + client_server::sync_events_route, client_server::get_context_route, client_server::get_message_events_route, client_server::turn_server_route, diff --git a/src/ruma_wrapper.rs b/src/ruma_wrapper.rs index 2a82b10..66f4d4c 100644 --- a/src/ruma_wrapper.rs +++ b/src/ruma_wrapper.rs @@ -13,7 +13,7 @@ use { http::Status, response::{self, Responder}, tokio::io::AsyncReadExt, - Outcome::*, + outcome::Outcome::*, Request, State, }, ruma::api::Endpoint, @@ -24,7 +24,7 @@ use { /// first. pub struct Ruma { pub body: T, - pub user_id: Option, + pub sender_id: Option, pub device_id: Option>, pub json_body: Option>, // This is None when body is not a valid string } @@ -94,7 +94,7 @@ impl<'a, T: Endpoint> FromTransformedData<'a> for Ruma { match T::try_from(http_request) { Ok(t) => Success(Ruma { body: t, - user_id, + sender_id: user_id, device_id, // TODO: Can we avoid parsing it again? (We only need this for append_pdu) json_body: utils::string_from_bytes(&body)