Mercurial > prosody-modules
comparison mod_authz_delegate/mod_authz_delegate.lua @ 5295:98d5acb93439
mod_authz_delegate: make resistant against startup order issues
There is no guarantee that the target_host gets activated and
initialized before the host this module is loaded on. As
add_default_permission is called during load time by many modules,
we need to be prepared to queue stuff.
author | Jonas Schäfer <jonas@wielicki.name> |
---|---|
date | Fri, 31 Mar 2023 16:56:42 +0200 |
parents | f61564b522f7 |
children |
comparison
equal
deleted
inserted
replaced
5294:385346b6c81d | 5295:98d5acb93439 |
---|---|
1 local target_host = assert(module:get_option("authz_delegate_to")); | 1 local target_host = assert(module:get_option("authz_delegate_to")); |
2 local this_host = module:get_host(); | 2 local this_host = module:get_host(); |
3 | 3 |
4 local array = require"util.array"; | |
4 local jid_split = import("prosody.util.jid", "split"); | 5 local jid_split = import("prosody.util.jid", "split"); |
5 | 6 |
6 local hosts = prosody.hosts; | 7 local hosts = prosody.hosts; |
7 | 8 |
8 function get_jids_with_role(role) --luacheck: ignore 212/role | 9 function get_jids_with_role(role) --luacheck: ignore 212/role |
51 function set_jid_role(jid) --luacheck: ignore 212/jid | 52 function set_jid_role(jid) --luacheck: ignore 212/jid |
52 -- TODO: figure out if there are actually legitimate uses for this... | 53 -- TODO: figure out if there are actually legitimate uses for this... |
53 return nil, "cannot set jid role on delegation target" | 54 return nil, "cannot set jid role on delegation target" |
54 end | 55 end |
55 | 56 |
57 local default_permission_queue = array{}; | |
58 | |
56 function add_default_permission(role_name, action, policy) | 59 function add_default_permission(role_name, action, policy) |
57 return hosts[target_host].authz.add_default_permission(role_name, action, policy) | 60 -- NOTE: we always record default permissions, because the delegated-to |
61 -- host may be re-activated. | |
62 default_permission_queue:push({ | |
63 role_name = role_name, | |
64 action = action, | |
65 policy = policy, | |
66 }); | |
67 local target_host_object = hosts[target_host]; | |
68 local authz = target_host_object and target_host_object.authz; | |
69 if not authz then | |
70 module:log("debug", "queueing add_default_permission call for later, %s is not active yet", target_host); | |
71 return; | |
72 end | |
73 return authz.add_default_permission(role_name, action, policy) | |
58 end | 74 end |
59 | 75 |
60 function get_role_by_name(role_name) | 76 function get_role_by_name(role_name) |
61 return hosts[target_host].authz.get_role_by_name(role_name) | 77 return hosts[target_host].authz.get_role_by_name(role_name) |
62 end | 78 end |
63 | 79 |
64 function get_all_roles() | 80 function get_all_roles() |
65 return hosts[target_host].authz.get_all_roles() | 81 return hosts[target_host].authz.get_all_roles() |
66 end | 82 end |
83 | |
84 module:hook_global("host-activated", function(host) | |
85 if host == target_host then | |
86 local authz = hosts[target_host].authz; | |
87 module:log("debug", "replaying %d queued permission changes", #default_permission_queue); | |
88 assert(authz); | |
89 -- replay default permission changes, if any | |
90 for i, item in ipairs(default_permission_queue) do | |
91 authz.add_default_permission(item.role_name, item.action, item.policy); | |
92 end | |
93 -- NOTE: we do not clear that array here -- in case the target_host is | |
94 -- re-activated | |
95 end | |
96 end, -10000) |