Annotate

mod_compat_roles/mod_compat_roles.lua @ 4983:7c77058a1ac5

mod_compat_roles: New module providing compat shim for trunk's new role API The new role API is translated to is_admin() calls on older versions. On newer versions (which have the role API) this module does nothing. It allows modules to drop their use of is_admin() (which is not available in trunk) and switch to the new role API, while remaining compatible with previous Prosody versions.
author Matthew Wild <mwild1@gmail.com>
date Thu, 11 Aug 2022 17:49:33 +0100
child 5097:d414fa8b37dc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4983
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 -- Export a module:may() that works on Prosody 0.12 and earlier
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 -- (i.e. backed by is_admin).
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 -- This API is safe because Prosody 0.12 and earlier do not support
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 -- per-session roles - all authorization is based on JID alone. It is not
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 -- safe on versions that support per-session authorization.
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 module:set_global();
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 local moduleapi = require "core.moduleapi";
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 -- If module.may already exists, abort
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 if moduleapi.may then return; end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 local jid_split = require "util.jid".split;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 local um_is_admin = require "core.usermanager".is_admin;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 local function get_jid_role_name(jid, host)
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 if um_is_admin(jid, "*") then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 return "prosody:operator";
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 elseif um_is_admin(jid, host) then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 return "prosody:admin";
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 return nil;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 local function get_user_role_name(username, host)
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 return get_jid_role_name(username.."@"..host, host);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 -- permissions[host][permission_name] = permitted_role_name
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 local permissions = {};
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 local function role_may(role_name, permission)
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 local role_permissions = permissions[role_name];
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 if not role_permissions then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 return false;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 return not not permissions[role_name][permission];
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 function moduleapi.may(self, action, context)
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 if action:byte(1) == 58 then -- action begins with ':'
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 action = self.name..action; -- prepend module name
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 if type(context) == "string" then -- check JID permissions
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 local role;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 local node, host = jid_split(context);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 if host == self.host then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 role = get_user_role_name(node, self.host);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 else
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 role = get_jid_role_name(context, self.host);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 if not role then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 self:log("debug", "Access denied: JID <%s> may not %s (no role found)", context, action);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 return false;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 local permit = role_may(role, action);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 if not permit then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", context, action, role.name);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 return permit;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 local session = context.origin or context.session;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 if type(session) ~= "table" then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 error("Unable to identify actor session from context");
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 if session.type == "s2sin" or (session.type == "c2s" and session.host ~= self.host) then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 local actor_jid = context.stanza.attr.from;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 local role_name = get_jid_role_name(actor_jid);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 if not role_name then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 self:log("debug", "Access denied: JID <%s> may not %s (no role found)", actor_jid, action);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 return false;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 local permit = role_may(role_name, action, context);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 if not permit then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 self:log("debug", "Access denied: JID <%s> may not %s (not permitted by role %s)", actor_jid, action, role_name);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 return permit;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 function moduleapi.default_permission(self, role_name, permission)
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 local r = permissions[self.host][role_name];
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 if not r then
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 r = {};
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 permissions[self.host][role_name] = r;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 r[permission] = true;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 function moduleapi.default_permissions(self, role_name, permission_list)
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 for _, permission in ipairs(permission_list) do
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 self:default_permission(role_name, permission);
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 function module.add_host(host_module)
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 permissions[host_module.host] = {};
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 function host_module.unload()
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 permissions[host_module.host] = nil;
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 end