diff --git a/assets/translations.yaml b/assets/translations.yaml index b193025..3485ce2 100644 --- a/assets/translations.yaml +++ b/assets/translations.yaml @@ -68,6 +68,7 @@ en: room_successfully_unbridged: "${channel_name} is now unbridged." defaults: admin_room_display_name: "Admin Room (Rocket.Chat)" + direct_message_room_display_name_suffix: "(DM Rocket.Chat)" internal_error: "An internal error occurred" handlers: welcome: "Your Rocket.Chat <-> Matrix application service is running" diff --git a/src/matrix-rocketchat/handlers/events/room_handler.rs b/src/matrix-rocketchat/handlers/events/room_handler.rs index ca89bbd..5f06d22 100644 --- a/src/matrix-rocketchat/handlers/events/room_handler.rs +++ b/src/matrix-rocketchat/handlers/events/room_handler.rs @@ -102,7 +102,14 @@ impl<'a> RoomHandler<'a> { room_creator_id: UserId, invited_user_id: UserId, ) -> Result { - let room = self.create_room(channel, rocketchat_server.id.clone(), room_creator_id, invited_user_id, false)?; + let room = self.create_room( + channel.id.clone(), + rocketchat_server.id.clone(), + room_creator_id, + invited_user_id, + channel.name.clone(), + false, + )?; self.add_virtual_users_to_room(rocketchat_api, channel, rocketchat_server.id.clone(), room.matrix_room_id.clone())?; Ok(room) } @@ -313,14 +320,15 @@ impl<'a> RoomHandler<'a> { /// Create a room on the Matrix homeserver with the power levels for a bridged room. pub fn create_room( &self, - channel: &Channel, + rocketchat_room_id: String, rocketchat_server_id: String, room_creator_id: UserId, invited_user_id: UserId, + room_display_name: Option, is_direct_message_room: bool, ) -> Result { - let room_alias_name = format!("{}_{}_{}", self.config.sender_localpart, rocketchat_server_id, channel.id); - let matrix_room_id = self.matrix_api.create_room(channel.name.clone(), Some(room_alias_name), &room_creator_id)?; + let room_alias_name = format!("{}_{}_{}", self.config.sender_localpart, rocketchat_server_id, rocketchat_room_id); + let matrix_room_id = self.matrix_api.create_room(room_display_name.clone(), Some(room_alias_name), &room_creator_id)?; debug!(self.logger, "Successfully created room, matrix_room_id is {}", &matrix_room_id); self.matrix_api.set_default_powerlevels(matrix_room_id.clone(), room_creator_id.clone())?; debug!(self.logger, "Successfully set powerlevels for room {}", &matrix_room_id); @@ -328,9 +336,9 @@ impl<'a> RoomHandler<'a> { debug!(self.logger, "{} successfully invited {} into room {}", &room_creator_id, &invited_user_id, &matrix_room_id); let new_room = NewRoom { matrix_room_id: matrix_room_id.clone(), - display_name: channel.name.clone().unwrap_or_else(|| channel.id.clone()), + display_name: room_display_name.unwrap_or_else(|| rocketchat_room_id.clone()), rocketchat_server_id: Some(rocketchat_server_id), - rocketchat_room_id: Some(channel.id.clone()), + rocketchat_room_id: Some(rocketchat_room_id), is_admin_room: false, is_bridged: true, is_direct_message_room: is_direct_message_room, diff --git a/src/matrix-rocketchat/handlers/rocketchat/forwarder.rs b/src/matrix-rocketchat/handlers/rocketchat/forwarder.rs index e9140a1..acb3ad0 100644 --- a/src/matrix-rocketchat/handlers/rocketchat/forwarder.rs +++ b/src/matrix-rocketchat/handlers/rocketchat/forwarder.rs @@ -5,6 +5,7 @@ use diesel::sqlite::SqliteConnection; use slog::Logger; use ruma_identifiers::RoomId; +use i18n::*; use api::{MatrixApi, RocketchatApi}; use api::rocketchat::Message; use config::Config; @@ -61,7 +62,6 @@ impl<'a> Forwarder<'a> { )? { Some(ref mut room) if room.is_direct_message_room => { debug!(self.logger, "Got a message for a direct message room (channel_id `{}`)", &message.channel_id); - let bot_matrix_user_id = self.config.matrix_bot_user_id()?; let receiver_matrix_user_id = match self.find_matching_user_for_direct_message(rocketchat_server, message)? { Some(user_on_rocketchat_server) => user_on_rocketchat_server.matrix_user_id.clone(), None => { @@ -73,8 +73,15 @@ impl<'a> Forwarder<'a> { return Ok(()); } }; - self.matrix_api.invite(room.matrix_room_id.clone(), receiver_matrix_user_id, bot_matrix_user_id)?; - room.set_is_bridged(self.connection, true)?; + + if !room.is_bridged { + self.matrix_api.invite( + room.matrix_room_id.clone(), + receiver_matrix_user_id, + user_on_rocketchat_server.matrix_user_id.clone(), + )?; + room.set_is_bridged(self.connection, true)?; + } room.matrix_room_id.clone() } Some(ref room) if room.is_bridged => room.matrix_room_id.clone(), @@ -182,11 +189,16 @@ impl<'a> Forwarder<'a> { )?; let room_handler = RoomHandler::new(self.config, self.connection, self.logger, self.matrix_api); + let direct_message_receiver = user_on_rocketchat_server.user(self.connection)?; + let room_display_name_suffix = + t!(["defaults", "direct_message_room_display_name_suffix"]).l(&direct_message_receiver.language); + let room_display_name = format!("{} {}", message.user_name, room_display_name_suffix); let room = room_handler.create_room( - direct_message_channel, + direct_message_channel.id.clone(), rocketchat_server.id.clone(), direct_message_sender.matrix_user_id.clone(), user_on_rocketchat_server.matrix_user_id.clone(), + Some(room_display_name), true, )?; debug!(self.logger, "Direct message room {} successfully created", &room.matrix_room_id); diff --git a/tests/forward_rocketchat_direct_message_to_matrix.rs b/tests/forward_rocketchat_direct_message_to_matrix.rs index 587631c..8a01bea 100644 --- a/tests/forward_rocketchat_direct_message_to_matrix.rs +++ b/tests/forward_rocketchat_direct_message_to_matrix.rs @@ -72,12 +72,13 @@ fn successfully_forwards_a_direct_message() { helpers::join( &test.config.as_url, - RoomId::try_from("!1234_id:localhost").unwrap(), + RoomId::try_from("!other_userDMRocketChat_id:localhost").unwrap(), UserId::try_from("@spec_user:localhost").unwrap(), ); let create_room_message = create_room_receiver.recv_timeout(default_timeout()).unwrap(); assert!(create_room_message.contains("\"room_alias_name\":\"rocketchat_rc_id_spec_user_id_other_user_id\"")); + assert!(create_room_message.contains("\"name\":\"other_user (DM Rocket.Chat)\"")); // discard bot registration register_receiver.recv_timeout(default_timeout()).unwrap(); @@ -168,13 +169,13 @@ fn the_bot_user_stays_in_the_direct_message_room_if_the_user_leaves() { helpers::join( &test.config.as_url, - RoomId::try_from("!1234_id:localhost").unwrap(), + RoomId::try_from("!other_userDMRocketChat_id:localhost").unwrap(), UserId::try_from("@spec_user:localhost").unwrap(), ); helpers::leave_room( &test.config.as_url, - RoomId::try_from("!1234_id:localhost").unwrap(), + RoomId::try_from("!other_userDMRocketChat_id:localhost").unwrap(), UserId::try_from("@spec_user:localhost").unwrap(), ); @@ -248,13 +249,13 @@ fn successfully_forwards_a_direct_message_to_a_room_that_was_bridged_before() { helpers::join( &test.config.as_url, - RoomId::try_from("!1234_id:localhost").unwrap(), + RoomId::try_from("!other_userDMRocketChat_id:localhost").unwrap(), UserId::try_from("@spec_user:localhost").unwrap(), ); helpers::leave_room( &test.config.as_url, - RoomId::try_from("!1234_id:localhost").unwrap(), + RoomId::try_from("!other_userDMRocketChat_id:localhost").unwrap(), UserId::try_from("@spec_user:localhost").unwrap(), ); @@ -283,7 +284,7 @@ fn successfully_forwards_a_direct_message_to_a_room_that_was_bridged_before() { helpers::join( &test.config.as_url, - RoomId::try_from("!1234_id:localhost").unwrap(), + RoomId::try_from("!other_userDMRocketChat_id:localhost").unwrap(), UserId::try_from("@spec_user:localhost").unwrap(), ); @@ -350,13 +351,13 @@ fn do_not_forwards_a_direct_message_to_a_room_if_the_user_is_no_longer_logged_in helpers::join( &test.config.as_url, - RoomId::try_from("!1234_id:localhost").unwrap(), + RoomId::try_from("!other_userDMRocketChat_id:localhost").unwrap(), UserId::try_from("@spec_user:localhost").unwrap(), ); helpers::leave_room( &test.config.as_url, - RoomId::try_from("!1234_id:localhost").unwrap(), + RoomId::try_from("!other_userDMRocketChat_id:localhost").unwrap(), UserId::try_from("@spec_user:localhost").unwrap(), ); diff --git a/tests/matrix-rocketchat-test/handlers.rs b/tests/matrix-rocketchat-test/handlers.rs index 98df14f..7359afa 100644 --- a/tests/matrix-rocketchat-test/handlers.rs +++ b/tests/matrix-rocketchat-test/handlers.rs @@ -31,7 +31,7 @@ impl Handler for RocketchatInfo { let payload = r#"{ "version": "VERSION" }"# - .replace("VERSION", self.version); + .replace("VERSION", self.version); Ok(Response::with((status::Ok, payload))) } @@ -49,23 +49,27 @@ impl Handler for RocketchatLogin { true => { let user_id: String = self.rocketchat_user_id.clone().unwrap_or(thread_rng().gen_ascii_chars().take(10).collect()); - (status::Ok, - r#"{ + ( + status::Ok, + r#"{ "status": "success", "data": { "authToken": "spec_auth_token", "userId": "USER_ID" } }"# - .replace("USER_ID", &user_id)) + .replace("USER_ID", &user_id), + ) } false => { - (status::Unauthorized, - r#"{ + ( + status::Unauthorized, + r#"{ "status": "error", "message": "Unauthorized" }"# - .to_string()) + .to_string(), + ) } }; @@ -82,7 +86,7 @@ impl Handler for RocketchatMe { let payload = r#"{ "username": "USERNAME" }"# - .replace("USERNAME", &self.username); + .replace("USERNAME", &self.username); Ok(Response::with((status::Ok, payload))) } @@ -115,8 +119,8 @@ impl Handler for RocketchatChannelsList { "sysMes": true, "_updatedAt": "2017-02-12T13:20:22.092Z" }"# - .replace("CHANNEL_NAME", channel_name) - .replace("CHANNEL_USERNAMES", &user_names.join("\",\"")); + .replace("CHANNEL_NAME", channel_name) + .replace("CHANNEL_USERNAMES", &user_names.join("\",\"")); channels.push(channel); } @@ -146,8 +150,8 @@ impl Handler for RocketchatDirectMessagesList { "usernames": [ "USER_NAMES" ]}"# - .replace("DIRECT_MESSAGE_ID", id) - .replace("USER_NAMES", &user_names.join("\",\"")); + .replace("DIRECT_MESSAGE_ID", id) + .replace("USER_NAMES", &user_names.join("\",\"")); dms.push(dm); } @@ -168,8 +172,9 @@ impl Handler for RocketchatUsersInfo { let (status, payload) = match query_pairs.find(|&(ref key, _)| key == "username") { Some((_, ref username)) => { - (status::Ok, - r#"{ + ( + status::Ok, + r#"{ "user": { "name": "Name USERNAME", "username": "USERNAME", @@ -181,16 +186,19 @@ impl Handler for RocketchatUsersInfo { }, "success": true }"# - .replace("USERNAME", username)) + .replace("USERNAME", username), + ) } None => { - (status::BadRequest, - r#"{ + ( + status::BadRequest, + r#"{ "success": false, "error": "The required \"userId\" or \"username\" param was not provided [error-user-param-not-provided]", "errorType": "error-user-param-not-provided" }"# - .to_string()) + .to_string(), + ) } }; @@ -279,14 +287,22 @@ impl Handler for MatrixCreateRoom { let request_payload = extract_payload(request); let create_room_payload: create_room::BodyParams = serde_json::from_str(&request_payload).unwrap(); - let room_id = RoomId::try_from(&format!("!{}_id:localhost", create_room_payload.name.unwrap_or("1234".to_string()))) - .unwrap(); + let room_id_local_part: String = create_room_payload + .name + .unwrap_or("1234".to_string()) + .chars() + .into_iter() + .filter(|c| c.is_alphanumeric() || c == &'_') + .collect(); + let test_room_id = format!("!{}_id:localhost", &room_id_local_part); + let room_id = RoomId::try_from(&test_room_id).unwrap(); let url: Url = request.url.clone().into(); let mut query_pairs = url.query_pairs(); - let (_, user_id_param) = - query_pairs.find(|&(ref key, _)| key == "user_id").unwrap_or((Cow::from("user_id"), - Cow::from("@rocketchat:localhost"))); + let (_, user_id_param) = query_pairs.find(|&(ref key, _)| key == "user_id").unwrap_or(( + Cow::from("user_id"), + Cow::from("@rocketchat:localhost"), + )); let user_id = UserId::try_from(user_id_param.borrow()).unwrap(); // join event that is triggered when the room creator enters the room @@ -369,9 +385,10 @@ impl Handler for MatrixJoinRoom { let url: Url = request.url.clone().into(); let mut query_pairs = url.query_pairs(); - let (_, user_id_param) = - query_pairs.find(|&(ref key, _)| key == "user_id").unwrap_or((Cow::from("user_id"), - Cow::from("@rocketchat:localhost"))); + let (_, user_id_param) = query_pairs.find(|&(ref key, _)| key == "user_id").unwrap_or(( + Cow::from("user_id"), + Cow::from("@rocketchat:localhost"), + )); let user_id = UserId::try_from(user_id_param.borrow()).unwrap(); helpers::join(&self.as_url, room_id, user_id); @@ -402,9 +419,10 @@ impl Handler for MatrixLeaveRoom { let url: Url = request.url.clone().into(); let mut query_pairs = url.query_pairs(); - let (_, user_id_param) = - query_pairs.find(|&(ref key, _)| key == "user_id").unwrap_or((Cow::from("user_id"), - Cow::from("@rocketchat:localhost"))); + let (_, user_id_param) = query_pairs.find(|&(ref key, _)| key == "user_id").unwrap_or(( + Cow::from("user_id"), + Cow::from("@rocketchat:localhost"), + )); let user_id = UserId::try_from(user_id_param.borrow()).unwrap(); helpers::leave_room(&self.as_url, room_id, user_id);