~singpolyma/biboumi

4792c70635cd73d581861a6da9794655a5e72099 — louiz’ 6 years ago 2e4a9fe
Send a presence error from the room, when receiving command ERR_BADCHANNELKEY

fix #2886
3 files changed, 56 insertions(+), 1 deletions(-)

M src/irc/irc_client.cpp
M src/irc/irc_client.hpp
M tests/end_to_end/__main__.py
M src/irc/irc_client.cpp => src/irc/irc_client.cpp +13 -1
@@ 66,6 66,7 @@ static const std::unordered_map<std::string,
  {"433", {&IrcClient::on_nickname_conflict, {2, 0}}},
  {"438", {&IrcClient::on_nickname_change_too_fast, {2, 0}}},
  {"443", {&IrcClient::on_useronchannel, {3, 0}}},
  {"475", {&IrcClient::on_channel_bad_key, {3, 0}}},
  {"ERR_USERONCHANNEL", {&IrcClient::on_useronchannel, {3, 0}}},
  {"001", {&IrcClient::on_welcome_message, {1, 0}}},
  {"PART", {&IrcClient::on_part, {1, 0}}},


@@ 113,7 114,6 @@ static const std::unordered_map<std::string,
  {"472", {&IrcClient::on_generic_error, {2, 0}}},
  {"473", {&IrcClient::on_generic_error, {2, 0}}},
  {"474", {&IrcClient::on_generic_error, {2, 0}}},
  {"475", {&IrcClient::on_generic_error, {2, 0}}},
  {"476", {&IrcClient::on_generic_error, {2, 0}}},
  {"477", {&IrcClient::on_generic_error, {2, 0}}},
  {"481", {&IrcClient::on_generic_error, {2, 0}}},


@@ 1014,6 1014,18 @@ void IrcClient::on_mode(const IrcMessage& message)
    this->on_user_mode(message);
}

void IrcClient::on_channel_bad_key(const IrcMessage& message)
{
  this->on_generic_error(message);
  const std::string& nickname = message.arguments[0];
  const std::string& channel = message.arguments[1];
  std::string text;
  if (message.arguments.size() > 2)
    text = message.arguments[2];

  this->bridge.send_presence_error({channel, this->hostname, Iid::Type::Channel}, nickname, "auth", "not-authorized", "", text);
}

void IrcClient::on_channel_mode(const IrcMessage& message)
{
  // For now, just transmit the modes so the user can know what happens

M src/irc/irc_client.hpp => src/irc/irc_client.hpp +1 -0
@@ 257,6 257,7 @@ public:
  void on_nick(const IrcMessage& message);
  void on_kick(const IrcMessage& message);
  void on_mode(const IrcMessage& message);
  void on_channel_bad_key(const IrcMessage& message);
  /**
   * A mode towards our own user is received (note, that is different from a
   * channel mode towards or own nick, see

M tests/end_to_end/__main__.py => tests/end_to_end/__main__.py +42 -0
@@ 554,6 554,48 @@ if __name__ == '__main__':
                         ("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]",),
                         ]),
                 ]),
        Scenario("channel_join_with_password",
                 [
                     handshake_sequence(),
                     # First user joins
                     partial(send_stanza,
                             "<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
                     connection_sequence("irc.localhost", '{jid_one}/{resource_one}'),
                     partial(expect_stanza,
                             "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
                     partial(expect_stanza,
                             ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@jid='~nick@localhost'][@role='moderator']",
                              "/presence/muc_user:x/muc_user:status[@code='110']")
                             ),
                     partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),

                     # Set a password in the room, by using /mode +k
                     partial(send_stanza, "<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>/mode +k SECRET</body></message>"),
                     partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='Mode #foo [+k SECRET] by {nick_one}']"),

                     # Second user tries to join, without a password
                     partial(send_stanza,
                             "<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}'/>"),
                     connection_sequence("irc.localhost", '{jid_two}/{resource_one}'),

                     partial(expect_stanza, "/message/body[text()='{irc_host_one}: #foo: Cannot join channel (+k) - bad key']"),
                     partial(expect_stanza,
                             "/presence[@type='error'][@from='#foo%{irc_server_one}/{nick_two}']/error[@type='auth']/stanza:not-authorized",
                     ),

                     # Second user joins, with a password
                     partial(send_stanza,
                             "<presence from='{jid_two}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}'>  <x xmlns='http://jabber.org/protocol/muc'><password>SECRET</password></x></presence>"),
                     # connection_sequence("irc.localhost", '{jid_two}/{resource_one}'),
                     partial(expect_unordered, [
                         ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@role='participant'][@jid='~bobby@localhost']",),
                         ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",),
                         ("/presence[@to='{jid_two}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_two}']/muc_user:x/muc_user:item[@affiliation='none'][@jid='~bobby@localhost'][@role='participant']",
                          "/presence/muc_user:x/muc_user:status[@code='110']",),
                         ("/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]",),
                     ]),

                 ]),
        Scenario("channel_custom_topic",
                 [
                     handshake_sequence(),