From 130965f322ea58d3d2bbce5ee6ac31dae2d3a659 Mon Sep 17 00:00:00 2001
From: fiaxh <git@lightrise.org>
Date: Thu, 22 Aug 2019 16:05:28 +0200
Subject: Add incoming mediated invitation support (#162)

Co-authored-by: Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
---
 xmpp-vala/src/module/message/module.vala           |  4 +-
 xmpp-vala/src/module/util.vala                     |  5 ++-
 xmpp-vala/src/module/xep/0045_muc/module.vala      | 48 ++++++++++++++++++++++
 .../src/module/xep/0363_http_file_upload.vala      |  2 +-
 4 files changed, 55 insertions(+), 4 deletions(-)

(limited to 'xmpp-vala')

diff --git a/xmpp-vala/src/module/message/module.vala b/xmpp-vala/src/module/message/module.vala
index 6db2dcb5..ab3a7d80 100644
--- a/xmpp-vala/src/module/message/module.vala
+++ b/xmpp-vala/src/module/message/module.vala
@@ -22,7 +22,9 @@ namespace Xmpp {
         public async void received_message_stanza_async(XmppStream stream, StanzaNode node) {
             MessageStanza message = new MessageStanza.from_stanza(node, stream.get_flag(Bind.Flag.IDENTITY).my_jid);
             if (!message.is_error()) {
-                yield received_pipeline.run(stream, message);
+                bool abort = yield received_pipeline.run(stream, message);
+                if (abort) return;
+
                 received_message(stream, message);
             }
         }
diff --git a/xmpp-vala/src/module/util.vala b/xmpp-vala/src/module/util.vala
index cb11418c..28f1a5f8 100644
--- a/xmpp-vala/src/module/util.vala
+++ b/xmpp-vala/src/module/util.vala
@@ -19,7 +19,7 @@ public abstract class StanzaListener<T> : OrderedListener {
 
 public class StanzaListenerHolder<T> : ListenerHolder {
 
-    public async void run(XmppStream stream, T stanza) {
+    public async bool run(XmppStream stream, T stanza) {
 
         // listeners can change e.g. when switching to another stream
         ArrayList<OrderedListener> listeners_copy = new ArrayList<OrderedListener>();
@@ -28,8 +28,9 @@ public class StanzaListenerHolder<T> : ListenerHolder {
         foreach (OrderedListener ol in listeners_copy) {
             StanzaListener<T> l = ol as StanzaListener<T>;
             bool stop = yield l.run(stream, stanza);
-            if (stop) break;
+            if (stop) return true;
         }
+        return false;
     }
 }
 
diff --git a/xmpp-vala/src/module/xep/0045_muc/module.vala b/xmpp-vala/src/module/xep/0045_muc/module.vala
index 7b136d8c..db7a299f 100644
--- a/xmpp-vala/src/module/xep/0045_muc/module.vala
+++ b/xmpp-vala/src/module/xep/0045_muc/module.vala
@@ -61,12 +61,19 @@ public class Module : XmppStreamModule {
     public signal void received_occupant_role(XmppStream stream, Jid jid, Role? role);
     public signal void subject_set(XmppStream stream, string? subject, Jid jid);
     public signal void room_name_set(XmppStream stream, Jid jid, string? room_name);
+    public signal void invite_received(XmppStream stream, Jid room_jid, Jid from_jid, string? password, string? reason);
 
     public signal void room_entered(XmppStream stream, Jid jid, string nick);
     public signal void room_enter_error(XmppStream stream, Jid jid, MucEnterError? error); // TODO "?" shoudln't be necessary (vala bug), remove someday
     public signal void self_removed_from_room(XmppStream stream, Jid jid, StatusCode code);
     public signal void removed_from_room(XmppStream stream, Jid jid, StatusCode? code);
 
+    private ReceivedPipelineListener received_pipeline_listener;
+
+    public Module() {
+        received_pipeline_listener = new ReceivedPipelineListener(this);
+    }
+
     public void enter(XmppStream stream, Jid bare_jid, string nick, string? password, DateTime? history_since) {
         Presence.Stanza presence = new Presence.Stanza();
         presence.to = bare_jid.with_resource(nick);
@@ -175,6 +182,7 @@ public class Module : XmppStreamModule {
     public override void attach(XmppStream stream) {
         stream.add_flag(new Flag());
         stream.get_module(MessageModule.IDENTITY).received_message.connect(on_received_message);
+        stream.get_module(MessageModule.IDENTITY).received_pipeline.connect(received_pipeline_listener);
         stream.get_module(Presence.Module.IDENTITY).received_presence.connect(check_for_enter_error);
         stream.get_module(Presence.Module.IDENTITY).received_available.connect(on_received_available);
         stream.get_module(Presence.Module.IDENTITY).received_unavailable.connect(on_received_unavailable);
@@ -191,6 +199,7 @@ public class Module : XmppStreamModule {
 
     public override void detach(XmppStream stream) {
         stream.get_module(MessageModule.IDENTITY).received_message.disconnect(on_received_message);
+        stream.get_module(MessageModule.IDENTITY).received_pipeline.disconnect(received_pipeline_listener);
         stream.get_module(Presence.Module.IDENTITY).received_presence.disconnect(check_for_enter_error);
         stream.get_module(Presence.Module.IDENTITY).received_available.disconnect(on_received_available);
         stream.get_module(Presence.Module.IDENTITY).received_unavailable.disconnect(on_received_unavailable);
@@ -429,4 +438,43 @@ public class Module : XmppStreamModule {
     }
 }
 
+public class ReceivedPipelineListener : StanzaListener<MessageStanza> {
+
+    private const string[] after_actions_const = {"EXTRACT_MESSAGE_2"};
+
+    public override string action_group { get { return ""; } }
+    public override string[] after_actions { get { return after_actions_const; } }
+
+    Module outer;
+
+    public ReceivedPipelineListener(Module outer) {
+        this.outer = outer;
+    }
+
+    public override async bool run(XmppStream stream, MessageStanza message) {
+        if (message.type_ == MessageStanza.TYPE_NORMAL) {
+            StanzaNode? x_node = message.stanza.get_subnode("x", NS_URI_USER);
+            if (x_node != null) {
+                StanzaNode? invite_node = x_node.get_subnode("invite", NS_URI_USER);
+                string? password = null;
+                StanzaNode? password_node = x_node.get_subnode("password", NS_URI_USER);
+                if (password_node != null)
+                password = password_node.get_string_content();
+                if (invite_node != null) {
+                    string? from_jid = invite_node.get_attribute("from");
+                    if (from_jid != null) {
+                        StanzaNode? reason_node = invite_node.get_subnode("reason", NS_URI_USER);
+                        string? reason = null;
+                        if (reason_node != null)
+                        reason = reason_node.get_string_content();
+                        outer.invite_received(stream, message.from, new Jid(from_jid), password, reason);
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+}
+
 }
diff --git a/xmpp-vala/src/module/xep/0363_http_file_upload.vala b/xmpp-vala/src/module/xep/0363_http_file_upload.vala
index 822ddc6b..8829ad15 100644
--- a/xmpp-vala/src/module/xep/0363_http_file_upload.vala
+++ b/xmpp-vala/src/module/xep/0363_http_file_upload.vala
@@ -166,7 +166,7 @@ public class ReceivedPipelineListener : StanzaListener<MessageStanza> {
         if (oob_url != null && oob_url == message.body) {
             stream.get_module(Module.IDENTITY).received_url(stream, message);
         }
-        return true;
+        return false;
     }
 }
 
-- 
cgit v1.2.3-70-g09d2