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 | 6ebda1e5b4f3 |
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) |
