From 22adbd38dca0868f0e10754314a3859bba0a7d87 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Fri, 31 Mar 2017 01:17:01 +0200 Subject: Handle MUC private messages --- xmpp-vala/CMakeLists.txt | 2 + .../module/xep/0030_service_discovery/flag.vala | 23 +++- .../xep/0030_service_discovery/identity.vala | 18 +++ .../xep/0030_service_discovery/info_result.vala | 36 ++--- .../module/xep/0030_service_discovery/item.vala | 15 ++ .../module/xep/0030_service_discovery/module.vala | 153 ++++++++++----------- xmpp-vala/src/module/xep/0045_muc/module.vala | 4 +- .../src/module/xep/0115_entitiy_capabilities.vala | 5 +- 8 files changed, 148 insertions(+), 108 deletions(-) create mode 100644 xmpp-vala/src/module/xep/0030_service_discovery/identity.vala create mode 100644 xmpp-vala/src/module/xep/0030_service_discovery/item.vala (limited to 'xmpp-vala') diff --git a/xmpp-vala/CMakeLists.txt b/xmpp-vala/CMakeLists.txt index 32162f0c..3294b472 100644 --- a/xmpp-vala/CMakeLists.txt +++ b/xmpp-vala/CMakeLists.txt @@ -34,7 +34,9 @@ SOURCES "src/module/util.vala" "src/module/xep/0030_service_discovery/flag.vala" + "src/module/xep/0030_service_discovery/identity.vala" "src/module/xep/0030_service_discovery/info_result.vala" + "src/module/xep/0030_service_discovery/item.vala" "src/module/xep/0030_service_discovery/items_result.vala" "src/module/xep/0030_service_discovery/module.vala" "src/module/xep/0045_muc/flag.vala" diff --git a/xmpp-vala/src/module/xep/0030_service_discovery/flag.vala b/xmpp-vala/src/module/xep/0030_service_discovery/flag.vala index 0f82f498..7c49fc30 100644 --- a/xmpp-vala/src/module/xep/0030_service_discovery/flag.vala +++ b/xmpp-vala/src/module/xep/0030_service_discovery/flag.vala @@ -7,15 +7,34 @@ namespace Xmpp.Xep.ServiceDiscovery { public class Flag : XmppStreamFlag { public static FlagIdentity IDENTITY = new FlagIdentity(NS_URI, "service_discovery"); - private HashMap> entity_features = new HashMap>(); + private HashMap?> entity_features = new HashMap?>(); + private HashMap?> entity_identities = new HashMap?>(); public ArrayList features = new ArrayList(); + public ArrayList? get_entity_categories(string jid) { + return entity_identities.has_key(jid) ? entity_identities[jid] : null; // TODO isnt this default for hashmap + } + + public bool? has_entity_identity(string jid, string category, string type) { + if (!entity_identities.has_key(jid)) return null; + if (entity_identities[jid] == null) return false; + foreach (Identity identity in entity_identities[jid]) { + if (identity.category == category && identity.type_ == type) return true; + } + return false; + } + public bool? has_entity_feature(string jid, string feature) { if (!entity_features.has_key(jid)) return null; + if (entity_features[jid] == null) return false; return entity_features[jid].contains(feature); } - public void set_entitiy_features(string jid, ArrayList features) { + public void set_entity_identities(string jid, ArrayList? identities) { + entity_identities[jid] = identities; + } + + public void set_entity_features(string jid, ArrayList? features) { entity_features[jid] = features; } diff --git a/xmpp-vala/src/module/xep/0030_service_discovery/identity.vala b/xmpp-vala/src/module/xep/0030_service_discovery/identity.vala new file mode 100644 index 00000000..e29eb111 --- /dev/null +++ b/xmpp-vala/src/module/xep/0030_service_discovery/identity.vala @@ -0,0 +1,18 @@ +namespace Xmpp.Xep.ServiceDiscovery { + +public class Identity { + public const string CATEGORY_CLIENT = "client"; + public const string CATEGORY_CONFERENCE = "conference"; + + public string category { get; set; } + public string type_ { get; set; } + public string? name { get; set; } + + public Identity(string category, string type, string? name = null) { + this.category = category; + this.type_ = type; + this.name = name; + } +} + +} \ No newline at end of file diff --git a/xmpp-vala/src/module/xep/0030_service_discovery/info_result.vala b/xmpp-vala/src/module/xep/0030_service_discovery/info_result.vala index 7e0f0ea4..ae6b9caf 100644 --- a/xmpp-vala/src/module/xep/0030_service_discovery/info_result.vala +++ b/xmpp-vala/src/module/xep/0030_service_discovery/info_result.vala @@ -39,30 +39,16 @@ public class InfoResult { } } - public void add_feature(string feature) { - iq.stanza.get_subnode("query", NS_URI_INFO).put_node(new StanzaNode.build("feature", NS_URI_INFO).put_attribute("var", feature)); - } - - public void add_identity(Identity identity) { - StanzaNode identity_node = new StanzaNode.build("identity", NS_URI_INFO) - .put_attribute("category", identity.category) - .put_attribute("type", identity.type_); - if (identity.name != null) { - identity_node.put_attribute("name", identity.name); - } - iq.stanza.get_subnode("query", NS_URI_INFO).put_node(identity_node); - } - - private InfoResult.from_iq(Iq.Stanza iq) { - this.iq = iq; - } - public InfoResult(Iq.Stanza iq_request) { iq = new Iq.Stanza.result(iq_request); iq.to = iq_request.from; iq.stanza.put_node(new StanzaNode.build("query", NS_URI_INFO).add_self_xmlns()); } + private InfoResult.from_iq(Iq.Stanza iq) { + this.iq = iq; + } + public static InfoResult? create_from_iq(Iq.Stanza iq) { if (iq.is_error()) return null; StanzaNode query_node = iq.stanza.get_subnode("query", NS_URI_INFO); @@ -73,6 +59,20 @@ public class InfoResult { if (identity_node == null) return null; return new ServiceDiscovery.InfoResult.from_iq(iq); } + + public void add_feature(string feature) { + iq.stanza.get_subnode("query", NS_URI_INFO).put_node(new StanzaNode.build("feature", NS_URI_INFO).put_attribute("var", feature)); + } + + public void add_identity(Identity identity) { + StanzaNode identity_node = new StanzaNode.build("identity", NS_URI_INFO) + .put_attribute("category", identity.category) + .put_attribute("type", identity.type_); + if (identity.name != null) { + identity_node.put_attribute("name", identity.name); + } + iq.stanza.get_subnode("query", NS_URI_INFO).put_node(identity_node); + } } } \ No newline at end of file diff --git a/xmpp-vala/src/module/xep/0030_service_discovery/item.vala b/xmpp-vala/src/module/xep/0030_service_discovery/item.vala new file mode 100644 index 00000000..9d8f1f3e --- /dev/null +++ b/xmpp-vala/src/module/xep/0030_service_discovery/item.vala @@ -0,0 +1,15 @@ +namespace Xmpp.Xep.ServiceDiscovery { + +public class Item { + public string jid; + public string? name; + public string? node; + + public Item(string jid, string? name = null, string? node = null) { + this.jid = jid; + this.name = name; + this.node = node; + } +} + +} \ No newline at end of file diff --git a/xmpp-vala/src/module/xep/0030_service_discovery/module.vala b/xmpp-vala/src/module/xep/0030_service_discovery/module.vala index 4b51e230..2ec0f630 100644 --- a/xmpp-vala/src/module/xep/0030_service_discovery/module.vala +++ b/xmpp-vala/src/module/xep/0030_service_discovery/module.vala @@ -3,109 +3,94 @@ using Gee; using Xmpp.Core; namespace Xmpp.Xep.ServiceDiscovery { - private const string NS_URI = "http://jabber.org/protocol/disco"; - public const string NS_URI_INFO = NS_URI + "#info"; - public const string NS_URI_ITEMS = NS_URI + "#items"; - public class Module : XmppStreamModule, Iq.Handler { - public static ModuleIdentity IDENTITY = new ModuleIdentity(NS_URI, "0030_service_discovery_module"); +private const string NS_URI = "http://jabber.org/protocol/disco"; +public const string NS_URI_INFO = NS_URI + "#info"; +public const string NS_URI_ITEMS = NS_URI + "#items"; - public ArrayList identities = new ArrayList(); +public class Module : XmppStreamModule, Iq.Handler { + public static ModuleIdentity IDENTITY = new ModuleIdentity(NS_URI, "0030_service_discovery_module"); - public Module.with_identity(string category, string type, string? name = null) { - add_identity(category, type, name); - } - - public void add_feature(XmppStream stream, string feature) { - stream.get_flag(Flag.IDENTITY).add_own_feature(feature); - } - - public void add_feature_notify(XmppStream stream, string feature) { - add_feature(stream, feature + "+notify"); - } - - public void add_identity(string category, string type, string? name = null) { - identities.add(new Identity(category, type, name)); - } - - [CCode (has_target = false)] public delegate void OnInfoResult(XmppStream stream, InfoResult query_result, Object? store); - public void request_info(XmppStream stream, string jid, OnInfoResult listener, Object? store) { - Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_INFO).add_self_xmlns()); - iq.to = jid; - stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, on_request_info_response, Tuple.create(listener, store)); - } - - [CCode (has_target = false)] public delegate void OnItemsResult(XmppStream stream, ItemsResult query_result); - public void request_items(XmppStream stream, string jid, OnItemsResult listener, Object? store) { - Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_ITEMS).add_self_xmlns()); - iq.to = jid; - stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq); - } - - public void on_iq_get(XmppStream stream, Iq.Stanza iq) { - StanzaNode? query_node = iq.stanza.get_subnode("query", NS_URI_INFO); - if (query_node != null) { - send_query_result(stream, iq); - } - } + public ArrayList identities = new ArrayList(); - public void on_iq_set(XmppStream stream, Iq.Stanza iq) { } + public Module.with_identity(string category, string type, string? name = null) { + add_identity(category, type, name); + } - public override void attach(XmppStream stream) { - Iq.Module.require(stream); - stream.get_module(Iq.Module.IDENTITY).register_for_namespace(NS_URI_INFO, this); - stream.add_flag(new Flag()); - add_feature(stream, NS_URI_INFO); - } + public void add_feature(XmppStream stream, string feature) { + stream.get_flag(Flag.IDENTITY).add_own_feature(feature); + } - public override void detach(XmppStream stream) { } + public void add_feature_notify(XmppStream stream, string feature) { + add_feature(stream, feature + "+notify"); + } - public static void require(XmppStream stream) { - if (stream.get_module(IDENTITY) == null) stream.add_module(new ServiceDiscovery.Module()); - } + public void add_identity(string category, string type, string? name = null) { + identities.add(new Identity(category, type, name)); + } - public override string get_ns() { return NS_URI; } - public override string get_id() { return IDENTITY.id; } + [CCode (has_target = false)] public delegate void HasEntryCategoryRes(XmppStream stream, ArrayList? identities, Object? store); + public void get_entity_categories(XmppStream stream, string jid, HasEntryCategoryRes on_result, Object? store) { + ArrayList? res = stream.get_flag(Flag.IDENTITY).get_entity_categories(jid); + if (res != null) on_result(stream, res, store); + request_info(stream, jid, (stream, query_result, store) => { + Tuple tuple = store as Tuple; + tuple.a(stream, query_result != null ? query_result.identities : null, tuple.b); + }, Tuple.create(on_result, store)); + } - private static void on_request_info_response(XmppStream stream, Iq.Stanza iq, Object o) { + [CCode (has_target = false)] public delegate void OnInfoResult(XmppStream stream, InfoResult? query_result, Object? store); + public void request_info(XmppStream stream, string jid, OnInfoResult listener, Object? store) { + Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_INFO).add_self_xmlns()); + iq.to = jid; + stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, (stream, iq, o) => { Tuple tuple = o as Tuple; OnInfoResult on_result = tuple.a; InfoResult? result = InfoResult.create_from_iq(iq); - if (result != null) { - stream.get_flag(Flag.IDENTITY).set_entitiy_features(iq.from, result.features); - on_result(stream, result, tuple.b); - } - } + stream.get_flag(Flag.IDENTITY).set_entity_features(iq.from, result != null ? result.features : null); + stream.get_flag(Flag.IDENTITY).set_entity_identities(iq.from, result != null ? result.identities : null); + on_result(stream, result, tuple.b); + }, Tuple.create(listener, store)); + } + + [CCode (has_target = false)] public delegate void OnItemsResult(XmppStream stream, ItemsResult query_result); + public void request_items(XmppStream stream, string jid, OnItemsResult listener, Object? store) { + Iq.Stanza iq = new Iq.Stanza.get(new StanzaNode.build("query", NS_URI_ITEMS).add_self_xmlns()); + iq.to = jid; + stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq); + } - private void send_query_result(XmppStream stream, Iq.Stanza iq_request) { - InfoResult query_result = new ServiceDiscovery.InfoResult(iq_request); - query_result.features = stream.get_flag(Flag.IDENTITY).features; - query_result.identities = identities; - stream.get_module(Iq.Module.IDENTITY).send_iq(stream, query_result.iq); + public void on_iq_get(XmppStream stream, Iq.Stanza iq) { + StanzaNode? query_node = iq.stanza.get_subnode("query", NS_URI_INFO); + if (query_node != null) { + send_query_result(stream, iq); } } - public class Identity { - public string category { get; set; } - public string type_ { get; set; } - public string? name { get; set; } + public void on_iq_set(XmppStream stream, Iq.Stanza iq) { } - public Identity(string category, string type, string? name = null) { - this.category = category; - this.type_ = type; - this.name = name; - } + public override void attach(XmppStream stream) { + Iq.Module.require(stream); + stream.get_module(Iq.Module.IDENTITY).register_for_namespace(NS_URI_INFO, this); + stream.add_flag(new Flag()); + add_feature(stream, NS_URI_INFO); } - public class Item { - public string jid; - public string? name; - public string? node; + public override void detach(XmppStream stream) { } - public Item(string jid, string? name = null, string? node = null) { - this.jid = jid; - this.name = name; - this.node = node; - } + public static void require(XmppStream stream) { + if (stream.get_module(IDENTITY) == null) stream.add_module(new ServiceDiscovery.Module()); } + + public override string get_ns() { return NS_URI; } + public override string get_id() { return IDENTITY.id; } + + private void send_query_result(XmppStream stream, Iq.Stanza iq_request) { + InfoResult query_result = new ServiceDiscovery.InfoResult(iq_request); + query_result.features = stream.get_flag(Flag.IDENTITY).features; + query_result.identities = identities; + stream.get_module(Iq.Module.IDENTITY).send_iq(stream, query_result.iq); + } +} + } diff --git a/xmpp-vala/src/module/xep/0045_muc/module.vala b/xmpp-vala/src/module/xep/0045_muc/module.vala index 624d8421..486c342a 100644 --- a/xmpp-vala/src/module/xep/0045_muc/module.vala +++ b/xmpp-vala/src/module/xep/0045_muc/module.vala @@ -129,7 +129,7 @@ public class Module : XmppStreamModule { string bare_jid = get_bare_jid(presence.from); ErrorStanza? error_stanza = presence.get_error(); if (flag.get_enter_id(bare_jid) == error_stanza.original_id) { - ListenerHolder listener = flag.get_enter_listener(bare_jid); + ListenerHolder? listener = flag.get_enter_listener(bare_jid); MucEnterError? error = null; if (error_stanza.condition == ErrorStanza.CONDITION_NOT_AUTHORIZED && ErrorStanza.TYPE_AUTH == error_stanza.type_) { error = MucEnterError.PASSWORD_REQUIRED; @@ -144,7 +144,7 @@ public class Module : XmppStreamModule { } else if (ErrorStanza.CONDITION_ITEM_NOT_FOUND == error_stanza.condition && ErrorStanza.TYPE_CANCEL == error_stanza.type_) { error = MucEnterError.ROOM_DOESNT_EXIST; } - if (error == null) listener.on_error(stream, error, listener.reference); + if (error != null && listener != null) listener.on_error(stream, error, listener.reference); flag.finish_muc_enter(bare_jid); } } diff --git a/xmpp-vala/src/module/xep/0115_entitiy_capabilities.vala b/xmpp-vala/src/module/xep/0115_entitiy_capabilities.vala index e1d6e6ff..a3f0a704 100644 --- a/xmpp-vala/src/module/xep/0115_entitiy_capabilities.vala +++ b/xmpp-vala/src/module/xep/0115_entitiy_capabilities.vala @@ -59,12 +59,13 @@ namespace Xmpp.Xep.EntityCapabilities { if (capabilities.size == 0) { stream.get_module(ServiceDiscovery.Module.IDENTITY).request_info(stream, presence.from, on_received_info_response, Tuple.create(storage, ver_attribute)); } else { - stream.get_flag(ServiceDiscovery.Flag.IDENTITY).set_entitiy_features(presence.from, capabilities); + stream.get_flag(ServiceDiscovery.Flag.IDENTITY).set_entity_features(presence.from, capabilities); } } } - private static void on_received_info_response(XmppStream stream, ServiceDiscovery.InfoResult query_result, Object? store) { + private static void on_received_info_response(XmppStream stream, ServiceDiscovery.InfoResult? query_result, Object? store) { + if (query_result == null) return; Tuple tuple = store as Tuple; Storage storage = tuple.a; string entity = tuple.b; -- cgit v1.2.3-70-g09d2