Changeset

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
parents 12994:5625da6ae6b6
children 12996:e8716515405e
files core/moduleapi.lua
diffstat 1 files changed, 19 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/core/moduleapi.lua	Sat Mar 25 19:38:41 2023 +0000
+++ b/core/moduleapi.lua	Sun Mar 26 14:06:04 2023 +0100
@@ -626,7 +626,11 @@
 	end
 end
 
-function api:may(action, context)
+function api:could(action, context)
+	return self:may(action, context, true);
+end
+
+function api:may(action, context, peek)
 	if action:byte(1) == 58 then -- action begins with ':'
 		action = self.name..action; -- prepend module name
 	end
@@ -639,12 +643,16 @@
 			role = hosts[self.host].authz.get_jid_role(context);
 		end
 		if not role then
-			self:log("debug", "Access denied: JID <%s> may not %s (no role found)", context, action);
+			if not peek then
+				self:log("debug", "Access denied: JID <%s> may not %s (no role found)", context, action);
+			end
 			return false;
 		end
 		local permit = role:may(action);
 		if not permit then
-			self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", context, action, role.name);
+			if not peek then
+				self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", context, action, role.name);
+			end
 		end
 		return permit;
 	end
@@ -656,11 +664,13 @@
 	if session.type == "c2s" and session.host == self.host then
 		local role = session.role;
 		if not role then
-			self:log("warn", "Access denied: session %s has no role assigned");
+			if not peek then
+				self:log("warn", "Access denied: session %s has no role assigned");
+			end
 			return false;
 		end
 		local permit = role:may(action, context);
-		if not permit then
+		if not permit and not peek then
 			self:log("debug", "Access denied: session %s (%s) may not %s (not permitted by role %s)",
 				session.id, session.full_jid, action, role.name
 			);
@@ -670,11 +680,13 @@
 		local actor_jid = context.stanza.attr.from;
 		local role = hosts[self.host].authz.get_jid_role(actor_jid);
 		if not role then
-			self:log("debug", "Access denied: JID <%s> may not %s (no role found)", actor_jid, action);
+			if not peek then
+				self:log("debug", "Access denied: JID <%s> may not %s (no role found)", actor_jid, action);
+			end
 			return false;
 		end
 		local permit = role:may(action, context);
-		if not permit then
+		if not permit and not peek then
 			self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", actor_jid, action, role.name);
 		end
 		return permit;