Software / code / prosody
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 |