Software / code / prosody
Annotate
util/roles.lua @ 13777:093ced3f8309
Merge 13.0->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Mon, 17 Mar 2025 15:23:50 +0100 |
| parent | 12987:2cf8d98d8a28 |
| rev | line source |
|---|---|
|
12975
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12748
diff
changeset
|
1 local array = require "prosody.util.array"; |
|
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12748
diff
changeset
|
2 local it = require "prosody.util.iterators"; |
|
d10957394a3c
util: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12748
diff
changeset
|
3 local new_short_id = require "prosody.util.id".short; |
|
12647
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 |
|
12746
7eabf8d78978
util.roles: Return nil if the role has no explicit policy (fixes inheritance)
Matthew Wild <mwild1@gmail.com>
parents:
12647
diff
changeset
|
33 return nil; |
|
12647
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 |
|
12987
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
76 function role_mt:__freeze() |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
77 local t = { |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
78 id = self.id; |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
79 name = self.name; |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
80 description = self.description; |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
81 default = self.default; |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
82 priority = self.priority; |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
83 inherits = self.inherits; |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
84 permissions = self[permissions_key]; |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
85 }; |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
86 return t; |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
87 end |
|
2cf8d98d8a28
util.roles: Implement a serialization preparation metamethod
Kim Alvefur <zash@zash.se>
parents:
12975
diff
changeset
|
88 |
|
12647
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 |
|
12748
7b9de8109a90
util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents:
12746
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:
12746
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:
12746
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:
12746
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:
12746
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:
12746
diff
changeset
|
107 end |
|
7b9de8109a90
util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents:
12746
diff
changeset
|
108 end |
|
7b9de8109a90
util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents:
12746
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:
12746
diff
changeset
|
110 end |
|
7b9de8109a90
util.roles: Add a :policies() method to iterate through available policies
Matthew Wild <mwild1@gmail.com>
parents:
12746
diff
changeset
|
111 |
|
12647
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 }; |