plugins/mod_disco.lua
changeset 3343 c70c6d5bf270
parent 2925 692b3c6c5bd2
child 3347 99f56bed5228
equal deleted inserted replaced
3342:20e99763a08a 3343:c70c6d5bf270
     9 local componentmanager_get_children = require "core.componentmanager".get_children;
     9 local componentmanager_get_children = require "core.componentmanager".get_children;
    10 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
    10 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
    11 local jid_split = require "util.jid".split;
    11 local jid_split = require "util.jid".split;
    12 local jid_bare = require "util.jid".bare;
    12 local jid_bare = require "util.jid".bare;
    13 local st = require "util.stanza"
    13 local st = require "util.stanza"
       
    14 local calculate_hash = require "util.caps".calculate_hash;
    14 
    15 
    15 local disco_items = module:get_option("disco_items") or {};
    16 local disco_items = module:get_option("disco_items") or {};
    16 do -- validate disco_items
    17 do -- validate disco_items
    17 	for _, item in ipairs(disco_items) do
    18 	for _, item in ipairs(disco_items) do
    18 		local err;
    19 		local err;
    33 
    34 
    34 module:add_identity("server", "im", "Prosody"); -- FIXME should be in the non-existing mod_router
    35 module:add_identity("server", "im", "Prosody"); -- FIXME should be in the non-existing mod_router
    35 module:add_feature("http://jabber.org/protocol/disco#info");
    36 module:add_feature("http://jabber.org/protocol/disco#info");
    36 module:add_feature("http://jabber.org/protocol/disco#items");
    37 module:add_feature("http://jabber.org/protocol/disco#items");
    37 
    38 
       
    39 -- Handle disco requests to the server
       
    40 
       
    41 local function build_server_disco_info(stanza)
       
    42 	local done = {};
       
    43 	for _,identity in ipairs(module:get_host_items("identity")) do
       
    44 		local identity_s = identity.category.."\0"..identity.type;
       
    45 		if not done[identity_s] then
       
    46 			stanza:tag("identity", identity):up();
       
    47 			done[identity_s] = true;
       
    48 		end
       
    49 	end
       
    50 	for _,feature in ipairs(module:get_host_items("feature")) do
       
    51 		if not done[feature] then
       
    52 			stanza:tag("feature", {var=feature}):up();
       
    53 			done[feature] = true;
       
    54 		end
       
    55 	end
       
    56 end
    38 module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event)
    57 module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event)
    39 	local origin, stanza = event.origin, event.stanza;
    58 	local origin, stanza = event.origin, event.stanza;
    40 	if stanza.attr.type ~= "get" then return; end
    59 	if stanza.attr.type ~= "get" then return; end
    41 	local node = stanza.tags[1].attr.node;
    60 	local node = stanza.tags[1].attr.node;
    42 	if node and node ~= "" then return; end -- TODO fire event?
    61 	if node and node ~= "" then return; end -- TODO fire event?
    43 
       
    44 	local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#info");
    62 	local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#info");
    45 	local done = {};
    63 	build_server_disco_info(reply);
    46 	for _,identity in ipairs(module:get_host_items("identity")) do
       
    47 		local identity_s = identity.category.."\0"..identity.type;
       
    48 		if not done[identity_s] then
       
    49 			reply:tag("identity", identity):up();
       
    50 			done[identity_s] = true;
       
    51 		end
       
    52 	end
       
    53 	for _,feature in ipairs(module:get_host_items("feature")) do
       
    54 		if not done[feature] then
       
    55 			reply:tag("feature", {var=feature}):up();
       
    56 			done[feature] = true;
       
    57 		end
       
    58 	end
       
    59 	origin.send(reply);
    64 	origin.send(reply);
    60 	return true;
    65 	return true;
    61 end);
    66 end);
    62 module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event)
    67 module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event)
    63 	local origin, stanza = event.origin, event.stanza;
    68 	local origin, stanza = event.origin, event.stanza;
    73 		reply:tag("item", {jid=item[1], name=item[2]}):up();
    78 		reply:tag("item", {jid=item[1], name=item[2]}):up();
    74 	end
    79 	end
    75 	origin.send(reply);
    80 	origin.send(reply);
    76 	return true;
    81 	return true;
    77 end);
    82 end);
       
    83 
       
    84 -- Server caps hash calculation
       
    85 local caps_hash_feature;
       
    86 
       
    87 local function recalculate_server_caps()
       
    88 	local caps_hash = calculate_hash(st.stanza());
       
    89 	caps_hash_feature = st.stanza("c", {
       
    90 		xmlns = "http://jabber.org/protocol/caps";
       
    91 		hash = "sha-1";
       
    92 		node = "http://prosody.im";
       
    93 		ver = caps_hash;
       
    94 	});
       
    95 end
       
    96 recalculate_server_caps();
       
    97 
       
    98 module:hook("item-added/identity", recalculate_server_caps);
       
    99 module:hook("item-added/feature", recalculate_server_caps);
       
   100 
       
   101 module:hook("stream-features", function (event)
       
   102 	if caps_hash_feature then
       
   103 		event.features:add_child(caps_hash_feature);
       
   104 	end
       
   105 end);
       
   106 
       
   107 -- Handle disco requests to user accounts
    78 module:hook("iq/bare/http://jabber.org/protocol/disco#info:query", function(event)
   108 module:hook("iq/bare/http://jabber.org/protocol/disco#info:query", function(event)
    79 	local origin, stanza = event.origin, event.stanza;
   109 	local origin, stanza = event.origin, event.stanza;
    80 	if stanza.attr.type ~= "get" then return; end
   110 	if stanza.attr.type ~= "get" then return; end
    81 	local node = stanza.tags[1].attr.node;
   111 	local node = stanza.tags[1].attr.node;
    82 	if node and node ~= "" then return; end -- TODO fire event?
   112 	if node and node ~= "" then return; end -- TODO fire event?