diff --git a/src/matrix-rocketchat/db/user_on_rocketchat_server.rs b/src/matrix-rocketchat/db/user_on_rocketchat_server.rs index 619ea55..b7bea5f 100644 --- a/src/matrix-rocketchat/db/user_on_rocketchat_server.rs +++ b/src/matrix-rocketchat/db/user_on_rocketchat_server.rs @@ -38,13 +38,28 @@ pub struct NewUserOnRocketchatServer { } impl UserOnRocketchatServer { - /// Insert a new `UserOnRocketchatServer` into the database. - pub fn insert(connection: &SqliteConnection, + /// Insert or update a `UserOnRocketchatServer`. + pub fn upsert(connection: &SqliteConnection, user_on_rocketchat_server: &NewUserOnRocketchatServer) -> Result { - diesel::insert(user_on_rocketchat_server).into(users_on_rocketchat_servers::table) - .execute(connection) - .chain_err(|| ErrorKind::DBInsertError)?; + let users_on_rocketchat_server: Vec = users_on_rocketchat_servers::table + .find((&user_on_rocketchat_server.matrix_user_id, &user_on_rocketchat_server.rocketchat_server_id)) + .load(connection).chain_err(|| ErrorKind::DBSelectError)?; + + match users_on_rocketchat_server.into_iter().next() { + Some(existing_user_on_rocketchat_server) => { + existing_user_on_rocketchat_server.set_credentials(connection, + user_on_rocketchat_server.rocketchat_user_id.clone(), + user_on_rocketchat_server.rocketchat_auth_token.clone())?; + } + None => { + diesel::insert(user_on_rocketchat_server).into(users_on_rocketchat_servers::table) + .execute(connection) + .chain_err(|| ErrorKind::DBInsertError)?; + } + } + + UserOnRocketchatServer::find(connection, &user_on_rocketchat_server.matrix_user_id, user_on_rocketchat_server.rocketchat_server_id) @@ -65,8 +80,8 @@ impl UserOnRocketchatServer { /// Update the users credentials. pub fn set_credentials(&self, connection: &SqliteConnection, - rocketchat_user_id: String, - rocketchat_auth_token: String) + rocketchat_user_id: Option, + rocketchat_auth_token: Option) -> Result<()> { diesel::update(users_on_rocketchat_servers::table.find((&self.matrix_user_id, self.rocketchat_server_id))) .set((users_on_rocketchat_servers::rocketchat_user_id.eq(rocketchat_user_id), diff --git a/src/matrix-rocketchat/handlers/events/command_handler.rs b/src/matrix-rocketchat/handlers/events/command_handler.rs index ed007a7..334f095 100644 --- a/src/matrix-rocketchat/handlers/events/command_handler.rs +++ b/src/matrix-rocketchat/handlers/events/command_handler.rs @@ -96,7 +96,7 @@ impl<'a> CommandHandler<'a> { rocketchat_auth_token: None, }; - UserOnRocketchatServer::insert(self.connection, &new_user_on_rocketchat_server)?; + UserOnRocketchatServer::upsert(self.connection, &new_user_on_rocketchat_server)?; let user = User::find(self.connection, &event.user_id)?; let body = t!(["admin_room", "login_instructions"]) @@ -184,7 +184,7 @@ impl<'a> CommandHandler<'a> { self.logger.clone())?; let (rocketchat_user_id, rocketchat_auth_token) = rocketchat_api.login(username, &password)?; - user_on_rocketchat_server.set_credentials(self.connection, rocketchat_user_id, rocketchat_auth_token)?; + user_on_rocketchat_server.set_credentials(self.connection, Some(rocketchat_user_id), Some(rocketchat_auth_token))?; let matrix_user_id = self.config.matrix_bot_user_id()?; let message = t!(["admin_room", "bridge_instructions"]); diff --git a/tests/admin_commands_login.rs b/tests/admin_commands_login.rs index 7ed774b..762937e 100644 --- a/tests/admin_commands_login.rs +++ b/tests/admin_commands_login.rs @@ -116,6 +116,55 @@ fn login_multiple_times() { assert!(message_received_by_matrix.contains("You are logged in.")); } +#[test] +fn the_user_can_login_again_on_the_same_server_with_a_new_admin_room() { + let (message_forwarder, receiver) = MessageForwarder::new(); + let mut matrix_router = Router::new(); + matrix_router.put(SendMessageEventEndpoint::router_path(), message_forwarder, "send_message_event"); + let mut rocketchat_router = Router::new(); + rocketchat_router.post(LOGIN_PATH, handlers::RocketchatLogin { successful: true }, "login"); + let test = Test::new() + .with_matrix_routes(matrix_router) + .with_rocketchat_mock() + .with_custom_rocketchat_routes(rocketchat_router) + .with_connected_admin_room() + .with_logged_in_user() + .run(); + + helpers::leave_room(&test.config.as_url, + RoomId::try_from("!admin:localhost").unwrap(), + UserId::try_from("@spec_user:localhost").unwrap()); + + helpers::create_admin_room(&test.config.as_url, + RoomId::try_from("!admin:localhost").unwrap(), + UserId::try_from("@spec_user:localhost").unwrap(), + UserId::try_from("@rocketchat: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(), + format!("connect {}", test.rocketchat_mock_url.clone().unwrap())); + + helpers::send_room_message_from_matrix(&test.config.as_url, + RoomId::try_from("!admin:localhost").unwrap(), + UserId::try_from("@spec_user:localhost").unwrap(), + "login spec_user secret".to_string()); + + // discard first welcome message + receiver.recv_timeout(default_timeout()).unwrap(); + // discard first connect message + receiver.recv_timeout(default_timeout()).unwrap(); + // discard first login message + receiver.recv_timeout(default_timeout()).unwrap(); + // discard second welcome message + receiver.recv_timeout(default_timeout()).unwrap(); + // discard second connect message + receiver.recv_timeout(default_timeout()).unwrap(); + + let message_received_by_matrix = receiver.recv_timeout(default_timeout()).unwrap(); + assert!(message_received_by_matrix.contains("You are logged in.")); +} + #[test] fn server_does_not_respond_when_logging_in_via_chat_mesage() { let (message_forwarder, receiver) = MessageForwarder::new();