From 3496abfdacdb40cd401952b7512c1221e771280e Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Sun, 27 Oct 2019 14:45:57 +0000 Subject: util.pubsub, pubsub.lib and tests: Add text to precondition-not-met error (fixes #1455) --- plugins/mod_pubsub/pubsub.lib.lua | 4 + spec/scansion/pubsub_preconditions.scs | 234 +++++++++++++++++++++++++++++++++ spec/util_pubsub_spec.lua | 2 +- util/pubsub.lua | 12 +- 4 files changed, 248 insertions(+), 4 deletions(-) create mode 100644 spec/scansion/pubsub_preconditions.scs diff --git a/plugins/mod_pubsub/pubsub.lib.lua b/plugins/mod_pubsub/pubsub.lib.lua index a002fbe7..23695211 100644 --- a/plugins/mod_pubsub/pubsub.lib.lua +++ b/plugins/mod_pubsub/pubsub.lib.lua @@ -7,6 +7,7 @@ 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 xmlns_pubsub = "http://jabber.org/protocol/pubsub"; local xmlns_pubsub_errors = "http://jabber.org/protocol/pubsub#errors"; @@ -34,6 +35,9 @@ local pubsub_errors = { }; 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(); diff --git a/spec/scansion/pubsub_preconditions.scs b/spec/scansion/pubsub_preconditions.scs new file mode 100644 index 00000000..25afaa8d --- /dev/null +++ b/spec/scansion/pubsub_preconditions.scs @@ -0,0 +1,234 @@ +# Pubsub preconditions are enforced + +[Client] Romeo + password: password + jid: jqpcrbq2@localhost + +----- + +Romeo connects + +Romeo sends: + + + + + + + + + + +Romeo receives: + + + + + + + + +Romeo sends: + + + + + + +Romeo receives: + + + + + + http://jabber.org/protocol/pubsub#node_config + + + + + + + 1 + + + 1 + + + + + + + + presence + + + + + + publishers + + + 1 + + + 1 + + + + + headline + + + 1 + + + 1 + + + + + + +Romeo sends: + + + + + + http://jabber.org/protocol/pubsub#node_config + + + Nice tunes + + + + + + 1 + + + 1 + + + + + + + + presence + + + + + + publishers + + + 1 + + + 1 + + + + + headline + + + 1 + + + 1 + + + + + + +Romeo receives: + + +Romeo sends: + + + + +Romeo receives: + + + + + + +Romeo sends: + + + + + + + + + + + http://jabber.org/protocol/pubsub#publish-options + + + whitelist + + + + + + +Romeo receives: + + + + Field does not match: access_model + + + + +Romeo disconnects + diff --git a/spec/util_pubsub_spec.lua b/spec/util_pubsub_spec.lua index c982fb36..a48bd400 100644 --- a/spec/util_pubsub_spec.lua +++ b/spec/util_pubsub_spec.lua @@ -107,7 +107,7 @@ describe("util.pubsub", function () it("fails to publish to a node with differing config", function () local ok, err = service:publish("node", true, "1", "item 2", { myoption = false }); assert.falsy(ok); - assert.equals("precondition-not-met", err); + assert.equals("precondition-not-met", err.pubsub_condition); end); it("allows to publish to a node with differing config when only defaults are suggested", function () diff --git a/util/pubsub.lua b/util/pubsub.lua index e5e0cb7c..8a07c669 100644 --- a/util/pubsub.lua +++ b/util/pubsub.lua @@ -1,5 +1,6 @@ local events = require "util.events"; local cache = require "util.cache"; +local errors = require "util.error"; local service_mt = {}; @@ -510,7 +511,7 @@ local function check_preconditions(node_config, required_config) end for config_field, value in pairs(required_config) do if node_config[config_field] ~= value then - return false; + return false, config_field; end end return true; @@ -546,8 +547,13 @@ function service:publish(node, actor, id, item, requested_config) --> ok, err node_obj = self.nodes[node]; elseif requested_config and not requested_config._defaults_only then -- Check that node has the requested config before we publish - if not check_preconditions(node_obj.config, requested_config) then - return false, "precondition-not-met"; + local ok, field = check_preconditions(node_obj.config, requested_config); + if not ok then + local err = errors.new({ + type = "cancel", condition = "conflict", text = "Field does not match: "..field; + }); + err.pubsub_condition = "precondition-not-met"; + return false, err; end end if not self.config.itemcheck(item) then -- cgit v1.2.3