core, plugins: Split prosody:user role into prosody:{guest,registered,member}
This gives us more granular control over different types of user account.
Accounts registered by IBR get assigned prosody:registered by default, while
accounts provisioned by an admin (e.g. via prosodyctl shell) will receive
prosody:member by default.
--- a/core/features.lua Thu Jun 29 15:31:46 2023 +0100
+++ b/core/features.lua Thu Jun 29 15:36:13 2023 +0100
@@ -12,5 +12,8 @@
"keyval+";
"s2sout-pre-connect-event";
+
+ -- prosody:guest, prosody:registered, prosody:member
+ "split-user-roles";
};
};
--- a/plugins/mod_admin_shell.lua Thu Jun 29 15:31:46 2023 +0100
+++ b/plugins/mod_admin_shell.lua Thu Jun 29 15:36:13 2023 +0100
@@ -282,8 +282,10 @@
elseif section == "roles" then
print [[Roles may grant access or restrict users from certain operations]]
print [[Built-in roles are:]]
- print [[ prosody:user - Normal user (default)]]
- print [[ prosody:admin - Host administrator]]
+ print [[ prosody:guest - Guest/anonymous user]]
+ print [[ prosody:registered - Registered user]]
+ print [[ prosody:member - Provisioned user]]
+ print [[ prosody:admin - Host administrator]]
print [[ prosody:operator - Server administrator]]
print [[]]
print [[Roles can be assigned using the user management commands (see 'help user').]]
@@ -1582,36 +1584,16 @@
return nil, "User exists";
end
- if role then
- local ok, err = um.create_user(username, nil, host);
- if not ok then
- return nil, "Could not create user: "..err;
- end
-
- local role_ok, rerr = um.set_user_role(jid, host, role);
- if not role_ok then
- return nil, "Could not set role: " .. tostring(rerr);
- end
-
- if password then
- local ok, err = um.set_password(username, password, host, nil);
- if not ok then
- return nil, "Could not set password for user: "..err;
- end
-
- local ok, err = um.enable_user(username, host);
- if not ok and err ~= "method not implemented" then
- return nil, "Could not enable user: "..err;
- end
- end
- else
- local ok, err = um.create_user(username, password, host);
- if not ok then
- return nil, "Could not create user: "..err;
- end
+ if not role then
+ role = module:get_option_string("default_provisioned_role", "prosody:member");
end
- return true, "User created";
+ local ok, err = um.create_user_with_role(username, password, host, role);
+ if not ok then
+ return nil, "Could not create user: "..err;
+ end
+
+ return true, ("Created %s with role '%s'"):format(jid, role);
end
function def_env.user:disable(jid)
--- a/plugins/mod_authz_internal.lua Thu Jun 29 15:31:46 2023 +0100
+++ b/plugins/mod_authz_internal.lua Thu Jun 29 15:36:13 2023 +0100
@@ -11,10 +11,13 @@
local host_suffix = host:gsub("^[^%.]+%.", "");
local hosts = prosody.hosts;
+local is_anon_host = module:get_option_string("authentication") == "anonymous";
+local default_user_role = module:get_option_string("default_user_role", is_anon_host and "prosody:guest" or "prosody:registered");
+
local is_component = hosts[host].type == "component";
local host_user_role, server_user_role, public_user_role;
if is_component then
- host_user_role = module:get_option_string("host_user_role", "prosody:user");
+ host_user_role = module:get_option_string("host_user_role", "prosody:registered");
server_user_role = module:get_option_string("server_user_role");
public_user_role = module:get_option_string("public_user_role");
end
@@ -48,23 +51,36 @@
end
-- Default roles
+
+-- For untrusted guest/anonymous users
register_role {
- name = "prosody:restricted";
+ name = "prosody:guest";
priority = 15;
};
+-- For e.g. self-registered accounts
register_role {
- name = "prosody:user";
+ name = "prosody:registered";
priority = 25;
- inherits = { "prosody:restricted" };
+ inherits = { "prosody:guest" };
};
+
+-- For trusted/provisioned accounts
+register_role {
+ name = "prosody:member";
+ priority = 35;
+ inherits = { "prosody:registered" };
+};
+
+-- For administrators, e.g. of a host
register_role {
name = "prosody:admin";
priority = 50;
- inherits = { "prosody:user" };
+ inherits = { "prosody:member" };
};
+-- For server operators (full access)
register_role {
name = "prosody:operator";
priority = 75;
@@ -128,11 +144,11 @@
return nil, err;
end
-- No role set, use default role
- return role_registry["prosody:user"];
+ return role_registry[default_user_role];
end
if stored_roles._default == nil then
-- No primary role explicitly set, return default
- return role_registry["prosody:user"];
+ return role_registry[default_user_role];
end
local primary_stored_role = role_registry[stored_roles._default];
if not primary_stored_role then
@@ -152,7 +168,7 @@
-- Primary role cannot be secondary role
[role_name] = role_map_store.remove;
};
- if role_name == "prosody:user" then
+ if role_name == default_user_role then
-- Don't store default
keys_update._default = role_map_store.remove;
end
--- a/plugins/mod_invites_adhoc.lua Thu Jun 29 15:31:46 2023 +0100
+++ b/plugins/mod_invites_adhoc.lua Thu Jun 29 15:36:13 2023 +0100
@@ -12,7 +12,7 @@
-- on the server, use the option above instead.
local allow_contact_invites = module:get_option_boolean("allow_contact_invites", true);
-module:default_permission(allow_user_invites and "prosody:user" or "prosody:admin", ":invite-users");
+module:default_permission(allow_user_invites and "prosody:registered" or "prosody:admin", ":invite-users");
local invites;
if prosody.shutdown then -- COMPAT hack to detect prosodyctl
--- a/plugins/mod_register_ibr.lua Thu Jun 29 15:31:46 2023 +0100
+++ b/plugins/mod_register_ibr.lua Thu Jun 29 15:36:13 2023 +0100
@@ -10,7 +10,7 @@
local st = require "prosody.util.stanza";
local dataform_new = require "prosody.util.dataforms".new;
local usermanager_user_exists = require "prosody.core.usermanager".user_exists;
-local usermanager_create_user = require "prosody.core.usermanager".create_user;
+local usermanager_create_user_with_role = require "prosody.core.usermanager".create_user_with_role;
local usermanager_set_password = require "prosody.core.usermanager".create_user;
local usermanager_delete_user = require "prosody.core.usermanager".delete_user;
local nodeprep = require "prosody.util.encodings".stringprep.nodeprep;
@@ -20,6 +20,8 @@
local require_encryption = module:get_option_boolean("c2s_require_encryption",
module:get_option_boolean("require_encryption", true));
+local default_role = module:get_option_string("register_ibr_default_role", "prosody:registered");
+
pcall(function ()
module:depends("register_limits");
end);
@@ -166,7 +168,12 @@
return true;
end
- local user = { username = username, password = password, host = host, additional = data, ip = session.ip, session = session, allowed = true }
+ local user = {
+ username = username, password = password, host = host;
+ additional = data, ip = session.ip, session = session;
+ role = default_role;
+ allowed = true;
+ };
module:fire_event("user-registering", user);
if not user.allowed then
local error_type, error_condition, reason;
@@ -200,7 +207,7 @@
end
end
- local created, err = usermanager_create_user(username, password, host);
+ local created, err = usermanager_create_user_with_role(username, password, host, user.role);
if created then
data.registered = os.time();
if not account_details:set(username, data) then
--- a/plugins/muc/hidden.lib.lua Thu Jun 29 15:31:46 2023 +0100
+++ b/plugins/muc/hidden.lib.lua Thu Jun 29 15:36:13 2023 +0100
@@ -8,7 +8,7 @@
--
local restrict_public = not module:get_option_boolean("muc_room_allow_public", true);
-module:default_permission(restrict_public and "prosody:admin" or "prosody:user", ":create-public-room");
+module:default_permission(restrict_public and "prosody:admin" or "prosody:registered", ":create-public-room");
local function get_hidden(room)
return room._data.hidden;
--- a/plugins/muc/mod_muc.lua Thu Jun 29 15:31:46 2023 +0100
+++ b/plugins/muc/mod_muc.lua Thu Jun 29 15:36:13 2023 +0100
@@ -414,7 +414,7 @@
end
local restrict_room_creation = module:get_option("restrict_room_creation");
-module:default_permission(restrict_room_creation == true and "prosody:admin" or "prosody:user", ":create-room");
+module:default_permission(restrict_room_creation == true and "prosody:admin" or "prosody:registered", ":create-room");
module:hook("muc-room-pre-create", function(event)
local origin, stanza = event.origin, event.stanza;
if restrict_room_creation ~= false and not module:may(":create-room", event) then
--- a/plugins/muc/persistent.lib.lua Thu Jun 29 15:31:46 2023 +0100
+++ b/plugins/muc/persistent.lib.lua Thu Jun 29 15:36:13 2023 +0100
@@ -9,7 +9,7 @@
local restrict_persistent = not module:get_option_boolean("muc_room_allow_persistent", true);
module:default_permission(
- restrict_persistent and "prosody:admin" or "prosody:user",
+ restrict_persistent and "prosody:admin" or "prosody:registered",
":create-persistent-room"
);