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