~singpolyma/biboumi

9500bfd4ccb21b261fd8204180d78553704f7acc — louiz’ 5 years ago 68e1480
Reflect message IDs in channel MUCs

fix #3283
M src/bridge/bridge.cpp => src/bridge/bridge.cpp +8 -3
@@ 5,6 5,7 @@
#include <utils/empty_if_fixed_server.hpp>
#include <utils/encoding.hpp>
#include <utils/tolower.hpp>
#include <utils/uuid.hpp>
#include <logger/logger.hpp>
#include <utils/revstr.hpp>
#include <utils/split.hpp>


@@ 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<std::string> 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());

        }
    }

M src/bridge/bridge.hpp => src/bridge/bridge.hpp +1 -1
@@ 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);

M src/database/database.cpp => src/database/database.cpp +2 -6
@@ 2,9 2,9 @@
#ifdef USE_DATABASE

#include <database/database.hpp>
#include <uuid/uuid.h>
#include <utils/get_first_non_empty.hpp>
#include <utils/time.hpp>
#include <utils/uuid.hpp>

#include <config/config.hpp>
#include <database/sqlite3_engine.hpp>


@@ 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()

A src/utils/uuid.cpp => src/utils/uuid.cpp +14 -0
@@ 0,0 1,14 @@
#include <utils/uuid.hpp>
#include <uuid/uuid.h>

namespace utils
{
std::string gen_uuid()
{
  char uuid_str[37];
  uuid_t uuid;
  uuid_generate(uuid);
  uuid_unparse(uuid, uuid_str);
  return uuid_str;
}
}

A src/utils/uuid.hpp => src/utils/uuid.hpp +8 -0
@@ 0,0 1,8 @@
#pragma once

#include <string>

namespace utils
{
std::string gen_uuid();
}

M src/xmpp/biboumi_component.cpp => src/xmpp/biboumi_component.cpp +1 -1
@@ 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)

M src/xmpp/xmpp_component.cpp => src/xmpp/xmpp_component.cpp +4 -8
@@ 2,6 2,7 @@
#include <utils/scopeguard.hpp>
#include <utils/tolower.hpp>
#include <logger/logger.hpp>
#include <utils/uuid.hpp>

#include <xmpp/xmpp_component.hpp>
#include <config/config.hpp>


@@ 14,8 15,6 @@
#include <iostream>
#include <set>

#include <uuid/uuid.h>

#include <cstdlib>
#include <set>



@@ 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();
}

M src/xmpp/xmpp_component.hpp => src/xmpp/xmpp_component.hpp +1 -1
@@ 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 <delay/> element, part of a MUC history

M tests/end_to_end/__main__.py => tests/end_to_end/__main__.py +11 -11
@@ 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, "<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>un\ndeux\ntrois</body></message>"),
                     partial(send_stanza, "<message id='the-message-id' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>un\ndeux\ntrois</body></message>"),
                     # 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, "<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>un\ndeux\ntrois</body></message>"),
                     partial(send_stanza, "<message id='the-message-id' from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>un\ndeux\ntrois</body></message>"),
                     # 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",