aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/mod_pubsub/pubsub.lib.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/mod_pubsub/pubsub.lib.lua')
-rw-r--r--plugins/mod_pubsub/pubsub.lib.lua100
1 files changed, 57 insertions, 43 deletions
diff --git a/plugins/mod_pubsub/pubsub.lib.lua b/plugins/mod_pubsub/pubsub.lib.lua
index 3196569f..f4d44f36 100644
--- a/plugins/mod_pubsub/pubsub.lib.lua
+++ b/plugins/mod_pubsub/pubsub.lib.lua
@@ -1,13 +1,12 @@
-local t_unpack = table.unpack or unpack; -- luacheck: ignore 113
local time_now = os.time;
-local jid_prep = require "util.jid".prep;
-local set = require "util.set";
-local st = require "util.stanza";
-local it = require "util.iterators";
-local uuid_generate = require "util.uuid".generate;
-local dataform = require"util.dataforms".new;
-local errors = require "util.error";
+local jid_prep = require "prosody.util.jid".prep;
+local set = require "prosody.util.set";
+local st = require "prosody.util.stanza";
+local it = require "prosody.util.iterators";
+local uuid_generate = require "prosody.util.uuid".generate;
+local dataform = require"prosody.util.dataforms".new;
+local errors = require "prosody.util.error";
local xmlns_pubsub = "http://jabber.org/protocol/pubsub";
local xmlns_pubsub_errors = "http://jabber.org/protocol/pubsub#errors";
@@ -18,7 +17,7 @@ local _M = {};
local handlers = {};
_M.handlers = handlers;
-local pubsub_errors = {
+local pubsub_errors = errors.init("pubsub", xmlns_pubsub_errors, {
["conflict"] = { "cancel", "conflict" };
["invalid-jid"] = { "modify", "bad-request", nil, "invalid-jid" };
["jid-required"] = { "modify", "bad-request", nil, "jid-required" };
@@ -33,16 +32,13 @@ local pubsub_errors = {
["precondition-not-met"] = { "cancel", "conflict", nil, "precondition-not-met" };
["invalid-item"] = { "modify", "bad-request", "invalid item" };
["persistent-items-unsupported"] = { "cancel", "feature-not-implemented", nil, "persistent-items" };
-};
-local function pubsub_error_reply(stanza, error)
- local e = pubsub_errors[error];
- if not e and errors.is_err(error) then
- e = { error.type, error.condition, error.text, error.pubsub_condition };
- end
- local reply = st.error_reply(stanza, t_unpack(e, 1, 3));
- if e[4] then
- reply:tag(e[4], { xmlns = xmlns_pubsub_errors }):up();
+});
+local function pubsub_error_reply(stanza, error, context)
+ local err = pubsub_errors.wrap(error, context);
+ if error == "precondition-not-met" and type(context) == "table" and type(context.field) == "string" then
+ err.text = "Field does not match: " .. context.field;
end
+ local reply = st.error_reply(stanza, err);
return reply;
end
_M.pubsub_error_reply = pubsub_error_reply;
@@ -110,6 +106,12 @@ local node_config_form = dataform {
};
};
{
+ type = "list-multi"; -- TODO some way to inject options
+ name = "roster_groups_allowed";
+ var = "pubsub#roster_groups_allowed";
+ label = "Roster groups allowed to subscribe";
+ };
+ {
type = "list-single";
name = "publish_model";
var = "pubsub#publish_model";
@@ -164,6 +166,17 @@ local node_config_form = dataform {
var = "pubsub#notify_retract";
value = true;
};
+ {
+ type = "list-single";
+ label = "Specify whose JID to include as the publisher of items";
+ name = "itemreply";
+ var = "pubsub#itemreply";
+ options = {
+ { label = "Include the node owner's JID", value = "owner" };
+ { label = "Include the item publisher's JID", value = "publisher" };
+ { label = "Don't include any JID with items", value = "none", default = true };
+ };
+ };
};
_M.node_config_form = node_config_form;
@@ -189,23 +202,28 @@ local node_metadata_form = dataform {
};
{
type = "text-single";
- name = "pubsub#title";
+ name = "title";
+ var = "pubsub#title";
};
{
type = "text-single";
- name = "pubsub#description";
+ name = "description";
+ var = "pubsub#description";
};
{
type = "text-single";
- name = "pubsub#type";
+ name = "payload_type";
+ var = "pubsub#type";
};
{
type = "text-single";
- name = "pubsub#access_model";
+ name = "access_model";
+ var = "pubsub#access_model";
};
{
type = "text-single";
- name = "pubsub#publish_model";
+ name = "publish_model";
+ var = "pubsub#publish_model";
};
};
_M.node_metadata_form = node_metadata_form;
@@ -277,27 +295,14 @@ end
function _M.handle_disco_info_node(event, service)
local stanza, reply, node = event.stanza, event.reply, event.node;
- local ok, ret = service:get_nodes(stanza.attr.from);
+ local ok, meta = service:get_node_metadata(node, stanza.attr.from);
if not ok then
- event.origin.send(pubsub_error_reply(stanza, ret));
- return true;
- end
- local node_obj = ret[node];
- if not node_obj then
- event.origin.send(pubsub_error_reply(stanza, "item-not-found"));
+ event.origin.send(pubsub_error_reply(stanza, meta));
return true;
end
event.exists = true;
reply:tag("identity", { category = "pubsub", type = "leaf" }):up();
- if node_obj.config then
- reply:add_child(node_metadata_form:form({
- ["pubsub#title"] = node_obj.config.title;
- ["pubsub#description"] = node_obj.config.description;
- ["pubsub#type"] = node_obj.config.payload_type;
- ["pubsub#access_model"] = node_obj.config.access_model;
- ["pubsub#publish_model"] = node_obj.config.publish_model;
- }, "result"));
- end
+ reply:add_child(node_metadata_form:form(meta, "result"));
end
function _M.handle_disco_items_node(event, service)
@@ -347,6 +352,13 @@ function handlers.get_items(origin, stanza, items, service)
origin.send(pubsub_error_reply(stanza, "nodeid-required"));
return true;
end
+
+ local node_obj = service.nodes[node];
+ if not node_obj then
+ origin.send(pubsub_error_reply(stanza, "item-not-found"));
+ return true;
+ end
+
local resultspec; -- TODO rsm.get()
if items.attr.max_items then
resultspec = { max = tonumber(items.attr.max_items) };
@@ -358,6 +370,9 @@ function handlers.get_items(origin, stanza, items, service)
end
local expose_publisher = service.config.expose_publisher;
+ if expose_publisher == nil and node_obj.config.itemreply == "publisher" then
+ expose_publisher = true;
+ end
local data = st.stanza("items", { node = node });
local iter, v, i = ipairs(results);
@@ -658,7 +673,7 @@ function handlers.set_publish(origin, stanza, publish, service)
if item then
item.attr.publisher = service.config.normalize_jid(stanza.attr.from);
end
- local ok, ret = service:publish(node, stanza.attr.from, id, item, required_config);
+ local ok, ret, context = service:publish(node, stanza.attr.from, id, item, required_config);
local reply;
if ok then
if type(ok) == "string" then
@@ -669,7 +684,7 @@ function handlers.set_publish(origin, stanza, publish, service)
:tag("publish", { node = node })
:tag("item", { id = id });
else
- reply = pubsub_error_reply(stanza, ret);
+ reply = pubsub_error_reply(stanza, ret, context);
end
origin.send(reply);
return true;
@@ -678,8 +693,7 @@ end
function handlers.set_retract(origin, stanza, retract, service)
local node, notify = retract.attr.node, retract.attr.notify;
notify = (notify == "1") or (notify == "true");
- local item = retract:get_child("item");
- local id = item and item.attr.id
+ local id = retract:get_child_attr("item", nil, "id");
if not (node and id) then
origin.send(pubsub_error_reply(stanza, node and "item-not-found" or "nodeid-required"));
return true;