diff options
-rw-r--r-- | src/bridge/bridge.cpp | 42 | ||||
-rw-r--r-- | src/bridge/bridge.hpp | 4 | ||||
-rw-r--r-- | src/xmpp/xmpp_component.cpp | 13 | ||||
-rw-r--r-- | src/xmpp/xmpp_component.hpp | 7 |
4 files changed, 61 insertions, 5 deletions
diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index c2ac11f..384131f 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -216,11 +216,49 @@ void Bridge::send_irc_nick_change(const Iid& iid, const std::string& new_nick) irc->send_nick_command(new_nick); } -void Bridge::send_irc_kick(const Iid& iid, const std::string& target, const std::string& reason) +void Bridge::send_irc_kick(const Iid& iid, const std::string& target, const std::string& reason, + const std::string& iq_id, const std::string& to_jid) { IrcClient* irc = this->get_irc_client(iid.get_server()); if (irc) - irc->send_kick_command(iid.get_local(), target, reason); + { + irc->send_kick_command(iid.get_local(), target, reason); + this->add_waiting_iq([this, target, iq_id, to_jid, iid](const std::string& irc_hostname, const IrcMessage& message){ + if (irc_hostname != iid.get_server()) + return false; + if (message.command == "KICK" && message.arguments.size() >= 2) + { + const std::string target_later = message.arguments[1]; + const std::string chan_name_later = utils::tolower(message.arguments[0]); + if (target_later != target || chan_name_later != iid.get_local()) + return false; + this->xmpp->send_iq_result(iq_id, to_jid, std::to_string(iid)); + } + else if (message.command == "401" && message.arguments.size() >= 2) + { + const std::string target_later = message.arguments[1]; + if (target_later != target) + return false; + std::string error_message = "No such nick"; + if (message.arguments.size() >= 3) + error_message = message.arguments[2]; + this->xmpp->send_stanza_error("iq", to_jid, std::to_string(iid), iq_id, "cancel", "item-not-found", + error_message, false); + } + else if (message.command == "482" && message.arguments.size() >= 2) + { + const std::string chan_name_later = utils::tolower(message.arguments[1]); + if (chan_name_later != iid.get_local()) + return false; + std::string error_message = "You're not channel operator"; + if (message.arguments.size() >= 3) + error_message = message.arguments[2]; + this->xmpp->send_stanza_error("iq", to_jid, std::to_string(iid), iq_id, "cancel", "not-allowed", + error_message, false); + } + return true; + }); + } } void Bridge::set_channel_topic(const Iid& iid, const std::string& subject) diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index 0983595..9eb239d 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -1,6 +1,7 @@ #ifndef BRIDGE_INCLUDED # define BRIDGE_INCLUDED +#include <irc/irc_message.hpp> #include <irc/irc_client.hpp> #include <bridge/colors.hpp> #include <irc/irc_user.hpp> @@ -62,7 +63,8 @@ public: void send_private_message(const Iid& iid, const std::string& body, const std::string& type="PRIVMSG"); void leave_irc_channel(Iid&& iid, std::string&& status_message); void send_irc_nick_change(const Iid& iid, const std::string& new_nick); - void send_irc_kick(const Iid& iid, const std::string& target, const std::string& reason); + void send_irc_kick(const Iid& iid, const std::string& target, const std::string& reason, + const std::string& iq_id, const std::string& to_jid); void set_channel_topic(const Iid& iid, const std::string& subject); void send_xmpp_version_to_irc(const Iid& iid, const std::string& name, const std::string& version, const std::string& os); diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index 901e168..5ecb283 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -468,7 +468,7 @@ void XmppComponent::handle_iq(const Stanza& stanza) if (reason_el) reason = reason_el->get_inner(); Iid iid(to.local); - bridge->send_irc_kick(iid, nick, reason); + bridge->send_irc_kick(iid, nick, reason, id, from); stanza_error.disable(); } } @@ -1014,6 +1014,17 @@ void XmppComponent::send_iq_version_request(const std::string& from, this->send_stanza(iq); } +void XmppComponent::send_iq_result(const std::string& id, const std::string& to_jid, const std::string& from_local_part) +{ + Stanza iq("iq"); + iq["from"] = from_local_part + "@" + this->served_hostname; + iq["to"] = to_jid; + iq["id"] = id; + iq["type"] = "result"; + iq.close(); + this->send_stanza(iq); +} + std::string XmppComponent::next_id() { char uuid_str[37]; diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index 17462f4..ac12e40 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -104,7 +104,8 @@ public: */ void send_stanza_error(const std::string& kind, const std::string& to, const std::string& from, const std::string& id, const std::string& error_type, - const std::string& defined_condition, const std::string& text); + const std::string& defined_condition, const std::string& text, + const bool fulljid=true); /** * Send the closing signal for our document (not closing the connection though). */ @@ -209,6 +210,10 @@ public: void send_iq_version_request(const std::string& from, const std::string& jid_to); /** + * Send an empty iq of type result + */ + void send_iq_result(const std::string& id, const std::string& to_jid, const std::string& from); + /** * Handle the various stanza types */ void handle_handshake(const Stanza& stanza); |