diff --git a/src/client_server.rs b/src/client_server.rs index dac5e47..873d3ec 100644 --- a/src/client_server.rs +++ b/src/client_server.rs @@ -38,7 +38,7 @@ use ruma_identifiers::{RoomId, UserId}; use serde_json::json; use std::{ collections::BTreeMap, - convert::TryInto, + convert::{TryFrom, TryInto}, path::PathBuf, time::{Duration, SystemTime}, }; @@ -325,8 +325,7 @@ pub fn set_displayname_route( if displayname == "" { data.displayname_remove(&user_id); } else { - data.displayname_set(&user_id, body.displayname.clone()); - // TODO send a new m.room.member join event with the updated displayname + data.displayname_set(&user_id, displayname.clone()); // TODO send a new m.presence event with the updated displayname } } @@ -610,26 +609,34 @@ pub fn create_room_route( MatrixResult(Ok(create_room::Response { room_id })) } -#[get("/_matrix/client/r0/directory/room/")] -pub fn get_alias_route(room_alias: String) -> MatrixResult { +#[get("/_matrix/client/r0/directory/room/<_room_alias>", data = "")] +pub fn get_alias_route( + data: State, + body: Ruma, + _room_alias: String, +) -> MatrixResult { // TODO - let room_id = match &*room_alias { - "#room:localhost" => "!xclkjvdlfj:localhost", - _ => { - debug!("Room not found."); - return MatrixResult(Err(Error { - kind: ErrorKind::NotFound, - message: "Room not found.".to_owned(), - status_code: http::StatusCode::NOT_FOUND, - })); + let room_id = if body.room_alias.server_name() == data.hostname() { + match body.room_alias.alias() { + "conduit" => "!lgOCCXQKtXOAPlAlG5:conduit.rs", + _ => { + debug!("Room alias not found."); + return MatrixResult(Err(Error { + kind: ErrorKind::NotFound, + message: "Room not found.".to_owned(), + status_code: http::StatusCode::NOT_FOUND, + })); + } } + } else { + todo!("ask remote server"); } .try_into() .unwrap(); MatrixResult(Ok(get_alias::Response { room_id, - servers: vec!["localhost".to_owned()], + servers: vec!["conduit.rs".to_owned()], })) } @@ -661,21 +668,19 @@ pub fn join_room_by_id_or_alias_route( body: Ruma, _room_id_or_alias: String, ) -> MatrixResult { - let room_id = if body.room_id_or_alias.is_room_alias_id() { - match body.room_id_or_alias.as_ref() { - "#room:localhost" => "!xclkjvdlfj:localhost".try_into().unwrap(), - _ => { - debug!("Room not found."); - return MatrixResult(Err(Error { - kind: ErrorKind::NotFound, - message: "Room not found.".to_owned(), - status_code: http::StatusCode::NOT_FOUND, - })); - } + let room_id = match RoomId::try_from(body.room_id_or_alias.clone()) { + Ok(room_id) => room_id, + Err(room_alias) => if room_alias.server_name() == data.hostname() { + return MatrixResult(Err(Error { + kind: ErrorKind::NotFound, + message: "Room alias not found.".to_owned(), + status_code: http::StatusCode::NOT_FOUND, + })); + } else { + // Ask creator server of the room to join TODO ask someone else when not available + //server_server::send_request(data, destination, request) + todo!(); } - } else { - todo!(); - //body.room_id_or_alias.try_into().unwrap() }; if data.room_join( @@ -758,9 +763,9 @@ pub async fn get_public_rooms_filtered_route( chunk.extend_from_slice( &server_server::send_request( &data, - "chat.privacytools.io".to_owned(), + "privacytools.io".to_owned(), ruma_federation_api::v1::get_public_rooms::Request { - limit: None, + limit: Some(20_u32.into()), since: None, include_all_networks: None, third_party_instance_id: None, diff --git a/src/data.rs b/src/data.rs index 8096a08..88facca 100644 --- a/src/data.rs +++ b/src/data.rs @@ -91,11 +91,21 @@ impl Data { } /// Set a new displayname. - pub fn displayname_set(&self, user_id: &UserId, displayname: Option) { + pub fn displayname_set(&self, user_id: &UserId, displayname: String) { self.db .userid_displayname - .insert(user_id.to_string(), &*displayname.unwrap_or_default()) + .insert(user_id.to_string(), &*displayname) .unwrap(); + for room_id in self.rooms_joined(user_id) { + self.pdu_append( + room_id.clone(), + user_id.clone(), + EventType::RoomMember, + json!({"membership": "join", "displayname": displayname}), + None, + Some(user_id.to_string()), + ); + } } /// Get a the displayname of a user. @@ -200,11 +210,19 @@ impl Data { room_id.to_string().as_bytes().into(), ); + let mut content = json!({"membership": "join"}); + if let Some(displayname) = self.displayname_get(user_id) { + content + .as_object_mut() + .unwrap() + .insert("displayname".to_owned(), displayname.into()); + } + self.pdu_append( room_id.clone(), user_id.clone(), EventType::RoomMember, - json!({"membership": "join"}), + content, None, Some(user_id.to_string()), ); @@ -429,6 +447,17 @@ impl Data { .unwrap_or(0_u64) + 1; + let mut unsigned = unsigned.unwrap_or_default(); + // TODO: Optimize this to not load the whole room state? + if let Some(state_key) = &state_key { + if let Some(prev_pdu) = self + .room_state(&room_id) + .get(&(event_type.clone(), state_key.clone())) + { + unsigned.insert("prev_content".to_owned(), prev_pdu.content.clone()); + } + } + let mut pdu = PduEvent { event_id: EventId::try_from("$thiswillbefilledinlater").unwrap(), room_id: room_id.clone(), @@ -442,7 +471,7 @@ impl Data { depth: depth.try_into().unwrap(), auth_events: Vec::new(), redacts: None, - unsigned: unsigned.unwrap_or_default(), + unsigned, hashes: ruma_federation_api::EventHash { sha256: "aaa".to_owned(), }, diff --git a/src/main.rs b/src/main.rs index 0794fcf..324e23f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,7 +76,7 @@ fn main() { } pretty_env_logger::init(); - let data = Data::load_or_create("matrixtesting.koesters.xyz:14004"); + let data = Data::load_or_create("conduit.rs"); //data.debug(); setup_rocket(data).launch().unwrap(); diff --git a/src/ruma_wrapper.rs b/src/ruma_wrapper.rs index 1d3328b..eec9d84 100644 --- a/src/ruma_wrapper.rs +++ b/src/ruma_wrapper.rs @@ -164,3 +164,11 @@ where } } } + +impl Deref for MatrixResult { + type Target = Result; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/src/server_server.rs b/src/server_server.rs index a62f23b..93c3c22 100644 --- a/src/server_server.rs +++ b/src/server_server.rs @@ -12,6 +12,22 @@ use std::{ time::{Duration, SystemTime}, }; +pub async fn request_well_known(data: &crate::Data, destination: &str) -> Option { + let body: serde_json::Value = serde_json::from_str(&data + .reqwest_client() + .get(&format!( + "https://{}/.well-known/matrix/server", + destination + )) + .send() + .await + .ok()? + .text() + .await + .ok()?).ok()?; + Some(body.get("m.server")?.as_str()?.to_owned()) +} + pub async fn send_request( data: &crate::Data, destination: String, @@ -19,7 +35,8 @@ pub async fn send_request( ) -> Option { let mut http_request: http::Request<_> = request.try_into().unwrap(); - *http_request.uri_mut() = format!("https://{}:8448{}", &destination.clone(), T::METADATA.path) + let actual_destination = "https://".to_owned() + &request_well_known(data, &destination).await.unwrap_or(destination.clone() + ":8448"); + *http_request.uri_mut() = (actual_destination + T::METADATA.path) .parse() .unwrap(); @@ -35,7 +52,7 @@ pub async fn send_request( request_map.insert("method".to_owned(), T::METADATA.method.to_string().into()); request_map.insert("uri".to_owned(), T::METADATA.path.into()); request_map.insert("origin".to_owned(), data.hostname().into()); - request_map.insert("destination".to_owned(), "privacytools.io".into()); + request_map.insert("destination".to_owned(), destination.into()); let mut request_json = request_map.into(); ruma_signatures::sign_json(data.hostname(), data.keypair(), &mut request_json).unwrap(); @@ -141,9 +158,6 @@ pub fn get_server_keys(data: State) -> Json { } #[get("/_matrix/key/v2/server/<_key_id>")] -pub fn get_server_keys_deprecated( - data: State, - _key_id: String, -) -> Json { +pub fn get_server_keys_deprecated(data: State, _key_id: String) -> Json { get_server_keys(data) }