Annotate

util/roles.lua @ 12647:a661292d074a

util.roles: Add new utility module to consolidate role objects and methods
author Matthew Wild <mwild1@gmail.com>
date Tue, 19 Jul 2022 17:44:26 +0100
child 12746:7eabf8d78978
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12647
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local array = require "util.array";
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 local it = require "util.iterators";
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local new_short_id = require "util.id".short;
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
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 return false;
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
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 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
77 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
78 end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 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
81 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
82 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
83 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
84 end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 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
86 return true;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 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
90 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
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_mt.__pairs(self)
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 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
95 end
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 return {
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 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
99 new = new;
a661292d074a util.roles: Add new utility module to consolidate role objects and methods
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 };