annotate mod_compat_roles/mod_compat_roles.lua @ 5300:fa97de0b0961

.luacheckrc: Add module.once
author Matthew Wild <mwild1@gmail.com>
date Sat, 01 Apr 2023 13:56:15 +0100
parents f03f4ec859a3
children 825c6fb76c48
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
5098
817bc9873fc2 mod_compat_roles: Fix permission checks/roles to be per-host as intended
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
31 -- permissions[host][role_name][permission_name] = is_permitted
4983
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
5099
f03f4ec859a3 mod_compat_roles: Add support for role inheritance (built-in roles only)
Matthew Wild <mwild1@gmail.com>
parents: 5098
diff changeset
34 local role_inheritance = {
f03f4ec859a3 mod_compat_roles: Add support for role inheritance (built-in roles only)
Matthew Wild <mwild1@gmail.com>
parents: 5098
diff changeset
35 ["prosody:operator"] = "prosody:admin";
f03f4ec859a3 mod_compat_roles: Add support for role inheritance (built-in roles only)
Matthew Wild <mwild1@gmail.com>
parents: 5098
diff changeset
36 ["prosody:admin"] = "prosody:user";
f03f4ec859a3 mod_compat_roles: Add support for role inheritance (built-in roles only)
Matthew Wild <mwild1@gmail.com>
parents: 5098
diff changeset
37 ["prosody:user"] = "prosody:restricted";
f03f4ec859a3 mod_compat_roles: Add support for role inheritance (built-in roles only)
Matthew Wild <mwild1@gmail.com>
parents: 5098
diff changeset
38 };
f03f4ec859a3 mod_compat_roles: Add support for role inheritance (built-in roles only)
Matthew Wild <mwild1@gmail.com>
parents: 5098
diff changeset
39
5098
817bc9873fc2 mod_compat_roles: Fix permission checks/roles to be per-host as intended
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
40 local function role_may(host, role_name, permission)
817bc9873fc2 mod_compat_roles: Fix permission checks/roles to be per-host as intended
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
41 local host_roles = permissions[host];
817bc9873fc2 mod_compat_roles: Fix permission checks/roles to be per-host as intended
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
42 if not host_roles then
817bc9873fc2 mod_compat_roles: Fix permission checks/roles to be per-host as intended
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
43 return false;
817bc9873fc2 mod_compat_roles: Fix permission checks/roles to be per-host as intended
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
44 end
817bc9873fc2 mod_compat_roles: Fix permission checks/roles to be per-host as intended
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
45 local role_permissions = host_roles[role_name];
4983
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 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
47 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
48 end
5099
f03f4ec859a3 mod_compat_roles: Add support for role inheritance (built-in roles only)
Matthew Wild <mwild1@gmail.com>
parents: 5098
diff changeset
49 local next_role = role_inheritance[role_name];
f03f4ec859a3 mod_compat_roles: Add support for role inheritance (built-in roles only)
Matthew Wild <mwild1@gmail.com>
parents: 5098
diff changeset
50 return not not permissions[role_name][permission] or (next_role and role_may(host, next_role, permission));
4983
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 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
54 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
55 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
56 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 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
58 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
59 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
60 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
61 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
62 else
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 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
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 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
66 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
67 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
68 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69
5098
817bc9873fc2 mod_compat_roles: Fix permission checks/roles to be per-host as intended
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
70 local permit = role_may(self.host, role, action);
4983
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 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
72 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
73 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 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
75 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76
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 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
78 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
79 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
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 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
82 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
83 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
84 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
85 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
86 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
87 end
5098
817bc9873fc2 mod_compat_roles: Fix permission checks/roles to be per-host as intended
Matthew Wild <mwild1@gmail.com>
parents: 5097
diff changeset
88 local permit = role_may(self.host, role_name, action, context);
4983
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 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
90 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
91 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 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
93 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 function moduleapi.default_permission(self, role_name, permission)
5097
d414fa8b37dc mod_compat_roles: Fix traceback when no host roles are defined (thanks cc)
Matthew Wild <mwild1@gmail.com>
parents: 4983
diff changeset
97 local p = permissions[self.host];
d414fa8b37dc mod_compat_roles: Fix traceback when no host roles are defined (thanks cc)
Matthew Wild <mwild1@gmail.com>
parents: 4983
diff changeset
98 if not p then
d414fa8b37dc mod_compat_roles: Fix traceback when no host roles are defined (thanks cc)
Matthew Wild <mwild1@gmail.com>
parents: 4983
diff changeset
99 p = {};
d414fa8b37dc mod_compat_roles: Fix traceback when no host roles are defined (thanks cc)
Matthew Wild <mwild1@gmail.com>
parents: 4983
diff changeset
100 permissions[self.host] = p;
d414fa8b37dc mod_compat_roles: Fix traceback when no host roles are defined (thanks cc)
Matthew Wild <mwild1@gmail.com>
parents: 4983
diff changeset
101 end
d414fa8b37dc mod_compat_roles: Fix traceback when no host roles are defined (thanks cc)
Matthew Wild <mwild1@gmail.com>
parents: 4983
diff changeset
102 local r = p[role_name];
4983
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 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
104 r = {};
5097
d414fa8b37dc mod_compat_roles: Fix traceback when no host roles are defined (thanks cc)
Matthew Wild <mwild1@gmail.com>
parents: 4983
diff changeset
105 p[role_name] = r;
4983
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 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
108 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 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
111 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
112 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
113 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 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
117 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
118 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
119 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
120 end
7c77058a1ac5 mod_compat_roles: New module providing compat shim for trunk's new role API
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 end