From e47b164a43e0c4f411869fbbefe875fd70df8506 Mon Sep 17 00:00:00 2001
From: Florent Le Coz <louiz@louiz.org>
Date: Mon, 24 Mar 2014 21:08:09 +0100
Subject: Send an error presence whenever a user tries to join an invalid room

---
 src/xmpp/xmpp_component.cpp | 41 ++++++++++++++++++++++++++++++++++++++++-
 src/xmpp/xmpp_component.hpp |  6 ++++++
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index d083190..a2c6c2b 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -231,7 +231,7 @@ void XmppComponent::handle_presence(const Stanza& stanza)
   }
   catch (const AttributeNotFound&) {}
 
-  if (!iid.chan.empty() && !iid.chan.empty())
+  if (!iid.chan.empty() && !iid.server.empty())
     { // presence toward a MUC that corresponds to an irc channel
       if (type.empty())
         {
@@ -246,6 +246,12 @@ void XmppComponent::handle_presence(const Stanza& stanza)
           bridge->leave_irc_channel(std::move(iid), status ? std::move(status->get_inner()) : "");
         }
     }
+  else
+    {
+      // An user wants to join an invalid IRC channel, return a presence error to him
+      if (type.empty())
+        this->send_invalid_room_error(to.local, to.resource, stanza["from"]);
+    }
 }
 
 void XmppComponent::handle_message(const Stanza& stanza)
@@ -392,6 +398,39 @@ void XmppComponent::send_user_join(const std::string& from,
   this->send_stanza(node);
 }
 
+void XmppComponent::send_invalid_room_error(const std::string& muc_name,
+                                            const std::string& nick,
+                                            const std::string& to)
+{
+  Stanza presence("presence");
+  presence["from"] = muc_name + "@" + this->served_hostname + "/" + nick;
+  presence["to"] = to;
+  presence["type"] = "error";
+  XmlNode x("x");
+  x["xmlns"] = MUC_NS;
+  x.close();
+  presence.add_child(std::move(x));
+  XmlNode error("error");
+  error["by"] = muc_name + "@" + this->served_hostname;
+  error["type"] = "wait";
+  XmlNode service_unavailable("service-unavailable");
+  service_unavailable["xmlns"] = STANZA_NS;
+  service_unavailable.close();
+  error.add_child(std::move(service_unavailable));
+  XmlNode text("text");
+  text["xmlns"] = STANZA_NS;
+  text["xml:lang"] = "en";
+  text.set_inner(muc_name +
+                 " is not a valid IRC channel name. A correct room jid is of the form: #<chan>%<server>@" +
+                 this->served_hostname);
+  text.close();
+  error.add_child(std::move(text));
+  error.close();
+  presence.add_child(std::move(error));
+  presence.close();
+  this->send_stanza(presence);
+}
+
 void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, const std::string& to)
 {
   XmlNode message("message");
diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp
index 373104c..d4853c8 100644
--- a/src/xmpp/xmpp_component.hpp
+++ b/src/xmpp/xmpp_component.hpp
@@ -86,6 +86,12 @@ public:
                       const std::string& role,
                       const std::string& to,
                       const bool self);
+  /**
+   * Send an error to indicate that the user tried to join an invalid room
+   */
+  void send_invalid_room_error(const std::string& muc_jid,
+                               const std::string& nick,
+                               const std::string& to);
   /**
    * Send the MUC topic to the user
    */
-- 
cgit v1.2.3