plugins/mod_authz_internal.lua
author Kim Alvefur <zash@zash.se>
Wed, 27 Mar 2024 19:33:11 +0100
changeset 13471 c2a476f4712a
parent 13236 e0ab20519ce5
permissions -rw-r--r--
util.startup: Fix exiting on pidfile trouble prosody.shutdown() relies on prosody.main_thread, which has not been set yet at this point. Doing a clean shutdown might actually be harmful in case it tears down things set up by the conflicting Prosody, such as the very pidfile we were looking at. Thanks again SigmaTel71 for noticing
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12929
diff changeset
     1
local array = require "prosody.util.array";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12929
diff changeset
     2
local it = require "prosody.util.iterators";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12929
diff changeset
     3
local set = require "prosody.util.set";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12929
diff changeset
     4
local jid_split, jid_bare, jid_host = import("prosody.util.jid", "split", "bare", "host");
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12929
diff changeset
     5
local normalize = require "prosody.util.jid".prep;
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12929
diff changeset
     6
local roles = require "prosody.util.roles";
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
     7
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
     8
local config_global_admin_jids = module:context("*"):get_option_set("admins", {}) / normalize;
11749
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
     9
local config_admin_jids = module:get_option_inherited_set("admins", {}) / normalize;
10663
8f95308c3c45 usermanager, mod_authz_*: Merge mod_authz_config and mod_authz_internal into the latter
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
local host = module.host;
12734
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
    11
local host_suffix = host:gsub("^[^%.]+%.", "");
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
    12
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
    13
local hosts = prosody.hosts;
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    14
local is_anon_host = module:get_option_string("authentication") == "anonymous";
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    15
local default_user_role = module:get_option_string("default_user_role", is_anon_host and "prosody:guest" or "prosody:registered");
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    16
12734
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
    17
local is_component = hosts[host].type == "component";
12744
f58c6ae5edc1 mod_authz_internal: Fix warning due to global use
Kim Alvefur <zash@zash.se>
parents: 12737
diff changeset
    18
local host_user_role, server_user_role, public_user_role;
12734
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
    19
if is_component then
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    20
	host_user_role = module:get_option_string("host_user_role", "prosody:registered");
12734
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
    21
	server_user_role = module:get_option_string("server_user_role");
12737
2167e1639aab mod_authz_internal: Allow specifying default role for public (remote) users
Matthew Wild <mwild1@gmail.com>
parents: 12734
diff changeset
    22
	public_user_role = module:get_option_string("public_user_role");
12734
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
    23
end
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
    24
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
    25
local role_store = module:open_store("account_roles");
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
    26
local role_map_store = module:open_store("account_roles", "map");
10663
8f95308c3c45 usermanager, mod_authz_*: Merge mod_authz_config and mod_authz_internal into the latter
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    28
local role_registry = {};
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
    29
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    30
function register_role(role)
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    31
	if role_registry[role.name] ~= nil then
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    32
		return error("A role '"..role.name.."' is already registered");
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    33
	end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    34
	if not roles.is_role(role) then
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    35
		-- Convert table syntax to real role object
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    36
		for i, inherited_role in ipairs(role.inherits or {}) do
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    37
			if type(inherited_role) == "string" then
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    38
				role.inherits[i] = assert(role_registry[inherited_role], "The named role '"..inherited_role.."' is not registered");
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    39
			end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    40
		end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    41
		if not role.permissions then role.permissions = {}; end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    42
		for _, allow_permission in ipairs(role.allow or {}) do
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    43
			role.permissions[allow_permission] = true;
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    44
		end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    45
		for _, deny_permission in ipairs(role.deny or {}) do
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    46
			role.permissions[deny_permission] = false;
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    47
		end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    48
		role = roles.new(role);
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    49
	end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    50
	role_registry[role.name] = role;
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    51
end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    52
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    53
-- Default roles
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    54
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    55
-- For untrusted guest/anonymous users
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    56
register_role {
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    57
	name = "prosody:guest";
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    58
	priority = 15;
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    59
};
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    60
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    61
-- For e.g. self-registered accounts
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    62
register_role {
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    63
	name = "prosody:registered";
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    64
	priority = 25;
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    65
	inherits = { "prosody:guest" };
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
    66
};
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
    67
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    68
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    69
-- For trusted/provisioned accounts
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    70
register_role {
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    71
	name = "prosody:member";
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    72
	priority = 35;
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    73
	inherits = { "prosody:registered" };
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    74
};
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    75
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    76
-- For administrators, e.g. of a host
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    77
register_role {
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    78
	name = "prosody:admin";
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    79
	priority = 50;
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    80
	inherits = { "prosody:member" };
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    81
};
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    82
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
    83
-- For server operators (full access)
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    84
register_role {
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    85
	name = "prosody:operator";
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    86
	priority = 75;
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    87
	inherits = { "prosody:admin" };
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    88
};
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    89
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    90
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    91
-- Process custom roles from config
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    92
13236
e0ab20519ce5 plugins: Use get_option_array for some list shaped options
Kim Alvefur <zash@zash.se>
parents: 13174
diff changeset
    93
local custom_roles = module:get_option_array("custom_roles", {});
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    94
for n, role_config in ipairs(custom_roles) do
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    95
	local ok, err = pcall(register_role, role_config);
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    96
	if not ok then
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
    97
		module:log("error", "Error registering custom role %s: %s", role_config.name or tostring(n), err);
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
    98
	end
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
    99
end
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   100
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   101
-- Process custom permissions from config
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   102
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   103
local config_add_perms = module:get_option("add_permissions", {});
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   104
local config_remove_perms = module:get_option("remove_permissions", {});
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   105
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   106
for role_name, added_permissions in pairs(config_add_perms) do
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   107
	if not role_registry[role_name] then
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   108
		module:log("error", "Cannot add permissions to unknown role '%s'", role_name);
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   109
	else
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   110
		for _, permission in ipairs(added_permissions) do
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   111
			role_registry[role_name]:set_permission(permission, true, true);
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   112
		end
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   113
	end
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   114
end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   115
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   116
for role_name, removed_permissions in pairs(config_remove_perms) do
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   117
	if not role_registry[role_name] then
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   118
		module:log("error", "Cannot remove permissions from unknown role '%s'", role_name);
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   119
	else
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   120
		for _, permission in ipairs(removed_permissions) do
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   121
			role_registry[role_name]:set_permission(permission, false, true);
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   122
		end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   123
	end
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   124
end
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   125
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   126
-- Public API
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   127
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   128
-- Get the primary role of a user
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   129
function get_user_role(user)
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   130
	local bare_jid = user.."@"..host;
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   131
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   132
	-- Check config first
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   133
	if config_global_admin_jids:contains(bare_jid) then
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   134
		return role_registry["prosody:operator"];
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   135
	elseif config_admin_jids:contains(bare_jid) then
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   136
		return role_registry["prosody:admin"];
10663
8f95308c3c45 usermanager, mod_authz_*: Merge mod_authz_config and mod_authz_internal into the latter
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   137
	end
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   138
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   139
	-- Check storage
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   140
	local stored_roles, err = role_store:get(user);
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   141
	if not stored_roles then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   142
		if err then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   143
			-- Unable to fetch role, fail
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   144
			return nil, err;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   145
		end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   146
		-- No role set, use default role
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
   147
		return role_registry[default_user_role];
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   148
	end
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   149
	if stored_roles._default == nil then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   150
		-- No primary role explicitly set, return default
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
   151
		return role_registry[default_user_role];
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   152
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   153
	local primary_stored_role = role_registry[stored_roles._default];
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   154
	if not primary_stored_role then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   155
		return nil, "unknown-role";
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   156
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   157
	return primary_stored_role;
10663
8f95308c3c45 usermanager, mod_authz_*: Merge mod_authz_config and mod_authz_internal into the latter
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   158
end
8f95308c3c45 usermanager, mod_authz_*: Merge mod_authz_config and mod_authz_internal into the latter
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   159
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   160
-- Set the primary role of a user
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   161
function set_user_role(user, role_name)
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   162
	local role = role_registry[role_name];
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   163
	if not role then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   164
		return error("Cannot assign default user an unknown role: "..tostring(role_name));
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   165
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   166
	local keys_update = {
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   167
		_default = role_name;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   168
		-- Primary role cannot be secondary role
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   169
		[role_name] = role_map_store.remove;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   170
	};
13174
082c7d856e61 core, plugins: Split prosody:user role into prosody:{guest,registered,member}
Matthew Wild <mwild1@gmail.com>
parents: 12981
diff changeset
   171
	if role_name == default_user_role then
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   172
		-- Don't store default
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   173
		keys_update._default = role_map_store.remove;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   174
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   175
	local ok, err = role_map_store:set_keys(user, keys_update);
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   176
	if not ok then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   177
		return nil, err;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   178
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   179
	return role;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   180
end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   181
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   182
function add_user_secondary_role(user, role_name)
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   183
	if not role_registry[role_name] then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   184
		return error("Cannot assign default user an unknown role: "..tostring(role_name));
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   185
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   186
	role_map_store:set(user, role_name, true);
11476
c32753ceb0f0 mod_authz_internal: add support for setting roles of a local user
Jonas Schäfer <jonas@wielicki.name>
parents: 10663
diff changeset
   187
end
c32753ceb0f0 mod_authz_internal: add support for setting roles of a local user
Jonas Schäfer <jonas@wielicki.name>
parents: 10663
diff changeset
   188
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   189
function remove_user_secondary_role(user, role_name)
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   190
	role_map_store:set(user, role_name, nil);
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   191
end
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   192
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   193
function get_user_secondary_roles(user)
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   194
	local stored_roles, err = role_store:get(user);
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   195
	if not stored_roles then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   196
		if err then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   197
			-- Unable to fetch role, fail
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   198
			return nil, err;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   199
		end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   200
		-- No role set
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   201
		return {};
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   202
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   203
	stored_roles._default = nil;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   204
	for role_name in pairs(stored_roles) do
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   205
		stored_roles[role_name] = role_registry[role_name];
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   206
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   207
	return stored_roles;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   208
end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   209
12667
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   210
function user_can_assume_role(user, role_name)
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   211
	local primary_role = get_user_role(user);
12929
6cb339423928 mod_authz_internal: Fix wrong role name field in user_can_assume_role()
Kim Alvefur <zash@zash.se>
parents: 12924
diff changeset
   212
	if primary_role and primary_role.name == role_name then
12667
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   213
		return true;
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   214
	end
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   215
	local secondary_roles = get_user_secondary_roles(user);
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   216
	if secondary_roles and secondary_roles[role_name] then
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   217
		return true;
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   218
	end
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   219
	return false;
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   220
end
cf88f6b03942 mod_authz_internal: Expose convenience method to test if user can assume role
Matthew Wild <mwild1@gmail.com>
parents: 12666
diff changeset
   221
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   222
-- This function is *expensive*
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   223
function get_users_with_role(role_name)
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   224
	local function role_filter(username, default_role) --luacheck: ignore 212/username
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   225
		return default_role == role_name;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   226
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   227
	local primary_role_users = set.new(it.to_array(it.filter(role_filter, pairs(role_map_store:get_all("_default") or {}))));
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   228
	local secondary_role_users = set.new(it.to_array(it.keys(role_map_store:get_all(role_name) or {})));
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   229
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   230
	local config_set;
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   231
	if role_name == "prosody:admin" then
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   232
		config_set = config_admin_jids;
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   233
	elseif role_name == "prosody:operator" then
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   234
		config_set = config_global_admin_jids;
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   235
	end
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   236
	if config_set then
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   237
		local config_admin_users = config_set / function (admin_jid)
11749
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   238
			local j_node, j_host = jid_split(admin_jid);
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   239
			if j_host == host then
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   240
				return j_node;
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   241
			end
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   242
		end;
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   243
		return it.to_array(config_admin_users + primary_role_users + secondary_role_users);
11749
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   244
	end
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   245
	return it.to_array(primary_role_users + secondary_role_users);
11749
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   246
end
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   247
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   248
function get_jid_role(jid)
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   249
	local bare_jid = jid_bare(jid);
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   250
	if config_global_admin_jids:contains(bare_jid) then
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   251
		return role_registry["prosody:operator"];
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   252
	elseif config_admin_jids:contains(bare_jid) then
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   253
		return role_registry["prosody:admin"];
12734
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
   254
	elseif is_component then
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
   255
		local user_host = jid_host(bare_jid);
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
   256
		if host_user_role and user_host == host_suffix then
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
   257
			return role_registry[host_user_role];
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
   258
		elseif server_user_role and hosts[user_host] then
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
   259
			return role_registry[server_user_role];
12737
2167e1639aab mod_authz_internal: Allow specifying default role for public (remote) users
Matthew Wild <mwild1@gmail.com>
parents: 12734
diff changeset
   260
		elseif public_user_role then
2167e1639aab mod_authz_internal: Allow specifying default role for public (remote) users
Matthew Wild <mwild1@gmail.com>
parents: 12734
diff changeset
   261
			return role_registry[public_user_role];
12734
427dd01f0864 mod_authz_internal: Allow configuring role of local-server/parent-host users
Matthew Wild <mwild1@gmail.com>
parents: 12667
diff changeset
   262
		end
10663
8f95308c3c45 usermanager, mod_authz_*: Merge mod_authz_config and mod_authz_internal into the latter
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   263
	end
8f95308c3c45 usermanager, mod_authz_*: Merge mod_authz_config and mod_authz_internal into the latter
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   264
	return nil;
8f95308c3c45 usermanager, mod_authz_*: Merge mod_authz_config and mod_authz_internal into the latter
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   265
end
8f95308c3c45 usermanager, mod_authz_*: Merge mod_authz_config and mod_authz_internal into the latter
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   266
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   267
function set_jid_role(jid, role_name) -- luacheck: ignore 212
11476
c32753ceb0f0 mod_authz_internal: add support for setting roles of a local user
Jonas Schäfer <jonas@wielicki.name>
parents: 10663
diff changeset
   268
	return false;
c32753ceb0f0 mod_authz_internal: add support for setting roles of a local user
Jonas Schäfer <jonas@wielicki.name>
parents: 10663
diff changeset
   269
end
11749
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   270
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   271
function get_jids_with_role(role_name)
11749
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   272
	-- Fetch role users from storage
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   273
	local storage_role_jids = array.map(get_users_with_role(role_name), function (username)
11749
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   274
		return username.."@"..host;
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   275
	end);
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   276
	if role_name == "prosody:admin" then
11749
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   277
		return it.to_array(config_admin_jids + set.new(storage_role_jids));
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   278
	elseif role_name == "prosody:operator" then
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   279
		return it.to_array(config_global_admin_jids + set.new(storage_role_jids));
11749
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   280
	end
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   281
	return storage_role_jids;
3a2d58a39872 usermanager, mod_authz_internal: Add methods to fetch users/JIDs of given role
Matthew Wild <mwild1@gmail.com>
parents: 11478
diff changeset
   282
end
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   283
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   284
function add_default_permission(role_name, action, policy)
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   285
	local role = role_registry[role_name];
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   286
	if not role then
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   287
		module:log("warn", "Attempt to add default permission for unknown role: %s", role_name);
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   288
		return nil, "no-such-role";
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   289
	end
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   290
	if policy == nil then policy = true; end
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   291
	module:log("debug", "Adding policy %s for permission %s on role %s", policy, action, role_name);
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   292
	return role:set_permission(action, policy);
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   293
end
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   294
12652
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   295
function get_role_by_name(role_name)
f299e570a0fe mod_authz_internal: Use util.roles, some API changes and config support
Matthew Wild <mwild1@gmail.com>
parents: 12646
diff changeset
   296
	return assert(role_registry[role_name], role_name);
12646
9061f9621330 Switch to a new role-based authorization framework, removing is_admin()
Matthew Wild <mwild1@gmail.com>
parents: 11749
diff changeset
   297
end
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   298
12924
cdb996637b08 authz: Add method for retrieving all roles
Kim Alvefur <zash@zash.se>
parents: 12744
diff changeset
   299
function get_all_roles()
cdb996637b08 authz: Add method for retrieving all roles
Kim Alvefur <zash@zash.se>
parents: 12744
diff changeset
   300
	return role_registry;
cdb996637b08 authz: Add method for retrieving all roles
Kim Alvefur <zash@zash.se>
parents: 12744
diff changeset
   301
end
cdb996637b08 authz: Add method for retrieving all roles
Kim Alvefur <zash@zash.se>
parents: 12744
diff changeset
   302
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   303
-- COMPAT: Migrate from 0.12 role storage
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   304
local function do_migration(migrate_host)
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   305
	local old_role_store = assert(module:context(migrate_host):open_store("roles"));
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   306
	local new_role_store = assert(module:context(migrate_host):open_store("account_roles"));
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   307
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   308
	local migrated, failed, skipped = 0, 0, 0;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   309
	-- Iterate all users
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   310
	for username in assert(old_role_store:users()) do
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   311
		local old_roles = it.to_array(it.filter(function (k) return k:sub(1,1) ~= "_"; end, it.keys(old_role_store:get(username))));
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   312
		if #old_roles == 1 then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   313
			local ok, err = new_role_store:set(username, {
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   314
				_default = old_roles[1];
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   315
			});
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   316
			if ok then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   317
				migrated = migrated + 1;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   318
			else
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   319
				failed = failed + 1;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   320
				print("EE: Failed to store new role info for '"..username.."': "..err);
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   321
			end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   322
		else
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   323
			print("WW: User '"..username.."' has multiple roles and cannot be automatically migrated");
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   324
			skipped = skipped + 1;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   325
		end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   326
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   327
	return migrated, failed, skipped;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   328
end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   329
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   330
function module.command(arg)
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   331
	if arg[1] == "migrate" then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   332
		table.remove(arg, 1);
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   333
		local migrate_host = arg[1];
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   334
		if not migrate_host or not prosody.hosts[migrate_host] then
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   335
			print("EE: Please supply a valid host to migrate to the new role storage");
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   336
			return 1;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   337
		end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   338
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   339
		-- Initialize storage layer
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12929
diff changeset
   340
		require "prosody.core.storagemanager".initialize_host(migrate_host);
12666
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   341
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   342
		print("II: Migrating roles...");
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   343
		local migrated, failed, skipped = do_migration(migrate_host);
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   344
		print(("II: %d migrated, %d failed, %d skipped"):format(migrated, failed, skipped));
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   345
		return (failed + skipped == 0) and 0 or 1;
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   346
	else
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   347
		print("EE: Unknown command: "..(arg[1] or "<none given>"));
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   348
		print("    Hint: try 'migrate'?");
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   349
	end
07424992d7fc mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents: 12652
diff changeset
   350
end