Software /
code /
prosody
Annotate
util/roles.lua @ 13085:0e17cb78264f
util.jsonschema: Implement 'luaPattern' - Lua variant of 'pattern'
Like 'pattern' but uses Lua patterns instead of Regular Expressions,
since only a subset of regex are also valid Lua patterns.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 22 Apr 2023 12:48:51 +0200 |
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 }; |