diff options
Diffstat (limited to 'plugins/mod_pubsub')
-rw-r--r-- | plugins/mod_pubsub/mod_pubsub.lua | 26 | ||||
-rw-r--r-- | plugins/mod_pubsub/pubsub.lib.lua | 87 |
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; |