diff options
author | Matthew Wild <mwild1@gmail.com> | 2025-04-09 10:59:28 +0100 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2025-04-09 10:59:28 +0100 |
commit | 60c270f2a8f96c498c250410093bec630e2d4c30 (patch) | |
tree | b37d9b165304e0f68971c19a93b68fae98f6425d | |
parent | efdb9a8919d1e21761148e273041f3ee6b1463b7 (diff) | |
parent | 775a4d3cf6bf8c7675e1ded0f5edf7c35e622043 (diff) | |
download | prosody-60c270f2a8f96c498c250410093bec630e2d4c30.tar.gz prosody-60c270f2a8f96c498c250410093bec630e2d4c30.zip |
Merge 13.0->trunk
-rw-r--r-- | core/modulemanager.lua | 70 | ||||
-rw-r--r-- | plugins/mod_admin_shell.lua | 60 | ||||
-rw-r--r-- | plugins/mod_authz_internal.lua | 6 | ||||
-rw-r--r-- | util/pluginloader.lua | 9 | ||||
-rw-r--r-- | util/prosodyctl/check.lua | 19 |
5 files changed, 131 insertions, 33 deletions
diff --git a/core/modulemanager.lua b/core/modulemanager.lua index 7295ba25..4d144a86 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -54,50 +54,58 @@ local _G = _G; local _ENV = nil; -- luacheck: std none -local loader = pluginloader.init({ - load_filter_cb = function (path, content) - local metadata = {}; - for line in content:gmatch("([^\r\n]+)\r?\n") do - local key, value = line:match("^%-%-%% *([%w_]+): *(.+)$"); - if key then - value = value:gsub("%s+$", ""); - metadata[key] = value; - end +local function plugin_load_filter_cb(path, content) + local metadata = {}; + for line in content:gmatch("([^\r\n]+)\r?\n") do + local key, value = line:match("^%-%-%% *([%w_]+): *(.+)$"); + if key then + value = value:gsub("%s+$", ""); + metadata[key] = value; end + end - if metadata.lua then - local supported = false; - for supported_lua_version in metadata.lua:gmatch("[^, ]+") do - if supported_lua_version == lua_version then - supported = true; - break; - end + if metadata.lua then + local supported = false; + for supported_lua_version in metadata.lua:gmatch("[^, ]+") do + if supported_lua_version == lua_version then + supported = true; + break; end - if not supported then + end + if not supported then + if prosody.process_type ~= "prosodyctl" then log("warn", "Not loading module, we have Lua %s but the module requires one of (%s): %s", lua_version, metadata.lua, path); - return; -- Don't load this module end + return nil, "incompatible with Lua "..lua_version; -- Don't load this module end + end - if metadata.conflicts then - local conflicts_features = set.new(array.collect(metadata.conflicts:gmatch("[^, ]+"))); - local conflicted_features = set.intersection(conflicts_features, core_features); - if not conflicted_features:empty() then - log("warn", "Not loading module, due to conflicting features '%s': %s", conflicted_features, path); - return; -- Don't load this module + if metadata.conflicts then + local conflicts_features = set.new(array.collect(metadata.conflicts:gmatch("[^, ]+"))); + local conflicted_features = set.intersection(conflicts_features, core_features); + if not conflicted_features:empty() then + if prosody.process_type ~= "prosodyctl" then + log("warn", "Not loading module, due to conflict with built-in features '%s': %s", conflicted_features, path); end + return nil, "conflict with built-in feature"; -- Don't load this module end - if metadata.requires then - local required_features = set.new(array.collect(metadata.requires:gmatch("[^, ]+"))); - local missing_features = required_features - core_features; - if not missing_features:empty() then + end + if metadata.requires then + local required_features = set.new(array.collect(metadata.requires:gmatch("[^, ]+"))); + local missing_features = required_features - core_features; + if not missing_features:empty() then + if prosody.process_type ~= "prosodyctl" then log("warn", "Not loading module, due to missing features '%s': %s", missing_features, path); - return; -- Don't load this module end + return nil, "Prosody version missing required feature"; -- Don't load this module end + end - return path, content, metadata; - end; + return path, content, metadata; +end; + +local loader = pluginloader.init({ + load_filter_cb = plugin_load_filter_cb; }); local load_modules_for_host, load, unload, reload, get_module, get_items; diff --git a/plugins/mod_admin_shell.lua b/plugins/mod_admin_shell.lua index d6d082f3..de345484 100644 --- a/plugins/mod_admin_shell.lua +++ b/plugins/mod_admin_shell.lua @@ -139,6 +139,8 @@ Built-in roles are: prosody:admin - Host administrator prosody:operator - Server administrator +To view roles and policies, see the commands in 'help role'. + Roles can be assigned using the user management commands (see 'help user'). ]]; @@ -2458,6 +2460,64 @@ function def_env.debug:cert_index(path) return true, ("Showing %d certificates in %s"):format(c, path); end +def_env.role = new_section("Role and access management"); + +describe_command [[role:list(host) - List known roles]] +function def_env.role:list(host) + if not host then + return nil, "Specify which host to list roles for"; + end + local role_list = {}; + for _, role in it.sorted_pairs(um.get_all_roles(host)) do + table.insert(role_list, role); + end + table.sort(role_list, function (a, b) + if a.priority ~= b.priority then + return (a.priority or 0) > (b.priority or 0); + end + return a.name < b.name; + end); + for _, role in ipairs(role_list) do + self.session.print(role.name); + end + return true, ("Showing %d roles on %s"):format(#role_list, host); +end + +describe_command [[role:show(host, role_name) - Show information about a role]] +function def_env.role:show(host, role_name) + if not host or not role_name then + return nil, "Specify the host and role to show"; + end + + local print = self.session.print; + local role = um.get_role_by_name(role_name, host); + + if not role then + return nil, ("Unable to find role %s on host %s"):format(role_name, host); + end + + local inherits = {}; + for _, inherited_role in ipairs(role.inherits or {}) do + table.insert(inherits, inherited_role.name); + end + + local permissions = {}; + for permission, is_allowed in role:policies() do + permissions[permission] = is_allowed and "allowed" or "denied"; + end + + print("Name: ", role.name); + print("Inherits:", table.concat(inherits, ", ")); + print("Policies:"); + local c = 0; + for permission, policy in it.sorted_pairs(permissions) do + c = c + 1; + print(" ["..(policy == "allowed" and "+" or " ").."] " .. permission); + end + print(""); + return true, ("Showing role %s with %d policies"):format(role.name, c); +end + def_env.stats = new_section("Commands to show internal statistics"); local short_units = { diff --git a/plugins/mod_authz_internal.lua b/plugins/mod_authz_internal.lua index f683d90c..1282f617 100644 --- a/plugins/mod_authz_internal.lua +++ b/plugins/mod_authz_internal.lua @@ -298,7 +298,11 @@ function add_default_permission(role_name, action, policy) end function get_role_by_name(role_name) - return assert(role_registry[role_name], role_name); + local role = role_registry[role_name]; + if not role then + return error("Unknown role: "..role_name); + end + return role, role_name; end function get_all_roles() diff --git a/util/pluginloader.lua b/util/pluginloader.lua index 634bd6f8..4d05ea8d 100644 --- a/util/pluginloader.lua +++ b/util/pluginloader.lua @@ -25,6 +25,7 @@ local pluginloader_mt = { __index = pluginloader_methods }; function pluginloader_methods:load_file(names) local file, err, path; local load_filter_cb = self._options.load_filter_cb; + local last_filter_path, last_filter_err; for i=1,#plugin_dir do for j=1,#names do path = plugin_dir[i]..names[j]; @@ -36,12 +37,18 @@ function pluginloader_methods:load_file(names) if load_filter_cb then path, content, metadata = load_filter_cb(path, content); end - if content and path then + if path and content then return content, path, metadata; + else + last_filter_path = plugin_dir[i]..names[j]; + last_filter_err = content or "skipped"; end end end end + if last_filter_err then + return nil, err..(" (%s skipped because of %s)"):format(last_filter_path, last_filter_err); + end return file, err; end diff --git a/util/prosodyctl/check.lua b/util/prosodyctl/check.lua index 622e475e..c46755af 100644 --- a/util/prosodyctl/check.lua +++ b/util/prosodyctl/check.lua @@ -644,6 +644,25 @@ local function check(arg) print(" been deprecated. You can safely remove it."); end + local load_failures = {}; + for mod_name in all_modules do + local mod, err = modulemanager.loader:load_resource(mod_name, nil); + if not mod then + load_failures[mod_name] = err; + end + end + + if next(load_failures) ~= nil then + print(""); + print(" The following modules failed to load:"); + print(""); + for mod_name, err in it.sorted_pairs(load_failures) do + print((" mod_%s: %s"):format(mod_name, err)); + end + print("") + print(" Check for typos and remove any obsolete/incompatible modules from your config."); + end + for host, host_config in pairs(config) do --luacheck: ignore 213/host if type(rawget(host_config, "storage")) == "string" and rawget(host_config, "default_storage") then print(""); |