aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_pubsub
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mod_pubsub')
-rw-r--r--plugins/mod_pubsub/mod_pubsub.lua26
-rw-r--r--plugins/mod_pubsub/pubsub.lib.lua87
2 files changed, 101 insertions, 12 deletions
diff --git a/plugins/mod_pubsub/mod_pubsub.lua b/plugins/mod_pubsub/mod_pubsub.lua
index 8e7bfc53..d4733ee4 100644
--- a/plugins/mod_pubsub/mod_pubsub.lua
+++ b/plugins/mod_pubsub/mod_pubsub.lua
@@ -16,16 +16,19 @@ local service;
local lib_pubsub = module:require "pubsub";
local handlers = lib_pubsub.handlers;
-local pubsub_error_reply = lib_pubsub.pubsub_error_reply;
module:depends("disco");
module:add_identity("pubsub", "service", pubsub_disco_name);
module:add_feature("http://jabber.org/protocol/pubsub");
+--[[ TODO Disabled until config persistence is implemented
+local archive = module:open_store("pubsub", "archive");
+--]]
+
function handle_pubsub_iq(event)
local origin, stanza = event.origin, event.stanza;
- local pubsub = stanza.tags[1];
- local action = pubsub.tags[1];
+ local pubsub_tag = stanza.tags[1];
+ local action = pubsub_tag.tags[1];
if not action then
origin.send(st.error_reply(stanza, "cancel", "bad-request"));
return true;
@@ -37,6 +40,12 @@ function handle_pubsub_iq(event)
end
end
+--[[ TODO Disabled until config persistence is implemented
+local function simple_itemstore(config, node)
+ return lib_pubsub.simple_itemstore(archive, config, nil, node, expose_publisher);
+end
+--]]
+
function simple_broadcast(kind, node, jids, item, actor)
if item then
item = st.clone(item);
@@ -90,7 +99,7 @@ local function add_disco_features_from_service(service)
end
module:hook("host-disco-info-node", function (event)
- local stanza, origin, reply, node = event.stanza, event.origin, event.reply, event.node;
+ local stanza, reply, node = event.stanza, event.reply, event.node;
local ok, ret = service:get_nodes(stanza.attr.from);
if not ok or not ret[node] then
return;
@@ -100,7 +109,7 @@ module:hook("host-disco-info-node", function (event)
end);
module:hook("host-disco-items-node", function (event)
- local stanza, origin, reply, node = event.stanza, event.origin, event.reply, event.node;
+ local stanza, reply, node = event.stanza, event.reply, event.node;
local ok, ret = service:get_items(node, stanza.attr.from);
if not ok then
return;
@@ -114,8 +123,8 @@ end);
module:hook("host-disco-items", function (event)
- local stanza, origin, reply = event.stanza, event.origin, event.reply;
- local ok, ret = service:get_nodes(event.stanza.attr.from);
+ local stanza, reply = event.stanza, event.reply;
+ local ok, ret = service:get_nodes(stanza.attr.from);
if not ok then
return;
end
@@ -225,6 +234,9 @@ function module.load()
autocreate_on_publish = autocreate_on_publish;
autocreate_on_subscribe = autocreate_on_subscribe;
+ --[[ TODO Disabled until config persistence is implemented
+ itemstore = simple_itemstore;
+ --]]
broadcaster = simple_broadcast;
get_affiliation = get_affiliation;
diff --git a/plugins/mod_pubsub/pubsub.lib.lua b/plugins/mod_pubsub/pubsub.lib.lua
index 1497c21c..25a534b6 100644
--- a/plugins/mod_pubsub/pubsub.lib.lua
+++ b/plugins/mod_pubsub/pubsub.lib.lua
@@ -1,3 +1,6 @@
+local t_unpack = table.unpack or unpack; -- luacheck: ignore 113
+local time_now = os.time;
+
local st = require "util.stanza";
local uuid_generate = require "util.uuid".generate;
local dataform = require"util.dataforms".new;
@@ -23,7 +26,7 @@ local pubsub_errors = {
};
local function pubsub_error_reply(stanza, error)
local e = pubsub_errors[error];
- local reply = st.error_reply(stanza, unpack(e, 1, 3));
+ local reply = st.error_reply(stanza, t_unpack(e, 1, 3));
if e[4] then
reply:tag(e[4], { xmlns = xmlns_pubsub_errors }):up();
end
@@ -31,7 +34,7 @@ local function pubsub_error_reply(stanza, error)
end
_M.pubsub_error_reply = pubsub_error_reply;
-local node_config_form = require"util.dataforms".new {
+local node_config_form = dataform {
{
type = "hidden";
name = "FORM_TYPE";
@@ -47,13 +50,13 @@ local node_config_form = require"util.dataforms".new {
function handlers.get_items(origin, stanza, items, service)
local node = items.attr.node;
local item = items:get_child("item");
- local id = item and item.attr.id;
+ local item_id = item and item.attr.id;
if not node then
origin.send(pubsub_error_reply(stanza, "nodeid-required"));
return true;
end
- local ok, results = service:get_items(node, stanza.attr.from, id);
+ local ok, results = service:get_items(node, stanza.attr.from, item_id);
if not ok then
origin.send(pubsub_error_reply(stanza, results));
return true;
@@ -122,7 +125,7 @@ end
function handlers.set_delete(origin, stanza, delete, service)
local node = delete.attr.node;
- local reply, notifier;
+ local reply;
if not node then
origin.send(pubsub_error_reply(stanza, "nodeid-required"));
return true;
@@ -314,4 +317,78 @@ function handlers.get_default(origin, stanza, default, service)
return true;
end
+local function create_encapsulating_item(id, payload, publisher, expose_publisher)
+ local item = st.stanza("item", { id = id, xmlns = xmlns_pubsub });
+ item:add_child(payload);
+ if expose_publisher then
+ item.attr.publisher = publisher;
+ end
+ return item;
+end
+
+local function simple_itemstore(archive, config, user, node, expose_publisher)
+ module:log("debug", "Creation of itemstore for node %s with config %s", node, config);
+ local get_set = {};
+ function get_set:items()
+ local store = self.store;
+ local data, err = archive:find(user, { with = node });
+ if not data then
+ module:log("error", "Unable to get items: %s", err);
+ return true;
+ end
+ module:log("debug", "Listed items %s from store %s", data, store);
+ return function()
+ local id, payload, when, publisher = data();
+ if id == nil then
+ return;
+ end
+ local item = create_encapsulating_item(id, payload, publisher, expose_publisher);
+ return id, item;
+ end;
+ end
+ function get_set:get(key)
+ local store = self.store;
+ local data, err = archive:find(user, {
+ with = node;
+ key = key;
+ });
+ if not data then
+ module:log("error", "Unable to get item: %s", err);
+ return nil, err;
+ end
+ -- Workaround for buggy SQL drivers which require iterating until we get a nil.
+ local id, payload, when, publisher;
+ for a, b, c, d in data() do
+ id, payload, when, publisher = a, b, c, d;
+ end
+ module:log("debug", "Get item %s (published at %s by %s) from store %s", id, when, publisher, store);
+ if id == nil then
+ return nil;
+ end
+ return create_encapsulating_item(id, payload, publisher, expose_publisher);
+ end
+ function get_set:set(key, value)
+ local store = self.store;
+ module:log("debug", "Set item %s to %s for %s in store %s", key, value, node, store);
+ local data, err;
+ if value ~= nil then
+ local publisher = value.attr.publisher;
+ local payload = value.tags[1];
+ data, err = archive:append(user, key, payload, time_now(), node);
+ else
+ data, err = archive:delete(user, {
+ key = key;
+ with = node;
+ });
+ end
+ if not data then
+ module:log("error", "Unable to set item: %s", err);
+ return nil, err;
+ end
+ return data;
+ end
+ return setmetatable(get_set, archive);
+end
+_M.simple_itemstore = simple_itemstore;
+
return _M;