~singpolyma/biboumi

12c8b1ae0b6f4c2b80d7c787b892ebcaafae6b03 — Florent Le Coz 10 years ago 712b7bd
Disconnect the user from all its IRC servers whenever he returns an error

fix #2524
3 files changed, 34 insertions(+), 4 deletions(-)

M src/bridge/bridge.cpp
M src/bridge/bridge.hpp
M src/xmpp/xmpp_component.cpp
M src/bridge/bridge.cpp => src/bridge/bridge.cpp +1 -2
@@ 41,11 41,10 @@ static std::tuple<std::string, std::string> get_role_affiliation_from_irc_mode(c
    return std::make_tuple("participant", "none");
}

void Bridge::shutdown()
void Bridge::shutdown(const std::string& exit_message)
{
  for (auto it = this->irc_clients.begin(); it != this->irc_clients.end(); ++it)
  {
    const std::string exit_message("Gateway shutdown");
    it->second->send_quit_command(exit_message);
    it->second->leave_dummy_channel(exit_message);
  }

M src/bridge/bridge.hpp => src/bridge/bridge.hpp +2 -1
@@ 27,11 27,12 @@ public:
  /**
   * QUIT all connected IRC servers.
   */
  void shutdown();
  void shutdown(const std::string& exit_message);
  /**
   * Remove all inactive IrcClients
   */
  void clean();

  static Xmpp::body make_xmpp_body(const std::string& str);
  /***
   **

M src/xmpp/xmpp_component.cpp => src/xmpp/xmpp_component.cpp +31 -1
@@ 34,6 34,19 @@ using namespace std::string_literals;

unsigned long XmppComponent::current_id = 0;

static std::set<std::string> kickable_errors{
    "gone",
    "internal-server-error",
    "item-not-found",
    "jid-malformed",
    "recipient-unavailable",
    "redirect",
    "remote-server-not-found",
    "remote-server-timeout",
    "service-unavailable",
    "malformed-error"
    };

XmppComponent::XmppComponent(const std::string& hostname, const std::string& secret):
  ever_auth(false),
  last_auth(false),


@@ 128,7 141,7 @@ void XmppComponent::shutdown()
{
  for (auto it = this->bridges.begin(); it != this->bridges.end(); ++it)
  {
    it->second->shutdown();
    it->second->shutdown("Gateway shutdown");
  }
}



@@ 359,6 372,23 @@ void XmppComponent::handle_message(const Stanza& stanza)
      if (subject)
        bridge->set_channel_topic(iid, subject->get_inner());
    }
  else if (type == "error")
    {
      const XmlNode* error = stanza.get_child(COMPONENT_NS":error");
      // Only a set of errors are considered “fatal”. If we encounter one of
      // them, we purge (we disconnect the user from all the IRC servers).
      // We consider this to be true, unless the error condition is
      // specified and is not in the kickable_errors set
      bool kickable_error = true;
      if (error)
        {
          const XmlNode* condition = error->get_last_child();
          if (kickable_errors.find(condition->get_name()) == kickable_errors.end())
              kickable_error = false;
        }
      if (kickable_error)
        bridge->shutdown("Error from remote client");
    }
  else
    {
      if (body && !body->get_inner().empty())