aboutsummaryrefslogtreecommitdiff
path: root/xmpp-vala
diff options
context:
space:
mode:
Diffstat (limited to 'xmpp-vala')
-rw-r--r--xmpp-vala/src/module/iq/module.vala3
-rw-r--r--xmpp-vala/src/module/message/module.vala4
-rw-r--r--xmpp-vala/src/module/util.vala5
-rw-r--r--xmpp-vala/src/module/xep/0045_muc/module.vala48
-rw-r--r--xmpp-vala/src/module/xep/0060_pubsub.vala33
-rw-r--r--xmpp-vala/src/module/xep/0084_user_avatars.vala4
-rw-r--r--xmpp-vala/src/module/xep/0363_http_file_upload.vala4
7 files changed, 92 insertions, 9 deletions
diff --git a/xmpp-vala/src/module/iq/module.vala b/xmpp-vala/src/module/iq/module.vala
index f73f5459..f5cb6acf 100644
--- a/xmpp-vala/src/module/iq/module.vala
+++ b/xmpp-vala/src/module/iq/module.vala
@@ -67,7 +67,8 @@ namespace Xmpp.Iq {
}
}
} else {
- Iq.Stanza unavailable_error = new Iq.Stanza.error(iq, new ErrorStanza.service_unavailable());
+ // Send error if we don't handle the NS of the IQ get/set payload (RFC6120 10.3.3 (2))
+ Iq.Stanza unavailable_error = new Iq.Stanza.error(iq, new ErrorStanza.service_unavailable()) { to=iq.from };
send_iq(stream, unavailable_error);
}
}
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/0060_pubsub.vala b/xmpp-vala/src/module/xep/0060_pubsub.vala
index e887f74f..91f5525d 100644
--- a/xmpp-vala/src/module/xep/0060_pubsub.vala
+++ b/xmpp-vala/src/module/xep/0060_pubsub.vala
@@ -3,6 +3,13 @@ using Gee;
namespace Xmpp.Xep.Pubsub {
private const string NS_URI = "http://jabber.org/protocol/pubsub";
private const string NS_URI_EVENT = NS_URI + "#event";
+ private const string NS_URI_OWNER = NS_URI + "#owner";
+
+ public const string ACCESS_MODEL_AUTHORIZE = "authorize";
+ public const string ACCESS_MODEL_OPEN = "open";
+ public const string ACCESS_MODEL_PRESENCE = "presence";
+ public const string ACCESS_MODEL_ROSTER = "roster";
+ public const string ACCESS_MODEL_WHITELIST = "whitelist";
public class Module : XmppStreamModule {
public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>(NS_URI, "0060_pubsub_module");
@@ -27,7 +34,7 @@ namespace Xmpp.Xep.Pubsub {
});
}
- public void publish(XmppStream stream, Jid? jid, string node_id, string node, string? item_id, StanzaNode content) {
+ public void publish(XmppStream stream, Jid? jid, string node_id, string? item_id, StanzaNode content, string? access_model=null) {
StanzaNode pubsub_node = new StanzaNode.build("pubsub", NS_URI).add_self_xmlns();
StanzaNode publish_node = new StanzaNode.build("publish", NS_URI).put_attribute("node", node_id);
pubsub_node.put_node(publish_node);
@@ -35,6 +42,30 @@ namespace Xmpp.Xep.Pubsub {
if (item_id != null) items_node.put_attribute("id", item_id);
items_node.put_node(content);
publish_node.put_node(items_node);
+
+ if (access_model != null) {
+ StanzaNode publish_options_node = new StanzaNode.build("publish-options", NS_URI);
+ pubsub_node.put_node(publish_options_node);
+
+ DataForms.DataForm data_form = new DataForms.DataForm();
+ DataForms.DataForm.HiddenField form_type_field = new DataForms.DataForm.HiddenField() { var="FORM_TYPE" };
+ form_type_field.set_value_string(NS_URI + "#publish-options");
+ data_form.add_field(form_type_field);
+ DataForms.DataForm.Field field = new DataForms.DataForm.Field() { var="pubsub#access_model" };
+ field.set_value_string(access_model);
+ data_form.add_field(field);
+ publish_options_node.put_node(data_form.get_submit_node());
+ }
+
+ Iq.Stanza iq = new Iq.Stanza.set(pubsub_node);
+ stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, null);
+ }
+
+ public void delete_node(XmppStream stream, Jid? jid, string node_id) {
+ StanzaNode pubsub_node = new StanzaNode.build("pubsub", NS_URI_OWNER).add_self_xmlns();
+ StanzaNode publish_node = new StanzaNode.build("delete", NS_URI_OWNER).put_attribute("node", node_id);
+ pubsub_node.put_node(publish_node);
+
Iq.Stanza iq = new Iq.Stanza.set(pubsub_node);
stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, null);
}
diff --git a/xmpp-vala/src/module/xep/0084_user_avatars.vala b/xmpp-vala/src/module/xep/0084_user_avatars.vala
index ed35dc44..51c2a563 100644
--- a/xmpp-vala/src/module/xep/0084_user_avatars.vala
+++ b/xmpp-vala/src/module/xep/0084_user_avatars.vala
@@ -18,7 +18,7 @@ namespace Xmpp.Xep.UserAvatars {
string sha1 = Checksum.compute_for_data(ChecksumType.SHA1, image);
StanzaNode data_node = new StanzaNode.build("data", NS_URI_DATA).add_self_xmlns()
.put_node(new StanzaNode.text(Base64.encode(image)));
- stream.get_module(Pubsub.Module.IDENTITY).publish(stream, null, NS_URI_DATA, NS_URI_DATA, sha1, data_node);
+ stream.get_module(Pubsub.Module.IDENTITY).publish(stream, null, NS_URI_DATA, sha1, data_node);
StanzaNode metadata_node = new StanzaNode.build("metadata", NS_URI_METADATA).add_self_xmlns();
StanzaNode info_node = new StanzaNode.build("info", NS_URI_METADATA)
@@ -28,7 +28,7 @@ namespace Xmpp.Xep.UserAvatars {
.put_attribute("height", height.to_string())
.put_attribute("type", "image/png");
metadata_node.put_node(info_node);
- stream.get_module(Pubsub.Module.IDENTITY).publish(stream, null, NS_URI_METADATA, NS_URI_METADATA, sha1, metadata_node);
+ stream.get_module(Pubsub.Module.IDENTITY).publish(stream, null, NS_URI_METADATA, sha1, metadata_node);
}
public override void attach(XmppStream stream) {
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 eefe05eb..8829ad15 100644
--- a/xmpp-vala/src/module/xep/0363_http_file_upload.vala
+++ b/xmpp-vala/src/module/xep/0363_http_file_upload.vala
@@ -22,7 +22,7 @@ public class Module : XmppStreamModule {
public string url_get { get; set; }
public string url_put { get; set; }
}
- public async SlotResult request_slot(XmppStream stream, string filename, int file_size, string? content_type) throws HttpFileTransferError {
+ public async SlotResult request_slot(XmppStream stream, string filename, int64 file_size, string? content_type) throws HttpFileTransferError {
Flag? flag = stream.get_flag(Flag.IDENTITY);
if (flag == null) {
throw new HttpFileTransferError.SLOT_REQUEST("No flag");
@@ -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;
}
}