diff options
-rw-r--r-- | plugins/mod_pubsub.lua | 43 | ||||
-rw-r--r-- | util/pubsub.lua | 21 |
2 files changed, 60 insertions, 4 deletions
diff --git a/plugins/mod_pubsub.lua b/plugins/mod_pubsub.lua index f92d27aa..0953de28 100644 --- a/plugins/mod_pubsub.lua +++ b/plugins/mod_pubsub.lua @@ -25,8 +25,10 @@ function handle_pubsub_iq(event) end local pubsub_errors = { + ["conflict"] = { "cancel", "conflict" }; ["invalid-jid"] = { "modify", "bad-request", nil, "invalid-jid" }; ["item-not-found"] = { "cancel", "item-not-found" }; + ["not-subscribed"] = { "modify", "unexpected-request", nil, "not-subscribed" }; }; function pubsub_error_reply(stanza, error) local e = pubsub_errors[error]; @@ -50,7 +52,7 @@ function handlers.get_items(origin, stanza, items) :tag("pubsub", { xmlns = xmlns_pubsub }) :add_child(data); else - reply = st.error_reply(stanza, "cancel", "item-not-found", "Item could not be found in this node"); + reply = pubsub_error_reply(stanza, "item-not-found"); end return origin.send(reply); end @@ -63,7 +65,7 @@ function handlers.set_create(origin, stanza, create) if ok then reply = st.reply(stanza); else - reply = st.error_reply(stanza, "cancel", ret); + reply = pubsub_error_reply(stanza, ret); end else repeat @@ -74,7 +76,7 @@ function handlers.set_create(origin, stanza, create) :tag("pubsub", { xmlns = xmlns_pubsub }) :tag("create", { node = node }); end - origin.send(reply); + return origin.send(reply); end function handlers.set_subscribe(origin, stanza, subscribe) @@ -98,6 +100,21 @@ function handlers.set_subscribe(origin, stanza, subscribe) return origin.send(reply); end +function handlers.set_unsubscribe(origin, stanza, unsubscribe) + local node, jid = unsubscribe.attr.node, unsubscribe.attr.jid; + if jid_bare(jid) ~= jid_bare(stanza.attr.from) then + return origin.send(pubsub_error_reply(stanza, "invalid-jid")); + end + local ok, ret = service:remove_subscription(node, stanza.attr.from, jid); + local reply; + if ok then + reply = st.reply(stanza); + else + reply = pubsub_error_reply(stanza, ret); + end + return origin.send(reply); +end + function handlers.set_publish(origin, stanza, publish) local node = publish.attr.node; local item = publish:get_child("item"); @@ -115,7 +132,27 @@ function handlers.set_publish(origin, stanza, publish) return origin.send(reply); end +function handlers.set_retract(origin, stanza, retract) + 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 reply, notifier; + if notify then + notifier = st.stanza("retract", { id = id }); + end + local ok, ret = service:retract(node, stanza.attr.from, id, notifier); + if ok then + reply = st.reply(stanza); + else + reply = pubsub_error_reply(stanza, ret); + end + return origin.send(reply); +end + function simple_broadcast(node, jids, item) + item = st.clone(item); + item.attr.xmlns = nil; -- Clear the pubsub namespace local message = st.message({ from = module.host, type = "headline" }) :tag("event", { xmlns = xmlns_pubsub_event }) :tag("items", { node = node }) diff --git a/util/pubsub.lua b/util/pubsub.lua index dc3f3432..02e845e1 100644 --- a/util/pubsub.lua +++ b/util/pubsub.lua @@ -17,7 +17,14 @@ function service:add_subscription(node, actor, jid) end function service:remove_subscription(node, actor, jid) - self.nodes[node].subscribers[jid] = nil; + local node_obj = self.nodes[node]; + if not node_obj then + return false, "item-not-found"; + end + if not node_obj.subscribers[jid] then + return false, "not-subscribed"; + end + node_obj.subscribers[jid] = nil; return true; end @@ -47,6 +54,18 @@ function service:publish(node, actor, id, item) return true; end +function service:retract(node, actor, id, retract) + local node_obj = self.nodes[node]; + if (not node_obj) or (not node_obj.data[id]) then + return false, "item-not-found"; + end + node_obj.data[id] = nil; + if retract then + self.cb.broadcaster(node, node_obj.subscribers, retract); + end + return true +end + function service:get(node, actor, id) local node_obj = self.nodes[node]; if node_obj then |