util/roles.lua
author Kim Alvefur <zash@zash.se>
Tue, 14 May 2024 17:07:47 +0200
changeset 13494 6f840763fc73
parent 12991 2cf8d98d8a28
permissions -rw-r--r--
net.server_epoll: Add support for systemd socket activation Allows creating listening sockets and accepting client connections before Prosody starts. This is unlike normal Prosody dynamic resource management, where ports may added and removed at any time, and the ports defined by the config. Weird things happen if these are closed (e.g. due to reload) so here we prevent closing and ensure sockets are reused when opened again.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12979
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12752
diff changeset
     1
local array = require "prosody.util.array";
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12752
diff changeset
     2
local it = require "prosody.util.iterators";
d10957394a3c util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12752
diff changeset
     3
local new_short_id = require "prosody.util.id".short;
12651
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
local role_methods = {};
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
local role_mt = {
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
	__index = role_methods;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
	__name = "role";
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
	__add = nil;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
};
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
local function is_role(o)
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    13
	local mt = getmetatable(o);
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    14
	return mt == role_mt;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
local function _new_may(permissions, inherited_mays)
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
	local n_inherited = inherited_mays and #inherited_mays;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
	return function (role, action, context)
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
		-- Note: 'role' may be a descendent role, not only the one we're attached to
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
		local policy = permissions[action];
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
		if policy ~= nil then
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
			return policy;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
		end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
		if n_inherited then
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
			for i = 1, n_inherited do
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
				policy = inherited_mays[i](role, action, context);
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
				if policy ~= nil then
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
					return policy;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
				end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
			end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
		end
12750
7eabf8d78978 util.roles: Return nil if the role has no explicit policy (fixes inheritance)
Matthew Wild <mwild1@gmail.com>
parents: 12651
diff changeset
    33
		return nil;
12651
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
	end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
local permissions_key = {};
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
-- {
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
-- Required:
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
--   name = "My fancy role";
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
--
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
-- Optional:
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
--   inherits = { role_obj... }
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
--   default = true
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
--   priority = 100
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
--   permissions = {
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
--     ["foo"] = true; -- allow
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
--     ["bar"] = false; -- deny
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
--   }
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
-- }
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
local function new(base_config, overrides)
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
	local config = setmetatable(overrides or {}, { __index = base_config });
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
	local permissions = {};
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
	local inherited_mays;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    56
	if config.inherits then
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    57
		inherited_mays = array.pluck(config.inherits, "may");
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    58
	end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    59
	local new_role = {
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    60
		id = new_short_id();
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    61
		name = config.name;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    62
		description = config.description;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    63
		default = config.default;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    64
		priority = config.priority;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    65
		may = _new_may(permissions, inherited_mays);
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    66
		inherits = config.inherits;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    67
		[permissions_key] = permissions;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    68
	};
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    69
	local desired_permissions = config.permissions or config[permissions_key];
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
	for k, v in pairs(desired_permissions or {}) do
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
		permissions[k] = v;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
	end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
	return setmetatable(new_role, role_mt);
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
12991
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    76
function role_mt:__freeze()
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    77
	local t = {
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    78
		id = self.id;
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    79
		name = self.name;
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    80
		description = self.description;
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    81
		default = self.default;
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    82
		priority = self.priority;
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    83
		inherits = self.inherits;
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    84
		permissions = self[permissions_key];
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    85
	};
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    86
	return t;
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    87
end
2cf8d98d8a28 util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents: 12979
diff changeset
    88
12651
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    89
function role_methods:clone(overrides)
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    90
	return new(self, overrides);
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    91
end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    92
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    93
function role_methods:set_permission(permission_name, policy, overwrite)
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    94
	local permissions = self[permissions_key];
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    95
	if overwrite ~= true and permissions[permission_name] ~= nil and permissions[permission_name] ~= policy then
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    96
		return false, "policy-already-exists";
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    97
	end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    98
	permissions[permission_name] = policy;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    99
	return true;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   100
end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   101
12752
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   102
function role_methods:policies()
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   103
	local policy_iterator, s, v = it.join(pairs(self[permissions_key]));
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   104
	if self.inherits then
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   105
		for _, inherited_role in ipairs(self.inherits) do
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   106
			policy_iterator:append(inherited_role:policies());
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   107
		end
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   108
	end
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   109
	return policy_iterator, s, v;
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   110
end
7b9de8109a90 util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents: 12750
diff changeset
   111
12651
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   112
function role_mt.__tostring(self)
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   113
	return ("role<[%s] %s>"):format(self.id or "nil", self.name or "[no name]");
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   114
end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   115
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   116
function role_mt.__pairs(self)
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   117
	return it.filter(permissions_key, next, self);
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   118
end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   119
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   120
return {
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   121
	is_role = is_role;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   122
	new = new;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
   123
};