Comparison

core/moduleapi.lua @ 12995:e385f3a06673

moduleapi: Add 'peek' to :may() and new :could() helper to suppress logging The current method logs scary "access denied" messages on failure - this is generally very useful when debugging access control stuff, but in some cases the call is simply a check to see if someone *could* perform an action, even if they haven't requested it yet. One example is determining whether to show the user as an admin in disco. The 'peek' parameter, if true, will suppress such logging. The :could() method is just a simple helper that can make the calling code a bit more readable (suggested by Zash).
author Matthew Wild <mwild1@gmail.com>
date Sun, 26 Mar 2023 14:06:04 +0100
parent 12994:5625da6ae6b6
child 13015:46c05c2e34f7
comparison
equal deleted inserted replaced
12994:5625da6ae6b6 12995:e385f3a06673
624 for _, permission in ipairs(permissions) do 624 for _, permission in ipairs(permissions) do
625 self:default_permission(role_name, permission); 625 self:default_permission(role_name, permission);
626 end 626 end
627 end 627 end
628 628
629 function api:may(action, context) 629 function api:could(action, context)
630 return self:may(action, context, true);
631 end
632
633 function api:may(action, context, peek)
630 if action:byte(1) == 58 then -- action begins with ':' 634 if action:byte(1) == 58 then -- action begins with ':'
631 action = self.name..action; -- prepend module name 635 action = self.name..action; -- prepend module name
632 end 636 end
633 if type(context) == "string" then -- check JID permissions 637 if type(context) == "string" then -- check JID permissions
634 local role; 638 local role;
637 role = hosts[host].authz.get_user_role(node); 641 role = hosts[host].authz.get_user_role(node);
638 else 642 else
639 role = hosts[self.host].authz.get_jid_role(context); 643 role = hosts[self.host].authz.get_jid_role(context);
640 end 644 end
641 if not role then 645 if not role then
642 self:log("debug", "Access denied: JID <%s> may not %s (no role found)", context, action); 646 if not peek then
647 self:log("debug", "Access denied: JID <%s> may not %s (no role found)", context, action);
648 end
643 return false; 649 return false;
644 end 650 end
645 local permit = role:may(action); 651 local permit = role:may(action);
646 if not permit then 652 if not permit then
647 self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", context, action, role.name); 653 if not peek then
654 self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", context, action, role.name);
655 end
648 end 656 end
649 return permit; 657 return permit;
650 end 658 end
651 659
652 local session = context.origin or context.session; 660 local session = context.origin or context.session;
654 error("Unable to identify actor session from context"); 662 error("Unable to identify actor session from context");
655 end 663 end
656 if session.type == "c2s" and session.host == self.host then 664 if session.type == "c2s" and session.host == self.host then
657 local role = session.role; 665 local role = session.role;
658 if not role then 666 if not role then
659 self:log("warn", "Access denied: session %s has no role assigned"); 667 if not peek then
668 self:log("warn", "Access denied: session %s has no role assigned");
669 end
660 return false; 670 return false;
661 end 671 end
662 local permit = role:may(action, context); 672 local permit = role:may(action, context);
663 if not permit then 673 if not permit and not peek then
664 self:log("debug", "Access denied: session %s (%s) may not %s (not permitted by role %s)", 674 self:log("debug", "Access denied: session %s (%s) may not %s (not permitted by role %s)",
665 session.id, session.full_jid, action, role.name 675 session.id, session.full_jid, action, role.name
666 ); 676 );
667 end 677 end
668 return permit; 678 return permit;
669 else 679 else
670 local actor_jid = context.stanza.attr.from; 680 local actor_jid = context.stanza.attr.from;
671 local role = hosts[self.host].authz.get_jid_role(actor_jid); 681 local role = hosts[self.host].authz.get_jid_role(actor_jid);
672 if not role then 682 if not role then
673 self:log("debug", "Access denied: JID <%s> may not %s (no role found)", actor_jid, action); 683 if not peek then
684 self:log("debug", "Access denied: JID <%s> may not %s (no role found)", actor_jid, action);
685 end
674 return false; 686 return false;
675 end 687 end
676 local permit = role:may(action, context); 688 local permit = role:may(action, context);
677 if not permit then 689 if not permit and not peek then
678 self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", actor_jid, action, role.name); 690 self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", actor_jid, action, role.name);
679 end 691 end
680 return permit; 692 return permit;
681 end 693 end
682 end 694 end