From f7323ed6e45a8354a88928cbf91c73c7078cd2d0 Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Thu, 29 Jun 2023 15:36:13 +0100 Subject: 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. --- core/features.lua | 3 +++ plugins/mod_admin_shell.lua | 40 +++++++++++----------------------------- plugins/mod_authz_internal.lua | 32 ++++++++++++++++++++++++-------- plugins/mod_invites_adhoc.lua | 2 +- plugins/mod_register_ibr.lua | 13 ++++++++++--- plugins/muc/hidden.lib.lua | 2 +- plugins/muc/mod_muc.lua | 2 +- plugins/muc/persistent.lib.lua | 2 +- 8 files changed, 52 insertions(+), 44 deletions(-) diff --git a/core/features.lua b/core/features.lua index 8fbfbe9c..c96f0c81 100644 --- a/core/features.lua +++ b/core/features.lua @@ -12,5 +12,8 @@ return { "keyval+"; "s2sout-pre-connect-event"; + + -- prosody:guest, prosody:registered, prosody:member + "split-user-roles"; }; }; diff --git a/plugins/mod_admin_shell.lua b/plugins/mod_admin_shell.lua index b127fc02..bc073f52 100644 --- a/plugins/mod_admin_shell.lua +++ b/plugins/mod_admin_shell.lua @@ -282,8 +282,10 @@ function commands.help(session, data) 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 @@ function def_env.user:create(jid, password, role) 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 + if not role then + role = module:get_option_string("default_provisioned_role", "prosody:member"); + 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 + 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, "User created"; + return true, ("Created %s with role '%s'"):format(jid, role); end function def_env.user:disable(jid) diff --git a/plugins/mod_authz_internal.lua b/plugins/mod_authz_internal.lua index 9c0833bc..8710b7fe 100644 --- a/plugins/mod_authz_internal.lua +++ b/plugins/mod_authz_internal.lua @@ -11,10 +11,13 @@ local host = module.host; 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 @@ function register_role(role) 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 @@ function get_user_role(user) 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 @@ function set_user_role(user, role_name) -- 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 diff --git a/plugins/mod_invites_adhoc.lua b/plugins/mod_invites_adhoc.lua index 5518743d..02e6a7dd 100644 --- a/plugins/mod_invites_adhoc.lua +++ b/plugins/mod_invites_adhoc.lua @@ -12,7 +12,7 @@ local allow_user_invites = module:get_option_boolean("allow_user_invites", false -- 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 diff --git a/plugins/mod_register_ibr.lua b/plugins/mod_register_ibr.lua index 1f3f2818..cf6d51fb 100644 --- a/plugins/mod_register_ibr.lua +++ b/plugins/mod_register_ibr.lua @@ -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 additional_fields = module:get_option("additional_registration_fields", {} 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 @@ module:hook("stanza/iq/jabber:iq:register:query", function(event) 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 @@ module:hook("stanza/iq/jabber:iq:register:query", function(event) 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 diff --git a/plugins/muc/hidden.lib.lua b/plugins/muc/hidden.lib.lua index 087fa102..d24fa47e 100644 --- a/plugins/muc/hidden.lib.lua +++ b/plugins/muc/hidden.lib.lua @@ -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; diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 0d216588..f26934be 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -414,7 +414,7 @@ if module:get_option_boolean("muc_tombstones", true) then 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 diff --git a/plugins/muc/persistent.lib.lua b/plugins/muc/persistent.lib.lua index 4c753921..29ed7784 100644 --- a/plugins/muc/persistent.lib.lua +++ b/plugins/muc/persistent.lib.lua @@ -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" ); -- cgit v1.2.3