summaryrefslogtreecommitdiff
path: root/src/xmpp
diff options
context:
space:
mode:
authorFlorent Le Coz <louiz@louiz.org>2013-11-13 01:24:36 +0100
committerFlorent Le Coz <louiz@louiz.org>2013-11-13 01:24:36 +0100
commit0859801230f999889d0f7356864888e8c5936cda (patch)
tree31b1eed96847157def5c22adb1a55abff6a3dae1 /src/xmpp
parent3cfaab9a2debe03829b1ff26fe94e775e1d18e0a (diff)
downloadbiboumi-0859801230f999889d0f7356864888e8c5936cda.tar.gz
biboumi-0859801230f999889d0f7356864888e8c5936cda.tar.bz2
biboumi-0859801230f999889d0f7356864888e8c5936cda.tar.xz
biboumi-0859801230f999889d0f7356864888e8c5936cda.zip
Handle KICK in irc channel, both ways
Diffstat (limited to 'src/xmpp')
-rw-r--r--src/xmpp/xmpp_component.cpp79
-rw-r--r--src/xmpp/xmpp_component.hpp9
2 files changed, 88 insertions, 0 deletions
diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index c36a141..2d891bc 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -14,6 +14,7 @@
#define COMPONENT_NS "jabber:component:accept"
#define MUC_NS "http://jabber.org/protocol/muc"
#define MUC_USER_NS MUC_NS"#user"
+#define MUC_ADMIN_NS MUC_NS"#admin"
#define DISCO_NS "http://jabber.org/protocol/disco"
#define DISCO_ITEMS_NS DISCO_NS"#items"
#define DISCO_INFO_NS DISCO_NS"#info"
@@ -36,6 +37,8 @@ XmppComponent::XmppComponent(const std::string& hostname, const std::string& sec
std::bind(&XmppComponent::handle_presence, this,std::placeholders::_1));
this->stanza_handlers.emplace(COMPONENT_NS":message",
std::bind(&XmppComponent::handle_message, this,std::placeholders::_1));
+ this->stanza_handlers.emplace(COMPONENT_NS":iq",
+ std::bind(&XmppComponent::handle_iq, this,std::placeholders::_1));
}
XmppComponent::~XmppComponent()
@@ -201,6 +204,46 @@ void XmppComponent::handle_message(const Stanza& stanza)
}
}
+void XmppComponent::handle_iq(const Stanza& stanza)
+{
+ Bridge* bridge = this->get_user_bridge(stanza["from"]);
+ Jid to(stanza["to"]);
+ std::string type;
+ try {
+ type = stanza["type"];
+ }
+ catch (const AttributeNotFound&)
+ { return; }
+ if (type == "set")
+ {
+ XmlNode* query;
+ if ((query = stanza.get_child(MUC_ADMIN_NS":query")))
+ {
+ XmlNode* child;
+ if ((child = query->get_child(MUC_ADMIN_NS":item")))
+ {
+ std::string nick;
+ std::string role;
+ try {
+ nick = (*child)["nick"];
+ role = (*child)["role"];
+ }
+ catch (const AttributeNotFound&)
+ { return; }
+ if (!nick.empty() && role == "none")
+ {
+ std::string reason;
+ XmlNode* reason_el = child->get_child(MUC_ADMIN_NS":reason");
+ if (reason_el)
+ reason = reason_el->get_inner();
+ Iid iid(to.local);
+ bridge->send_irc_kick(iid, nick, reason);
+ }
+ }
+ }
+ }
+}
+
Bridge* XmppComponent::get_user_bridge(const std::string& user_jid)
{
try
@@ -360,3 +403,39 @@ void XmppComponent::send_nick_change(const std::string& muc_name, const std::str
else
this->send_user_join(muc_name, new_nick, jid_to);
}
+
+void XmppComponent::kick_user(const std::string& muc_name,
+ const std::string& target,
+ const std::string& txt,
+ const std::string& author,
+ const std::string& jid_to)
+{
+ Stanza presence("presence");
+ presence["from"] = muc_name + "@" + this->served_hostname + "/" + target;
+ presence["to"] = jid_to;
+ presence["type"] = "unavailable";
+ XmlNode x("x");
+ x["xmlns"] = MUC_USER_NS;
+ XmlNode item("item");
+ item["affiliation"] = "none";
+ item["role"] = "none";
+ XmlNode actor("actor");
+ actor["nick"] = author;
+ actor["jid"] = author; // backward compatibility with old clients
+ actor.close();
+ item.add_child(std::move(actor));
+ XmlNode reason("reason");
+ reason.set_inner(txt);
+ reason.close();
+ item.add_child(std::move(reason));
+ item.close();
+ x.add_child(std::move(item));
+ XmlNode status("status");
+ status["code"] = "307";
+ status.close();
+ x.add_child(std::move(status));
+ x.close();
+ presence.add_child(std::move(x));
+ presence.close();
+ this->send_stanza(presence);
+}
diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp
index 84b19a9..0c68497 100644
--- a/src/xmpp/xmpp_component.hpp
+++ b/src/xmpp/xmpp_component.hpp
@@ -84,11 +84,20 @@ public:
*/
void send_nick_change(const std::string& muc_name, const std::string& old_nick, const std::string& new_nick, const std::string& jid_to, const bool self);
/**
+ * An user is kicked from a room
+ */
+ void kick_user(const std::string& muc_name,
+ const std::string& target,
+ const std::string& reason,
+ const std::string& author,
+ const std::string& jid_to);
+ /**
* Handle the various stanza types
*/
void handle_handshake(const Stanza& stanza);
void handle_presence(const Stanza& stanza);
void handle_message(const Stanza& stanza);
+ void handle_iq(const Stanza& stanza);
private:
/**