plugins/mod_pep.lua
changeset 12095 7a48ccb084dd
parent 12026 eedd3eff0768
parent 12093 76b4e3f12b53
child 12157 26af75c20163
equal deleted inserted replaced
12087:ec21e379c145 12095:7a48ccb084dd
     4 local jid_join = require "util.jid".join;
     4 local jid_join = require "util.jid".join;
     5 local set_new = require "util.set".new;
     5 local set_new = require "util.set".new;
     6 local st = require "util.stanza";
     6 local st = require "util.stanza";
     7 local calculate_hash = require "util.caps".calculate_hash;
     7 local calculate_hash = require "util.caps".calculate_hash;
     8 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
     8 local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
       
     9 local cache = require "util.cache";
     9 local set = require "util.set";
    10 local set = require "util.set";
    10 local new_id = require "util.id".medium;
    11 local new_id = require "util.id".medium;
    11 local storagemanager = require "core.storagemanager";
    12 local storagemanager = require "core.storagemanager";
       
    13 local usermanager = require "core.usermanager";
    12 
    14 
    13 local xmlns_pubsub = "http://jabber.org/protocol/pubsub";
    15 local xmlns_pubsub = "http://jabber.org/protocol/pubsub";
    14 local xmlns_pubsub_event = "http://jabber.org/protocol/pubsub#event";
    16 local xmlns_pubsub_event = "http://jabber.org/protocol/pubsub#event";
    15 local xmlns_pubsub_owner = "http://jabber.org/protocol/pubsub#owner";
    17 local xmlns_pubsub_owner = "http://jabber.org/protocol/pubsub#owner";
    16 
    18 
    17 local lib_pubsub = module:require "pubsub";
    19 local lib_pubsub = module:require "pubsub";
    18 
    20 
    19 local empty_set = set_new();
    21 local empty_set = set_new();
    20 
    22 
       
    23 -- username -> object passed to module:add_items()
       
    24 local pep_service_items = {};
       
    25 
       
    26 -- size of caches with full pubsub service objects
       
    27 local service_cache_size = module:get_option_number("pep_service_cache_size", 1000);
       
    28 
    21 -- username -> util.pubsub service object
    29 -- username -> util.pubsub service object
    22 local services = {};
    30 local services = cache.new(service_cache_size, function (username, _)
       
    31 	local item = pep_service_items[username];
       
    32 	pep_service_items[username] = nil;
       
    33 	if item then
       
    34 		module:remove_item("pep-service", item);
       
    35 	end
       
    36 end):table();
       
    37 
       
    38 -- size of caches with smaller objects
       
    39 local info_cache_size = module:get_option_number("pep_info_cache_size", 10000);
    23 
    40 
    24 -- username -> recipient -> set of nodes
    41 -- username -> recipient -> set of nodes
    25 local recipients = {};
    42 local recipients = cache.new(info_cache_size):table();
    26 
    43 
    27 -- caps hash -> set of nodes
    44 -- caps hash -> set of nodes
    28 local hash_map = {};
    45 local hash_map = cache.new(info_cache_size):table();
    29 
    46 
    30 local host = module.host;
    47 local host = module.host;
    31 
    48 
    32 local node_config = module:open_store("pep", "map");
    49 local node_config = module:open_store("pep", "map");
    33 local known_nodes = module:open_store("pep");
    50 local known_nodes = module:open_store("pep");
    48 	end
    65 	end
    49 end
    66 end
    50 
    67 
    51 function module.save()
    68 function module.save()
    52 	return {
    69 	return {
    53 		services = services;
       
    54 		recipients = recipients;
    70 		recipients = recipients;
    55 	};
    71 	};
    56 end
    72 end
    57 
    73 
    58 function module.restore(data)
    74 function module.restore(data)
    59 	services = data.services;
       
    60 	recipients = data.recipients;
    75 	recipients = data.recipients;
    61 	for username, service in pairs(services) do
       
    62 		local user_bare = jid_join(username, host);
       
    63 		module:add_item("pep-service", { service = service, jid = user_bare });
       
    64 	end
       
    65 end
    76 end
    66 
    77 
    67 function is_item_stanza(item)
    78 function is_item_stanza(item)
    68 	return st.is_stanza(item) and item.attr.xmlns == xmlns_pubsub and item.name == "item" and #item.tags == 1;
    79 	return st.is_stanza(item) and item.attr.xmlns == xmlns_pubsub and item.name == "item" and #item.tags == 1;
    69 end
    80 end
   179 		end
   190 		end
   180 		return broadcast_to;
   191 		return broadcast_to;
   181 	end
   192 	end
   182 end
   193 end
   183 
   194 
       
   195 local nobody_service = pubsub.new({
       
   196 	service = pubsub.new({
       
   197 		node_defaults = {
       
   198 			["max_items"] = 1;
       
   199 			["persist_items"] = false;
       
   200 			["access_model"] = "presence";
       
   201 			["send_last_published_item"] = "on_sub_and_presence";
       
   202 		};
       
   203 	});
       
   204 });
       
   205 
   184 function get_pep_service(username)
   206 function get_pep_service(username)
   185 	local user_bare = jid_join(username, host);
   207 	local user_bare = jid_join(username, host);
   186 	local service = services[username];
   208 	local service = services[username];
   187 	if service then
   209 	if service then
   188 		return service;
   210 		return service;
       
   211 	end
       
   212 	if not usermanager.user_exists(username, host) then
       
   213 		return nobody_service;
   189 	end
   214 	end
   190 	module:log("debug", "Creating pubsub service for user %q", username);
   215 	module:log("debug", "Creating pubsub service for user %q", username);
   191 	service = pubsub.new({
   216 	service = pubsub.new({
   192 		pep_username = username;
   217 		pep_username = username;
   193 		node_defaults = {
   218 		node_defaults = {
   224 		normalize_jid = jid_bare;
   249 		normalize_jid = jid_bare;
   225 
   250 
   226 		check_node_config = check_node_config;
   251 		check_node_config = check_node_config;
   227 	});
   252 	});
   228 	services[username] = service;
   253 	services[username] = service;
   229 	module:add_item("pep-service", { service = service, jid = user_bare });
   254 	local item = { service = service, jid = user_bare }
       
   255 	pep_service_items[username] = item;
       
   256 	module:add_item("pep-service", item);
   230 	return service;
   257 	return service;
   231 end
   258 end
   232 
   259 
   233 function handle_pubsub_iq(event)
   260 function handle_pubsub_iq(event)
   234 	local origin, stanza = event.origin, event.stanza;
   261 	local origin, stanza = event.origin, event.stanza;
   457 
   484 
   458 	for node, node_obj in pairs(ret) do
   485 	for node, node_obj in pairs(ret) do
   459 		reply:tag("item", { jid = user_bare, node = node, name = node_obj.config.title }):up();
   486 		reply:tag("item", { jid = user_bare, node = node, name = node_obj.config.title }):up();
   460 	end
   487 	end
   461 end);
   488 end);
       
   489 
       
   490 module:hook_global("user-deleted", function(event)
       
   491 	if event.host ~= host then return end
       
   492 	local username = event.username;
       
   493 	local service = services[username];
       
   494 	if not service then return end
       
   495 	for node in pairs(service.nodes) do service:delete(node, true); end
       
   496 
       
   497 	local item = pep_service_items[username];
       
   498 	pep_service_items[username] = nil;
       
   499 	if item then module:remove_item("pep-service", item); end
       
   500 
       
   501 	recipients[username] = nil;
       
   502 end);
       
   503