~singpolyma/biboumi

272c0e4995f2fe94fb2366c15453fdada341861a — louiz’ 8 years ago 7540f67
Reset the preferred private JID when all resources leave a room

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!!!
3 files changed, 35 insertions(+), 1 deletions(-)

M src/bridge/bridge.cpp
M src/bridge/bridge.hpp
M tests/end_to_end/__main__.py
M src/bridge/bridge.cpp => src/bridge/bridge.cpp +18 -1
@@ 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));

M src/bridge/bridge.hpp => src/bridge/bridge.hpp +5 -0
@@ 186,6 186,11 @@ public:
   */
  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.
   */
  void add_waiting_irc(irc_responder_callback_t&& callback);

M tests/end_to_end/__main__.py => tests/end_to_end/__main__.py +12 -0
@@ 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, "<message from='{jid_two}/{resource_one}' to='{lower_nick_one}!{irc_server_one}' type='chat'><body>re</body></message>"),
                     # 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,
                     "<presence from='{jid_one}/{resource_one}' to='%{irc_server_one}/{nick_one}' type='unavailable' />"),
                     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, "<message from='{jid_two}/{resource_one}' to='{lower_nick_one}!{irc_server_one}' type='chat'><body>hihihoho</body></message>"),
                     partial(expect_stanza,
                     "/message[@from='{lower_nick_two}!{irc_server_one}'][@to='{jid_one}/{resource_one}']"),
                 ]
                 )
    )