Mercurial > prosody-hg
comparison util/pubsub.lua @ 14116:c8458864dcea
util.pubsub: Allow publishers to retract items they published
This requires the service configuration to provide an iteminfo() callback
which returns a table of metadata including a 'publisher' field.
Retraction is permitted only if the JID (currently) has permission to publish,
and they were the publisher of the item.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 31 Mar 2026 14:13:32 +0100 |
| parents | 3b357ab6b6eb |
| children | 221f3378e7f4 |
comparison
equal
deleted
inserted
replaced
| 14115:44a8c8d4146a | 14116:c8458864dcea |
|---|---|
| 7 max_items = 256; | 7 max_items = 256; |
| 8 itemstore = function (config, _) return cache.new(config["max_items"]) end; | 8 itemstore = function (config, _) return cache.new(config["max_items"]) end; |
| 9 broadcaster = function () end; | 9 broadcaster = function () end; |
| 10 subscriber_filter = function (subs) return subs end; | 10 subscriber_filter = function (subs) return subs end; |
| 11 itemcheck = function () return true; end; | 11 itemcheck = function () return true; end; |
| 12 iteminfo = function () return nil; end; | |
| 12 get_affiliation = function () end; | 13 get_affiliation = function () end; |
| 13 normalize_jid = function (jid) return jid; end; | 14 normalize_jid = function (jid) return jid; end; |
| 14 metadata_subset = {}; | 15 metadata_subset = {}; |
| 15 capabilities = { | 16 capabilities = { |
| 16 outcast = { | 17 outcast = { |
| 594 return self.config.broadcaster(event, node, subscribers, item, actor, node_obj, self); | 595 return self.config.broadcaster(event, node, subscribers, item, actor, node_obj, self); |
| 595 end | 596 end |
| 596 | 597 |
| 597 function service:retract(node, actor, id, retract) --> ok, err | 598 function service:retract(node, actor, id, retract) --> ok, err |
| 598 -- Access checking | 599 -- Access checking |
| 599 if not self:may(node, actor, "retract") then | 600 local may_retract = self:may(node, actor, "retract"); |
| 600 return false, "forbidden"; | 601 |
| 602 if not may_retract then | |
| 603 local node_obj = self.nodes[node]; | |
| 604 local publish_model = node_obj and node_obj.config.publish_model; | |
| 605 local may_publish = ( | |
| 606 publish_model == "open" | |
| 607 or (publish_model == "subscribers" and node_obj.subscribers[actor]) | |
| 608 ); | |
| 609 if not may_publish then | |
| 610 return false, "forbidden"; | |
| 611 end | |
| 612 -- Otherwise, we continue on, with may_retract = false, which | |
| 613 -- indicates they cannot retract items published by *others* | |
| 614 -- but may still retract their own items | |
| 601 end | 615 end |
| 602 -- | 616 -- |
| 603 local node_obj = self.nodes[node]; | 617 local node_obj = self.nodes[node]; |
| 604 if not node_obj then | 618 if not node_obj then |
| 605 return false, "item-not-found"; | 619 return false, "item-not-found"; |
| 606 end | 620 end |
| 607 if self.data[node] then | 621 if self.data[node] then |
| 608 if not self.data[node]:get(id) then | 622 local item = self.data[node]:get(id); |
| 623 if not item then | |
| 609 return false, "item-not-found"; | 624 return false, "item-not-found"; |
| 610 end | 625 end |
| 626 | |
| 627 if not may_retract then | |
| 628 -- May not generally retract all items, so check if they are the publisher | |
| 629 local info = self.config.iteminfo(item); | |
| 630 local is_publisher = info and info.publisher and self:jids_equal(info.publisher, actor); | |
| 631 if not is_publisher then | |
| 632 return false, "forbidden"; | |
| 633 end | |
| 634 end | |
| 635 | |
| 611 local ok = self.data[node]:set(id, nil); | 636 local ok = self.data[node]:set(id, nil); |
| 612 if not ok then | 637 if not ok then |
| 613 return nil, "internal-server-error"; | 638 return nil, "internal-server-error"; |
| 614 end | 639 end |
| 615 end | 640 end |
