diff --git a/src/matrix-rocketchat/handlers/rocketchat/forwarder.rs b/src/matrix-rocketchat/handlers/rocketchat/forwarder.rs index ebdd2bb..bc9d146 100644 --- a/src/matrix-rocketchat/handlers/rocketchat/forwarder.rs +++ b/src/matrix-rocketchat/handlers/rocketchat/forwarder.rs @@ -32,13 +32,11 @@ impl<'a> Forwarder<'a> { pub fn send(&self, rocketchat_server: &RocketchatServer, message: &Message) -> Result<()> { let user_on_rocketchat_server = match UserOnRocketchatServer::find_by_rocketchat_user_id(self.connection, rocketchat_server.id, - message.user_id - .clone(), + message.user_id.clone(), true)? { Some(user_on_rocketchat_server) => user_on_rocketchat_server, None => { - self.connection - .transaction(|| self.create_virtual_user_on_rocketchat_server(rocketchat_server.id, message))? + self.connection.transaction(|| self.create_virtual_user_on_rocketchat_server(rocketchat_server.id, message))? } }; @@ -48,10 +46,10 @@ impl<'a> Forwarder<'a> { return Ok(()); } - let room = + let matrix_room_id = match Room::find_by_rocketchat_room_id(self.connection, rocketchat_server.id, message.channel_id.clone())? { - Some(room) => room, - None => { + Some(ref room) if room.is_bridged => room.matrix_room_id.clone(), + _ => { debug!(self.logger, "Ignoring message from Rocket.Chat channel `{}`, because the channel is not bridged.", message.channel_id); @@ -70,17 +68,14 @@ impl<'a> Forwarder<'a> { } - let user_in_room = - UserInRoom::find_by_matrix_user_id_and_matrix_room_id(self.connection, - &user_on_rocketchat_server.matrix_user_id, - &room.matrix_room_id)?; + let user_in_room = UserInRoom::find_by_matrix_user_id_and_matrix_room_id(self.connection, + &user_on_rocketchat_server.matrix_user_id, + &matrix_room_id)?; if user_in_room.is_none() { - self.add_virtual_user_to_room(user_on_rocketchat_server.matrix_user_id.clone(), room.matrix_room_id.clone())?; + self.add_virtual_user_to_room(user_on_rocketchat_server.matrix_user_id.clone(), matrix_room_id.clone())?; } - self.matrix_api.send_text_message_event(room.matrix_room_id, - user_on_rocketchat_server.matrix_user_id, - message.text.clone()) + self.matrix_api.send_text_message_event(matrix_room_id, user_on_rocketchat_server.matrix_user_id, message.text.clone()) } fn create_virtual_user_on_rocketchat_server(&self, @@ -141,10 +136,8 @@ impl<'a> Forwarder<'a> { false)? { Some(user_on_rocketchat_server) => { let user = user_on_rocketchat_server.user(self.connection)?; - let now = SystemTime::now() - .duration_since(UNIX_EPOCH) - .chain_err(|| ErrorKind::InternalServerError)? - .as_secs() as i64; + let now = + SystemTime::now().duration_since(UNIX_EPOCH).chain_err(|| ErrorKind::InternalServerError)?.as_secs() as i64; let last_sent = now - user.last_message_sent; Ok(last_sent > RESEND_THRESHOLD_IN_SECONDS) } diff --git a/tests/forward_rocketchat_to_matrix.rs b/tests/forward_rocketchat_to_matrix.rs index 2d24e51..590c24f 100644 --- a/tests/forward_rocketchat_to_matrix.rs +++ b/tests/forward_rocketchat_to_matrix.rs @@ -87,9 +87,8 @@ fn successfully_forwards_a_text_message_from_rocketchat_to_matrix_when_the_user_ let connection = test.connection_pool.get().unwrap(); let admin_room = Room::find(&connection, &RoomId::try_from("!admin:localhost").unwrap()).unwrap(); let rocketchat_server_id = admin_room.rocketchat_server_id.unwrap(); - let bridged_room = Room::find_by_rocketchat_room_id(&connection, rocketchat_server_id, "spec_channel_id".to_string()) - .unwrap() - .unwrap(); + let bridged_room = + Room::find_by_rocketchat_room_id(&connection, rocketchat_server_id, "spec_channel_id".to_string()).unwrap().unwrap(); // the bot, the user who bridged the channel and the virtual user are in the channel let users = bridged_room.users(&connection).unwrap(); @@ -191,9 +190,8 @@ fn successfully_forwards_a_text_message_from_rocketchat_to_matrix_when_the_user_ let connection = test.connection_pool.get().unwrap(); let admin_room = Room::find(&connection, &RoomId::try_from("!admin:localhost").unwrap()).unwrap(); let rocketchat_server_id = admin_room.rocketchat_server_id.unwrap(); - let bridged_room = Room::find_by_rocketchat_room_id(&connection, rocketchat_server_id, "spec_channel_id".to_string()) - .unwrap() - .unwrap(); + let bridged_room = + Room::find_by_rocketchat_room_id(&connection, rocketchat_server_id, "spec_channel_id".to_string()).unwrap().unwrap(); // the bot, the user who bridged the channel and the virtual user are in the channel let users = bridged_room.users(&connection).unwrap(); @@ -480,6 +478,62 @@ fn ignore_messages_forwarded_from_rocketchat_if_the_non_virtual_user_just_sent_a assert!(receiver.recv_timeout(default_timeout()).is_err()); } +#[test] +fn do_not_forward_messages_when_the_channel_was_bridged_but_is_unbridged_now() { + let (message_forwarder, receiver) = MessageForwarder::new(); + let mut matrix_router = Router::new(); + matrix_router.put(SendMessageEventEndpoint::router_path(), message_forwarder, "send_message_event"); + matrix_router.put(SetDisplayNameEndpoint::router_path(), + handlers::MatrixErrorResponder { + status: status::InternalServerError, + message: "Could not set display name".to_string(), + }, + "set_display_name"); + + let test = Test::new() + .with_matrix_routes(matrix_router) + .with_rocketchat_mock() + .with_connected_admin_room() + .with_logged_in_user() + .with_bridged_room(("spec_channel", "spec_user")) + .run(); + + helpers::leave_room(&test.config.as_url, + RoomId::try_from("!spec_channel_id:localhost").unwrap(), + UserId::try_from("@spec_user:localhost").unwrap()); + + helpers::send_room_message_from_matrix(&test.config.as_url, + RoomId::try_from("!admin:localhost").unwrap(), + UserId::try_from("@spec_user:localhost").unwrap(), + "unbridge spec_channel".to_string()); + + let message = Message { + message_id: "spec_id".to_string(), + token: Some(RS_TOKEN.to_string()), + channel_id: "spec_channel_id".to_string(), + channel_name: "spec_channel".to_string(), + user_id: "virtual_spec_user_id".to_string(), + user_name: "virtual_spec_user".to_string(), + text: "spec_message".to_string(), + }; + let payload = to_string(&message).unwrap(); + + helpers::simulate_message_from_rocketchat(&test.config.as_url, &payload); + + // discard welcome message + receiver.recv_timeout(default_timeout()).unwrap(); + // discard connect message + receiver.recv_timeout(default_timeout()).unwrap(); + // discard login message + receiver.recv_timeout(default_timeout()).unwrap(); + // discard room bridged message + receiver.recv_timeout(default_timeout()).unwrap(); + // discard room unbridged message + receiver.recv_timeout(default_timeout()).unwrap(); + + assert!(receiver.recv_timeout(default_timeout()).is_err()); +} + #[test] fn returns_unauthorized_when_the_rs_token_is_missing() { let test = Test::new().run();