From 272c0e4995f2fe94fb2366c15453fdada341861a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 10 Jun 2016 10:00:48 +0200 Subject: Reset the preferred private JID when all resources leave a room MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For example if we are talking in private with nick Joe from room #foo, and then we leave that room, we start receiving Joe’s message from the server-wide JID e2e tests included!!! --- src/bridge/bridge.cpp | 19 ++++++++++++++++++- src/bridge/bridge.hpp | 5 +++++ tests/end_to_end/__main__.py | 12 ++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 95ca68e..3a7a147 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -344,7 +344,12 @@ void Bridge::leave_irc_channel(Iid&& iid, std::string&& status_message, const st const auto resources = this->number_of_resources_in_chan(key); if (resources == 1) - irc->send_part_command(iid.get_local(), status_message); + { + irc->send_part_command(iid.get_local(), status_message); + // Since there are no resources left in that channel, we don't + // want to receive private messages using this room's JID + this->remove_all_preferred_from_jid_of_room(iid.get_local()); + } else { IrcChannel* chan = irc->get_channel(iid.get_local()); @@ -767,6 +772,18 @@ void Bridge::remove_preferred_from_jid(const std::string& nick) this->preferred_user_from.erase(it); } +void Bridge::remove_all_preferred_from_jid_of_room(const std::string& channel_name) +{ + for (auto it = this->preferred_user_from.begin(); it != this->preferred_user_from.end();) + { + Iid iid(Jid(it->second).local); + if (iid.get_local() == channel_name) + it = this->preferred_user_from.erase(it); + else + ++it; + } +} + void Bridge::add_waiting_irc(irc_responder_callback_t&& callback) { this->waiting_irc.emplace_back(std::move(callback)); diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index eabd9af..01f8f78 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -185,6 +185,11 @@ public: * Remove the preferred jid for the given IRC nick */ void remove_preferred_from_jid(const std::string& nick); + /** + * Given a channel_name, remove all preferred from_jid that come + * from this chan. + */ + void remove_all_preferred_from_jid_of_room(const std::string& channel_name); /** * Add a callback to the waiting list of irc callbacks. */ diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 1408ea9..0e2ca64 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -303,6 +303,7 @@ common_replacements = { 'jid_admin': 'admin@example.com', 'nick_two': 'Bobby', 'lower_nick_one': 'nick', + 'lower_nick_two': 'bobby', } @@ -673,6 +674,17 @@ if __name__ == '__main__': partial(send_stanza, "re"), # The response is received from the in-room JID partial(expect_stanza, "/message[@from='%{irc_server_one}/{nick_two}'][@to='{jid_one}/{resource_one}'][@type='chat']/body[text()='re']"), + + # Now we leave the room, to check if the subsequent private messages are still received properly + partial(send_stanza, + ""), + partial(expect_stanza, + "/presence[@type='unavailable']/muc_user:x/muc_user:status[@code='110']"), + + # The private messages from this nick should now come (again) from the server-wide JID + partial(send_stanza, "hihihoho"), + partial(expect_stanza, + "/message[@from='{lower_nick_two}!{irc_server_one}'][@to='{jid_one}/{resource_one}']"), ] ) ) -- cgit v1.2.3