From 9500bfd4ccb21b261fd8204180d78553704f7acc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Sun, 18 Mar 2018 19:33:07 +0100 Subject: Reflect message IDs in channel MUCs fix #3283 --- src/bridge/bridge.cpp | 11 ++++++++--- src/bridge/bridge.hpp | 2 +- src/database/database.cpp | 8 ++------ src/utils/uuid.cpp | 14 ++++++++++++++ src/utils/uuid.hpp | 8 ++++++++ src/xmpp/biboumi_component.cpp | 2 +- src/xmpp/xmpp_component.cpp | 12 ++++-------- src/xmpp/xmpp_component.hpp | 2 +- tests/end_to_end/__main__.py | 22 +++++++++++----------- 9 files changed, 50 insertions(+), 31 deletions(-) create mode 100644 src/utils/uuid.cpp create mode 100644 src/utils/uuid.hpp diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 9269bb7..9a0358c 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -185,7 +186,7 @@ bool Bridge::join_irc_channel(const Iid& iid, const std::string& nickname, const return false; } -void Bridge::send_channel_message(const Iid& iid, const std::string& body) +void Bridge::send_channel_message(const Iid& iid, const std::string& body, std::string id) { if (iid.get_server().empty()) { @@ -210,6 +211,7 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body) std::vector lines = utils::split(body, '\n', true); if (lines.empty()) return ; + bool first = true; for (const std::string& line: lines) { if (line.substr(0, 5) == "/mode") @@ -231,9 +233,12 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body) uuid = Database::store_muc_message(this->get_bare_jid(), iid.get_local(), iid.get_server(), std::chrono::system_clock::now(), std::get<0>(xmpp_body), irc->get_own_nick()); #endif + if (!first) + id = utils::gen_uuid(); for (const auto& resource: this->resources_in_chan[iid.to_tuple()]) this->xmpp.send_muc_message(std::to_string(iid), irc->get_own_nick(), this->make_xmpp_body(line), - this->user_jid + "/" + resource, uuid); + this->user_jid + "/" + resource, uuid, id); + first = false; } } @@ -816,7 +821,7 @@ void Bridge::send_message(const Iid& iid, const std::string& nick, const std::st for (const auto& resource: this->resources_in_chan[iid.to_tuple()]) { this->xmpp.send_muc_message(std::to_string(iid), nick, this->make_xmpp_body(body, encoding), - this->user_jid + "/" + resource, {}); + this->user_jid + "/" + resource, {}, utils::gen_uuid()); } } diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index 44df4c2..3798465 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -77,7 +77,7 @@ public: */ bool join_irc_channel(const Iid& iid, const std::string& nickname, const std::string& password, const std::string& resource, HistoryLimit history_limit); - void send_channel_message(const Iid& iid, const std::string& body); + void send_channel_message(const Iid& iid, const std::string& body, std::string id); void send_private_message(const Iid& iid, const std::string& body, const std::string& type="PRIVMSG"); void send_raw_message(const std::string& hostname, const std::string& body); void leave_irc_channel(Iid&& iid, const std::string& status_message, const std::string& resource); diff --git a/src/database/database.cpp b/src/database/database.cpp index b1525d5..02c5b4f 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -2,9 +2,9 @@ #ifdef USE_DATABASE #include -#include #include #include +#include #include #include @@ -325,11 +325,7 @@ void Database::close() std::string Database::gen_uuid() { - char uuid_str[37]; - uuid_t uuid; - uuid_generate(uuid); - uuid_unparse(uuid, uuid_str); - return uuid_str; + return utils::gen_uuid(); } Transaction::Transaction() diff --git a/src/utils/uuid.cpp b/src/utils/uuid.cpp new file mode 100644 index 0000000..23b71fe --- /dev/null +++ b/src/utils/uuid.cpp @@ -0,0 +1,14 @@ +#include +#include + +namespace utils +{ +std::string gen_uuid() +{ + char uuid_str[37]; + uuid_t uuid; + uuid_generate(uuid); + uuid_unparse(uuid, uuid_str); + return uuid_str; +} +} diff --git a/src/utils/uuid.hpp b/src/utils/uuid.hpp new file mode 100644 index 0000000..d550475 --- /dev/null +++ b/src/utils/uuid.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace utils +{ +std::string gen_uuid(); +} diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 891b715..f35c7f4 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -279,7 +279,7 @@ void BiboumiComponent::handle_message(const Stanza& stanza) { if (body && !body->get_inner().empty()) { - bridge->send_channel_message(iid, body->get_inner()); + bridge->send_channel_message(iid, body->get_inner(), id); } const XmlNode* subject = stanza.get_child("subject", COMPONENT_NS); if (subject) diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index a71d810..b3d925e 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -14,8 +15,6 @@ #include #include -#include - #include #include @@ -364,10 +363,11 @@ void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, cons this->send_stanza(message); } -void XmppComponent::send_muc_message(const std::string& muc_name, const std::string& nick, Xmpp::body&& xmpp_body, const std::string& jid_to, std::string uuid) +void XmppComponent::send_muc_message(const std::string& muc_name, const std::string& nick, Xmpp::body&& xmpp_body, const std::string& jid_to, std::string uuid, std::string id) { Stanza message("message"); message["to"] = jid_to; + message["id"] = std::move(id); if (!nick.empty()) message["from"] = muc_name + "@" + this->served_hostname + "/" + nick; else // Message from the room itself @@ -673,9 +673,5 @@ void XmppComponent::send_iq_result(const std::string& id, const std::string& to_ std::string XmppComponent::next_id() { - char uuid_str[37]; - uuid_t uuid; - uuid_generate(uuid); - uuid_unparse(uuid, uuid_str); - return uuid_str; + return utils::gen_uuid(); } diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index 06cc6ff..b11e56c 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -134,7 +134,7 @@ public: * Send a (non-private) message to the MUC */ void send_muc_message(const std::string& muc_name, const std::string& nick, Xmpp::body&& body, const std::string& jid_to, - std::string uuid); + std::string uuid, std::string id); #ifdef USE_DATABASE /** * Send a message, with a element, part of a MUC history diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 3bd9f1c..a2bb2d3 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -1218,14 +1218,14 @@ if __name__ == '__main__': partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"), # Send a multi-line channel message - partial(send_stanza, "un\ndeux\ntrois"), + partial(send_stanza, "un\ndeux\ntrois"), # Receive multiple messages, in order partial(expect_stanza, - "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='un']"), + "/message[@from='#foo%{irc_server_one}/{nick_one}'][@id='the-message-id'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='un']"), partial(expect_stanza, - "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='deux']"), + "/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='deux']"), partial(expect_stanza, - "/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='trois']"), + "/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='trois']"), # Second user joins partial(send_stanza, @@ -1241,16 +1241,16 @@ if __name__ == '__main__': ]), # Send a multi-line channel message - partial(send_stanza, "un\ndeux\ntrois"), + partial(send_stanza, "un\ndeux\ntrois"), # Receive multiple messages, for each user partial(expect_unordered, [ - ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='un']",), - ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='deux']",), - ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='trois']",), + ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@id='the-message-id'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='un']",), + ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='deux']",), + ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='trois']",), - ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='un']",), - ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='deux']",), - ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='trois']",), + ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='un']",), + ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='deux']",), + ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='trois']",), ]) ]), Scenario("channel_messages", -- cgit v1.2.3