aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_pep.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mod_pep.lua')
-rw-r--r--plugins/mod_pep.lua73
1 files changed, 49 insertions, 24 deletions
diff --git a/plugins/mod_pep.lua b/plugins/mod_pep.lua
index 4ee3db5e..71e45e7c 100644
--- a/plugins/mod_pep.lua
+++ b/plugins/mod_pep.lua
@@ -8,6 +8,7 @@ local calculate_hash = require "util.caps".calculate_hash;
local is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
local cache = require "util.cache";
local set = require "util.set";
+local new_id = require "util.id".medium;
local storagemanager = require "core.storagemanager";
local usermanager = require "core.usermanager";
@@ -50,6 +51,20 @@ local known_nodes = module:open_store("pep");
local max_max_items = module:get_option_number("pep_max_items", 256);
+local function tonumber_max_items(n)
+ if n == "max" then
+ return max_max_items;
+ end
+ return tonumber(n);
+end
+
+for _, field in ipairs(lib_pubsub.node_config_form) do
+ if field.var == "pubsub#max_items" then
+ field.range_max = max_max_items;
+ break;
+ end
+end
+
function module.save()
return {
recipients = recipients;
@@ -65,7 +80,7 @@ function is_item_stanza(item)
end
function check_node_config(node, actor, new_config) -- luacheck: ignore 212/node 212/actor
- if (new_config["max_items"] or 1) > max_max_items then
+ if (tonumber_max_items(new_config["max_items"]) or 1) > max_max_items then
return false;
end
if new_config["access_model"] ~= "presence"
@@ -111,14 +126,10 @@ end
local function simple_itemstore(username)
local driver = storagemanager.get_driver(module.host, "pep_data");
return function (config, node)
- if config["persist_items"] then
- module:log("debug", "Creating new persistent item store for user %s, node %q", username, node);
- local archive = driver:open("pep_"..node, "archive");
- return lib_pubsub.archive_itemstore(archive, config, username, node, false);
- else
- module:log("debug", "Creating new ephemeral item store for user %s, node %q", username, node);
- return cache.new(tonumber(config["max_items"]));
- end
+ local max_items = tonumber_max_items(config["max_items"]);
+ module:log("debug", "Creating new persistent item store for user %s, node %q", username, node);
+ local archive = driver:open("pep_"..node, "archive");
+ return lib_pubsub.archive_itemstore(archive, max_items, username, node, false);
end
end
@@ -133,9 +144,6 @@ local function get_broadcaster(username)
if kind == "retract" then
kind = "items"; -- XEP-0060 signals retraction in an <items> container
end
- local message = st.message({ from = user_bare, type = "headline" })
- :tag("event", { xmlns = xmlns_pubsub_event })
- :tag(kind, { node = node });
if item then
item = st.clone(item);
item.attr.xmlns = nil; -- Clear the pubsub namespace
@@ -144,10 +152,19 @@ local function get_broadcaster(username)
item:maptags(function () return nil; end);
end
end
+ end
+
+ local id = new_id();
+ local message = st.message({ from = user_bare, type = "headline", id = id })
+ :tag("event", { xmlns = xmlns_pubsub_event })
+ :tag(kind, { node = node });
+
+ if item then
message:add_child(item);
end
+
for jid in pairs(jids) do
- module:log("debug", "Sending notification to %s from %s: %s", jid, user_bare, tostring(item));
+ module:log("debug", "Sending notification to %s from %s for node %s", jid, user_bare, node);
message.attr.to = jid;
module:send(message);
end
@@ -175,19 +192,23 @@ local function get_subscriber_filter(username)
end
end
+-- Read-only service with no nodes where nobody is allowed anything to act as a
+-- fallback for interactions with non-existent users
local nobody_service = pubsub.new({
- service = pubsub.new({
- node_defaults = {
- ["max_items"] = 1;
- ["persist_items"] = false;
- ["access_model"] = "presence";
- ["send_last_published_item"] = "on_sub_and_presence";
- };
- });
+ node_defaults = {
+ ["max_items"] = 1;
+ ["persist_items"] = false;
+ ["access_model"] = "presence";
+ ["send_last_published_item"] = "on_sub_and_presence";
+ };
+ autocreate_on_publish = false;
+ autocreate_on_subscribe = false;
+ get_affiliation = function ()
+ return "outcast";
+ end;
});
function get_pep_service(username)
- module:log("debug", "get_pep_service(%q)", username);
local user_bare = jid_join(username, host);
local service = services[username];
if service then
@@ -196,13 +217,16 @@ function get_pep_service(username)
if not usermanager.user_exists(username, host) then
return nobody_service;
end
+ module:log("debug", "Creating pubsub service for user %q", username);
service = pubsub.new({
pep_username = username;
node_defaults = {
["max_items"] = 1;
["persist_items"] = true;
["access_model"] = "presence";
+ ["send_last_published_item"] = "on_sub_and_presence";
};
+ max_items = max_max_items;
autocreate_on_publish = true;
autocreate_on_subscribe = false;
@@ -227,6 +251,7 @@ function get_pep_service(username)
end;
};
+ jid = user_bare;
normalize_jid = jid_bare;
check_node_config = check_node_config;
@@ -252,8 +277,6 @@ end
module:hook("iq/bare/"..xmlns_pubsub..":pubsub", handle_pubsub_iq);
module:hook("iq/bare/"..xmlns_pubsub_owner..":pubsub", handle_pubsub_iq);
-module:add_identity("pubsub", "pep", module:get_option_string("name", "Prosody"));
-module:add_feature("http://jabber.org/protocol/pubsub#publish");
local function get_caps_hash_from_presence(stanza, current)
local t = stanza.attr.type;
@@ -279,6 +302,8 @@ local function get_caps_hash_from_presence(stanza, current)
end
local function resend_last_item(jid, node, service)
+ local ok, config = service:get_node_config(node, true);
+ if ok and config.send_last_published_item ~= "on_sub_and_presence" then return end
local ok, id, item = service:get_last_item(node, jid);
if not (ok and id) then return; end
service.config.broadcaster("items", node, { [jid] = true }, item);