From e815486030cbae0706663051a1ed4f2da1e9caf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 21 Apr 2021 09:56:50 +0200 Subject: [PATCH 1/3] fix: don't allow inviting other users (not implemented yet) --- src/client_server/membership.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/client_server/membership.rs b/src/client_server/membership.rs index dcd7c37..7eca676 100644 --- a/src/client_server/membership.rs +++ b/src/client_server/membership.rs @@ -152,6 +152,13 @@ pub async fn invite_user_route( let sender_user = body.sender_user.as_ref().expect("user is authenticated"); if let invite_user::IncomingInvitationRecipient::UserId { user_id } = &body.recipient { + if body.room_id.server_name() != db.globals.server_name() { + return Err(Error::BadRequest( + ErrorKind::Forbidden, + "Inviting users from other homeservers is not implemented yet.", + )); + } + db.rooms.build_and_append_pdu( PduBuilder { event_type: EventType::RoomMember, From 71ed1b295a3204c1e6abb865f322b1874e0ebb1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 21 Apr 2021 10:51:34 +0200 Subject: [PATCH 2/3] feat: /devices route --- src/database.rs | 1 + src/database/users.rs | 23 +++++++++++++++++++++++ src/main.rs | 1 + src/server_server.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/src/database.rs b/src/database.rs index 6bb1b17..06a708d 100644 --- a/src/database.rs +++ b/src/database.rs @@ -123,6 +123,7 @@ impl Database { userid_avatarurl: db.open_tree("userid_avatarurl")?, userdeviceid_token: db.open_tree("userdeviceid_token")?, userdeviceid_metadata: db.open_tree("userdeviceid_metadata")?, + userid_devicelistversion: db.open_tree("userid_devicelistversion")?, token_userdeviceid: db.open_tree("token_userdeviceid")?, onetimekeyid_onetimekeys: db.open_tree("onetimekeyid_onetimekeys")?, userid_lastonetimekeyupdate: db.open_tree("userid_lastonetimekeyupdate")?, diff --git a/src/database/users.rs b/src/database/users.rs index c794e52..9cdfb5f 100644 --- a/src/database/users.rs +++ b/src/database/users.rs @@ -22,6 +22,7 @@ pub struct Users { pub(super) userid_avatarurl: sled::Tree, pub(super) userdeviceid_token: sled::Tree, pub(super) userdeviceid_metadata: sled::Tree, // This is also used to check if a device exists + pub(super) userid_devicelistversion: sled::Tree, // DevicelistVersion = u64 pub(super) token_userdeviceid: sled::Tree, pub(super) onetimekeyid_onetimekeys: sled::Tree, // OneTimeKeyId = UserId + DeviceKeyId @@ -189,6 +190,10 @@ impl Users { userdeviceid.push(0xff); userdeviceid.extend_from_slice(device_id.as_bytes()); + self.userid_devicelistversion + .update_and_fetch(&user_id.as_bytes(), utils::increment)? + .expect("utils::increment will always put in a value"); + self.userdeviceid_metadata.insert( userdeviceid, serde_json::to_string(&Device { @@ -227,6 +232,10 @@ impl Users { // TODO: Remove onetimekeys + self.userid_devicelistversion + .update_and_fetch(&user_id.as_bytes(), utils::increment)? + .expect("utils::increment will always put in a value"); + self.userdeviceid_metadata.remove(&userdeviceid)?; Ok(()) @@ -811,6 +820,10 @@ impl Users { // Only existing devices should be able to call this. assert!(self.userdeviceid_metadata.get(&userdeviceid)?.is_some()); + self.userid_devicelistversion + .update_and_fetch(&user_id.as_bytes(), utils::increment)? + .expect("utils::increment will always put in a value"); + self.userdeviceid_metadata.insert( userdeviceid, serde_json::to_string(device) @@ -840,6 +853,16 @@ impl Users { }) } + pub fn get_devicelist_version(&self, user_id: &UserId) -> Result> { + self.userid_devicelistversion + .get(user_id.as_bytes())? + .map_or(Ok(None), |bytes| { + utils::u64_from_bytes(&bytes) + .map_err(|_| Error::bad_database("Invalid devicelistversion in db.")) + .map(Some) + }) + } + pub fn all_devices_metadata(&self, user_id: &UserId) -> impl Iterator> { let mut key = user_id.as_bytes().to_vec(); key.push(0xff); diff --git a/src/main.rs b/src/main.rs index 3157023..ba8448d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -171,6 +171,7 @@ fn setup_rocket() -> (rocket::Rocket, Config) { server_server::create_join_event_template_route, server_server::create_join_event_route, server_server::create_invite_route, + server_server::get_devices_route, server_server::get_room_information_route, server_server::get_profile_information_route, ], diff --git a/src/server_server.rs b/src/server_server.rs index 5779b90..e969b31 100644 --- a/src/server_server.rs +++ b/src/server_server.rs @@ -8,6 +8,7 @@ use ruma::{ api::{ client::error::ErrorKind, federation::{ + device::get_devices::{self, v1::UserDevice}, directory::{get_public_rooms, get_public_rooms_filtered}, discovery::{ get_remote_server_keys, get_server_keys, get_server_version, ServerSigningKeys, @@ -1979,6 +1980,46 @@ pub async fn create_invite_route<'a>( .into()) } +#[cfg_attr( + feature = "conduit_bin", + get("/_matrix/federation/v1/user/devices/<_>", data = "") +)] +#[tracing::instrument(skip(db, body))] +pub fn get_devices_route<'a>( + db: State<'a, Database>, + body: Ruma>, +) -> ConduitResult { + if !db.globals.allow_federation() { + return Err(Error::bad_config("Federation is disabled.")); + } + + Ok(get_devices::v1::Response { + user_id: body.user_id.clone(), + stream_id: db + .users + .get_devicelist_version(&body.user_id)? + .unwrap_or(0) + .try_into() + .expect("version will not grow that large"), + devices: db + .users + .all_devices_metadata(&body.user_id) + .filter_map(|r| r.ok()) + .filter_map(|metadata| { + Some(UserDevice { + keys: db + .users + .get_device_keys(&body.user_id, &metadata.device_id) + .ok()??, + device_id: metadata.device_id, + device_display_name: metadata.display_name, + }) + }) + .collect(), + } + .into()) +} + #[cfg_attr( feature = "conduit_bin", get("/_matrix/federation/v1/query/directory", data = "") From 2f440e644dedb958ed290671165a3441e2109b55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20K=C3=B6sters?= Date: Wed, 21 Apr 2021 10:59:07 +0200 Subject: [PATCH 3/3] fix: clippy --- src/server_server.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/server_server.rs b/src/server_server.rs index e969b31..6024b8a 100644 --- a/src/server_server.rs +++ b/src/server_server.rs @@ -862,8 +862,6 @@ fn handle_incoming_pdu<'a>( .collect(), ); } - &state_at_incoming_event; - // TODO: set incoming_auth_events? } @@ -1860,12 +1858,12 @@ pub async fn create_join_event_route<'a>( auth_chain: auth_chain_ids .iter() .filter_map(|id| db.rooms.get_pdu_json(&id).ok().flatten()) - .map(|json| PduEvent::convert_to_outgoing_federation_event(json)) + .map(PduEvent::convert_to_outgoing_federation_event) .collect(), state: state_ids .iter() .filter_map(|id| db.rooms.get_pdu_json(&id).ok().flatten()) - .map(|json| PduEvent::convert_to_outgoing_federation_event(json)) + .map(PduEvent::convert_to_outgoing_federation_event) .collect(), }, } @@ -2036,7 +2034,7 @@ pub fn get_room_information_route<'a>( let room_id = db .rooms .id_from_alias(&body.room_alias)? - .ok_or_else(|| Error::BadRequest(ErrorKind::NotFound, "Room alias not found."))?; + .ok_or(Error::BadRequest(ErrorKind::NotFound, "Room alias not found."))?; Ok(get_room_information::v1::Response { room_id,