aboutsummaryrefslogtreecommitdiff
path: root/xmpp-vala/src/module/xep/0313_message_archive_management.vala
diff options
context:
space:
mode:
Diffstat (limited to 'xmpp-vala/src/module/xep/0313_message_archive_management.vala')
-rw-r--r--xmpp-vala/src/module/xep/0313_message_archive_management.vala146
1 files changed, 66 insertions, 80 deletions
diff --git a/xmpp-vala/src/module/xep/0313_message_archive_management.vala b/xmpp-vala/src/module/xep/0313_message_archive_management.vala
index c24c6b04..36a43ac9 100644
--- a/xmpp-vala/src/module/xep/0313_message_archive_management.vala
+++ b/xmpp-vala/src/module/xep/0313_message_archive_management.vala
@@ -1,11 +1,18 @@
-namespace Xmpp.Xep.MessageArchiveManagement {
+using Gee;
+using Xmpp.Xep;
+
+namespace Xmpp.MessageArchiveManagement {
public const string NS_URI = "urn:xmpp:mam:2";
public const string NS_URI_2 = "urn:xmpp:mam:2";
public const string NS_URI_1 = "urn:xmpp:mam:1";
-private static string NS_VER(XmppStream stream) {
- return stream.get_flag(Flag.IDENTITY).ns_ver;
+public class QueryResult {
+ public bool error { get; set; default=false; }
+ public bool malformed { get; set; default=false; }
+ public bool complete { get; set; default=false; }
+ public string first { get; set; }
+ public string last { get; set; }
}
public class Module : XmppStreamModule {
@@ -15,54 +22,6 @@ public class Module : XmppStreamModule {
private ReceivedPipelineListener received_pipeline_listener = new ReceivedPipelineListener();
- private StanzaNode crate_base_query(XmppStream stream, string? jid, string? queryid, DateTime? start, DateTime? end) {
- 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_VER(stream));
- data_form.add_field(form_type_field);
- if (jid != null) {
- DataForms.DataForm.Field field = new DataForms.DataForm.Field() { var="with" };
- field.set_value_string(jid);
- data_form.add_field(field);
- }
- if (start != null) {
- DataForms.DataForm.Field field = new DataForms.DataForm.Field() { var="start" };
- field.set_value_string(DateTimeProfiles.to_datetime(start));
- data_form.add_field(field);
- }
- if (end != null) {
- DataForms.DataForm.Field field = new DataForms.DataForm.Field() { var="end" };
- field.set_value_string(DateTimeProfiles.to_datetime(end));
- data_form.add_field(field);
- }
- StanzaNode query_node = new StanzaNode.build("query", NS_VER(stream)).add_self_xmlns().put_node(data_form.get_submit_node());
- if (queryid != null) {
- query_node.put_attribute("queryid", queryid);
- }
- return query_node;
- }
-
- private StanzaNode create_set_rsm_node(string? before_id) {
- var before_node = new StanzaNode.build("before", "http://jabber.org/protocol/rsm");
- if (before_id != null) {
- before_node.put_node(new StanzaNode.text(before_id));
- }
- var max_node = (new StanzaNode.build("max", "http://jabber.org/protocol/rsm")).put_node(new StanzaNode.text("20"));
- return (new StanzaNode.build("set", "http://jabber.org/protocol/rsm")).add_self_xmlns()
- .put_node(before_node)
- .put_node(max_node);
- }
-
- public async Iq.Stanza? query_archive(XmppStream stream, string? jid, string? query_id, DateTime? start_time, string? start_id, DateTime? end_time, string? end_id) {
- if (stream.get_flag(Flag.IDENTITY) == null) return null;
-
- var query_node = crate_base_query(stream, jid, query_id, start_time, end_time);
- query_node.put_node(create_set_rsm_node(end_id));
- Iq.Stanza iq = new Iq.Stanza.set(query_node);
-
- return yield stream.get_module(Iq.Module.IDENTITY).send_iq_async(stream, iq);
- }
-
public override void attach(XmppStream stream) {
stream.get_module(MessageModule.IDENTITY).received_pipeline.connect(received_pipeline_listener);
stream.stream_negotiated.connect(query_availability);
@@ -75,25 +34,6 @@ public class Module : XmppStreamModule {
public override string get_ns() { return NS_URI; }
public override string get_id() { return IDENTITY.id; }
- public async Iq.Stanza? page_through_results(XmppStream stream, string? jid, string? query_id, DateTime? start_time, DateTime? end_time, Iq.Stanza iq) {
-
- string? complete = iq.stanza.get_deep_attribute("urn:xmpp:mam:2:fin", "complete");
- if (complete == "true") {
- return null;
- }
- string? first = iq.stanza.get_deep_string_content(NS_VER(stream) + ":fin", "http://jabber.org/protocol/rsm" + ":set", "first");
- if (first == null) {
- return null;
- }
-
- var query_node = crate_base_query(stream, jid, query_id, start_time, end_time);
- query_node.put_node(create_set_rsm_node(first));
-
- Iq.Stanza paging_iq = new Iq.Stanza.set(query_node);
-
- return yield stream.get_module(Iq.Module.IDENTITY).send_iq_async(stream, paging_iq);
- }
-
private async void query_availability(XmppStream stream) {
Jid own_jid = stream.get_flag(Bind.Flag.IDENTITY).my_jid.bare_jid;
@@ -113,6 +53,52 @@ public class Module : XmppStreamModule {
}
}
+ internal StanzaNode create_base_query(XmppStream stream, string ns, string? queryid, Gee.List<DataForms.DataForm.Field> fields) {
+ 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_VER(stream));
+ data_form.add_field(form_type_field);
+
+ foreach (var field in fields) {
+ data_form.add_field(field);
+ }
+
+ StanzaNode query_node = new StanzaNode.build("query", NS_VER(stream)).add_self_xmlns().put_node(data_form.get_submit_node());
+ if (queryid != null) {
+ query_node.put_attribute("queryid", queryid);
+ }
+ return query_node;
+ }
+
+ internal async QueryResult query_archive(XmppStream stream, string ns, Jid? mam_server, StanzaNode query_node) {
+ var res = new QueryResult();
+
+ if (stream.get_flag(Flag.IDENTITY) == null) { res.error = true; return res; }
+
+ // Build and send query
+ Iq.Stanza iq = new Iq.Stanza.set(query_node) { to=mam_server };
+
+ print(@"OUT:\n$(iq.stanza.to_string())\n");
+ Iq.Stanza result_iq = yield stream.get_module(Iq.Module.IDENTITY).send_iq_async(stream, iq);
+
+ print(result_iq.stanza.to_string() + "\n");
+
+ // Parse the response IQ into a QueryResult.
+ StanzaNode? fin_node = result_iq.stanza.get_subnode("fin", ns);
+ if (fin_node == null) { print(@"$ns a1\n"); res.malformed = true; return res; }
+
+ StanzaNode? rsm_node = fin_node.get_subnode("set", Xmpp.ResultSetManagement.NS_URI);
+ if (rsm_node == null) { print("a2\n"); res.malformed = true; return res; }
+
+ res.first = rsm_node.get_deep_string_content("first");
+ res.last = rsm_node.get_deep_string_content("last");
+ if ((res.first == null) != (res.last == null)) { print("a3\n"); res.malformed = true; }
+ res.complete = fin_node.get_attribute_bool("complete", false, ns);
+
+ return res;
+ }
+
public class ReceivedPipelineListener : StanzaListener<MessageStanza> {
private string[] after_actions_const = {};
@@ -123,19 +109,13 @@ public class ReceivedPipelineListener : StanzaListener<MessageStanza> {
public override async bool run(XmppStream stream, MessageStanza message) {
if (stream.get_flag(Flag.IDENTITY) == null) return false;
- StanzaNode? message_node = message.stanza.get_deep_subnode(NS_VER(stream) + ":result", "urn:xmpp:forward:0:forwarded", Xmpp.NS_URI + ":message");
+ StanzaNode? message_node = message.stanza.get_deep_subnode(NS_VER(stream) + ":result", StanzaForwarding.NS_URI + ":forwarded", Xmpp.NS_URI + ":message");
if (message_node != null) {
- // MAM messages must come from our server // TODO or a MUC server
- if (!message.from.equals(stream.get_flag(Bind.Flag.IDENTITY).my_jid.bare_jid)) {
- warning("Received alleged MAM message from %s, ignoring", message.from.to_string());
- return true;
- }
-
- StanzaNode? forward_node = message.stanza.get_deep_subnode(NS_VER(stream) + ":result", "urn:xmpp:forward:0:forwarded", DelayedDelivery.NS_URI + ":delay");
+ StanzaNode? forward_node = message.stanza.get_deep_subnode(NS_VER(stream) + ":result", StanzaForwarding.NS_URI + ":forwarded", DelayedDelivery.NS_URI + ":delay");
DateTime? datetime = DelayedDelivery.get_time_for_node(forward_node);
string? mam_id = message.stanza.get_deep_attribute(NS_VER(stream) + ":result", NS_VER(stream) + ":id");
string? query_id = message.stanza.get_deep_attribute(NS_VER(stream) + ":result", NS_VER(stream) + ":queryid");
- message.add_flag(new MessageFlag(datetime, mam_id, query_id));
+ message.add_flag(new MessageFlag(message.from, datetime, mam_id, query_id));
message.stanza = message_node;
message.rerun_parsing = true;
@@ -160,11 +140,13 @@ public class Flag : XmppStreamFlag {
public class MessageFlag : Xmpp.MessageFlag {
public const string ID = "message_archive_management";
+ public Jid sender_jid { get; private set; }
public DateTime? server_time { get; private set; }
public string? mam_id { get; private set; }
public string? query_id { get; private set; }
- public MessageFlag(DateTime? server_time, string? mam_id, string? query_id) {
+ public MessageFlag(Jid sender_jid, DateTime? server_time, string? mam_id, string? query_id) {
+ this.sender_jid = sender_jid;
this.server_time = server_time;
this.mam_id = mam_id;
this.query_id = query_id;
@@ -176,4 +158,8 @@ public class MessageFlag : Xmpp.MessageFlag {
public override string get_id() { return ID; }
}
+private static string NS_VER(XmppStream stream) {
+ return stream.get_flag(Flag.IDENTITY).ns_ver;
}
+
+} \ No newline at end of file