~singpolyma/biboumi

f125de4833d65a83d1f550f4bfbff4d5e4c333b2 — louiz’ 7 years ago 407f95a
Add the possibility to invite any external JID to a room

fix #3285
M CHANGELOG.rst => CHANGELOG.rst +2 -0
@@ 13,6 13,8 @@ Version 6.0
   being shutdown or the connection to the IRC server is cut unexpectedly.
 - Support for botan version 1.11.x has been dropped, only version 2.x is
   supported.
 - Invitations can now be sent to any JID, not only JIDs served by the biboumi
   instance itself.

Version 5.0 - 2017-05-24
========================

M doc/biboumi.1.rst => doc/biboumi.1.rst +13 -8
@@ 455,17 455,22 @@ be replaced by a space, because the IRC server wouldn’t accept it.
Invitations
-----------

Biboumi forwards the mediated invitations to the target nick.  If the user
wishes to invite the user “FooBar” into a room, they can invite one of the
following “JIDs” (one of them is not a JID, actually):
If the invited JID is a user JID served by this biboumi instance, it will forward the
invitation to the target nick, over IRC.
Otherwise, the mediated instance will directly be sent to the invited JID, over XMPP.

- foobar%anything@anything
- anything@anything/FooBar
Example: if the user wishes to invite the IRC user “FooBar” into a room, they can
invite one of the following “JIDs” (one of them is not a JID, actually):

- foobar%anything@biboumi.example.com
- anything@biboumi.example.com/FooBar
- FooBar

Note that the “anything” part are simply ignored because they have no
meaning for the IRC server: we already know which IRC server is targeted
using the JID of the target channel.
(Note that the “anything” parts are simply ignored because they carry no
additional meaning for biboumi: we already know which IRC server is targeted
using the JID of the target channel.)

Otherwise, any valid JID can be used, to invite any XMPP user.

Kicks and bans
--------------

M src/xmpp/biboumi_component.cpp => src/xmpp/biboumi_component.cpp +16 -5
@@ 310,7 310,11 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
            const auto invite_to = invite->get_tag("to");
            if (!invite_to.empty())
              {
                bridge->send_irc_invitation(iid, invite_to);
                Jid invited_jid{invite_to};
                if (invited_jid.domain == this->get_served_hostname() || invited_jid.local.empty())
                  bridge->send_irc_invitation(iid, invite_to);
                else
                  this->send_invitation_from_fulljid(std::to_string(iid), invite_to, from_str);
              }
          }



@@ 987,6 991,16 @@ void BiboumiComponent::send_invitation(const std::string& room_target,
                                       const std::string& jid_to,
                                       const std::string& author_nick)
{
  if (author_nick.empty())
    this->send_invitation_from_fulljid(room_target, jid_to, room_target + "@" + this->served_hostname);
  else
    this->send_invitation_from_fulljid(room_target, jid_to, room_target + "@" + this->served_hostname + "/" + author_nick);
}

void BiboumiComponent::send_invitation_from_fulljid(const std::string& room_target,
                                       const std::string& jid_to,
                                       const std::string& from)
{
  Stanza message("message");
  {
    message["from"] = room_target + "@" + this->served_hostname;


@@ 994,10 1008,7 @@ void BiboumiComponent::send_invitation(const std::string& room_target,
    XmlSubNode x(message, "x");
    x["xmlns"] = MUC_USER_NS;
    XmlSubNode invite(x, "invite");
    if (author_nick.empty())
      invite["from"] = room_target + "@" + this->served_hostname;
    else
      invite["from"] = room_target + "@" + this->served_hostname + "/" + author_nick;
    invite["from"] = from;
  }
  this->send_stanza(message);
}

M src/xmpp/biboumi_component.hpp => src/xmpp/biboumi_component.hpp +3 -0
@@ 87,6 87,9 @@ public:
                                const ChannelList& channel_list, std::vector<ListElement>::const_iterator begin,
                                std::vector<ListElement>::const_iterator end, const ResultSetInfo& rs_info);
  void send_invitation(const std::string& room_target, const std::string& jid_to, const std::string& author_nick);
private:
  void send_invitation_from_fulljid(const std::string& room_target, const std::string& jid_to, const std::string& from);
public:
  void accept_subscription(const std::string& from, const std::string& to);
  void ask_subscription(const std::string& from, const std::string& to);
  void send_presence_to_contact(const std::string& from, const std::string& to, const std::string& type, const std::string& id="");

M tests/end_to_end/__main__.py => tests/end_to_end/__main__.py +3 -0
@@ 2406,6 2406,9 @@ if __name__ == '__main__':
                     partial(send_stanza, "<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><x xmlns='http://jabber.org/protocol/muc#user'><invite to='{nick_two}'/></x></message>"),
                     partial(expect_stanza, "/message/body[text()='{nick_two} has been invited to #foo']"),
                     partial(expect_stanza, "/message[@to='{jid_two}/{resource_two}'][@from='#foo%{irc_server_one}']/muc_user:x/muc_user:invite[@from='#foo%{irc_server_one}/{nick_one}']"),

                     partial(send_stanza, "<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}'><x xmlns='http://jabber.org/protocol/muc#user'><invite to='bertrand@example.com'/></x></message>"),
                     partial(expect_stanza, "/message[@to='bertrand@example.com'][@from='#foo%{irc_server_one}']/muc_user:x/muc_user:invite[@from='{jid_one}/{resource_one}']"),
                ]),
                Scenario("virtual_channel_multisession",
                 [