1 local array = require "util.array"; |
1 local array = require "util.array"; |
2 local it = require "util.iterators"; |
2 local it = require "util.iterators"; |
3 local set = require "util.set"; |
3 local set = require "util.set"; |
4 local jid_split, jid_bare = require "util.jid".split, require "util.jid".bare; |
4 local jid_split, jid_bare = require "util.jid".split, require "util.jid".bare; |
5 local normalize = require "util.jid".prep; |
5 local normalize = require "util.jid".prep; |
|
6 local roles = require "util.roles"; |
|
7 |
6 local config_global_admin_jids = module:context("*"):get_option_set("admins", {}) / normalize; |
8 local config_global_admin_jids = module:context("*"):get_option_set("admins", {}) / normalize; |
7 local config_admin_jids = module:get_option_inherited_set("admins", {}) / normalize; |
9 local config_admin_jids = module:get_option_inherited_set("admins", {}) / normalize; |
8 local host = module.host; |
10 local host = module.host; |
9 local role_store = module:open_store("roles"); |
11 local role_store = module:open_store("roles"); |
10 local role_map_store = module:open_store("roles", "map"); |
12 local role_map_store = module:open_store("roles", "map"); |
11 |
13 |
12 local role_methods = {}; |
14 local role_registry = {}; |
13 local role_mt = { __index = role_methods }; |
15 |
14 |
16 function register_role(role) |
15 local role_registry = { |
17 if role_registry[role.name] ~= nil then |
16 ["prosody:operator"] = { |
18 return error("A role '"..role.name.."' is already registered"); |
17 default = true; |
19 end |
18 priority = 75; |
20 if not roles.is_role(role) then |
19 includes = { "prosody:admin" }; |
21 -- Convert table syntax to real role object |
20 }; |
22 for i, inherited_role in ipairs(role.inherits or {}) do |
21 ["prosody:admin"] = { |
23 if type(inherited_role) == "string" then |
22 default = true; |
24 role.inherits[i] = assert(role_registry[inherited_role], "The named role '"..inherited_role.."' is not registered"); |
23 priority = 50; |
25 end |
24 includes = { "prosody:user" }; |
26 end |
25 }; |
27 if not role.permissions then role.permissions = {}; end |
26 ["prosody:user"] = { |
28 for _, allow_permission in ipairs(role.allow or {}) do |
27 default = true; |
29 role.permissions[allow_permission] = true; |
28 priority = 25; |
30 end |
29 includes = { "prosody:restricted" }; |
31 for _, deny_permission in ipairs(role.deny or {}) do |
30 }; |
32 role.permissions[deny_permission] = false; |
31 ["prosody:restricted"] = { |
33 end |
32 default = true; |
34 role = roles.new(role); |
33 priority = 15; |
35 end |
34 }; |
36 role_registry[role.name] = role; |
35 }; |
37 end |
36 |
38 |
37 -- Some processing on the role registry |
39 -- Default roles |
38 for role_name, role_info in pairs(role_registry) do |
40 register_role { |
39 role_info.name = role_name; |
41 name = "prosody:restricted"; |
40 role_info.includes = set.new(role_info.includes) / function (included_role_name) |
42 priority = 15; |
41 return role_registry[included_role_name]; |
43 }; |
42 end; |
44 |
43 if not role_info.permissions then |
45 register_role { |
44 role_info.permissions = {}; |
46 name = "prosody:user"; |
45 end |
47 priority = 25; |
46 setmetatable(role_info, role_mt); |
48 inherits = { "prosody:restricted" }; |
47 end |
49 }; |
48 |
50 |
49 function role_methods:may(action, context) |
51 register_role { |
50 local policy = self.permissions[action]; |
52 name = "prosody:admin"; |
51 if policy ~= nil then |
53 priority = 50; |
52 return policy; |
54 inherits = { "prosody:user" }; |
53 end |
55 }; |
54 for inherited_role in self.includes do |
56 |
55 module:log("debug", "Checking included role '%s' for %s", inherited_role.name, action); |
57 register_role { |
56 policy = inherited_role:may(action, context); |
58 name = "prosody:operator"; |
57 if policy ~= nil then |
59 priority = 75; |
58 return policy; |
60 inherits = { "prosody:admin" }; |
59 end |
61 }; |
60 end |
62 |
61 return false; |
63 |
|
64 -- Process custom roles from config |
|
65 |
|
66 local custom_roles = module:get_option("custom_roles", {}); |
|
67 for n, role_config in ipairs(custom_roles) do |
|
68 local ok, err = pcall(register_role, role_config); |
|
69 if not ok then |
|
70 module:log("error", "Error registering custom role %s: %s", role_config.name or tostring(n), err); |
|
71 end |
|
72 end |
|
73 |
|
74 -- Process custom permissions from config |
|
75 |
|
76 local config_add_perms = module:get_option("add_permissions", {}); |
|
77 local config_remove_perms = module:get_option("remove_permissions", {}); |
|
78 |
|
79 for role_name, added_permissions in pairs(config_add_perms) do |
|
80 if not role_registry[role_name] then |
|
81 module:log("error", "Cannot add permissions to unknown role '%s'", role_name); |
|
82 else |
|
83 for _, permission in ipairs(added_permissions) do |
|
84 role_registry[role_name]:set_permission(permission, true, true); |
|
85 end |
|
86 end |
|
87 end |
|
88 |
|
89 for role_name, removed_permissions in pairs(config_remove_perms) do |
|
90 if not role_registry[role_name] then |
|
91 module:log("error", "Cannot remove permissions from unknown role '%s'", role_name); |
|
92 else |
|
93 for _, permission in ipairs(removed_permissions) do |
|
94 role_registry[role_name]:set_permission(permission, false, true); |
|
95 end |
|
96 end |
62 end |
97 end |
63 |
98 |
64 -- Public API |
99 -- Public API |
65 |
100 |
66 local config_operator_role_set = { |
101 local config_operator_role_set = { |
67 ["prosody:operator"] = role_registry["prosody:operator"]; |
102 ["prosody:operator"] = role_registry["prosody:operator"]; |
68 }; |
103 }; |
69 local config_admin_role_set = { |
104 local config_admin_role_set = { |
70 ["prosody:admin"] = role_registry["prosody:admin"]; |
105 ["prosody:admin"] = role_registry["prosody:admin"]; |
|
106 }; |
|
107 local default_role_set = { |
|
108 ["prosody:user"] = role_registry["prosody:user"]; |
71 }; |
109 }; |
72 |
110 |
73 function get_user_roles(user) |
111 function get_user_roles(user) |
74 local bare_jid = user.."@"..host; |
112 local bare_jid = user.."@"..host; |
75 if config_global_admin_jids:contains(bare_jid) then |
113 if config_global_admin_jids:contains(bare_jid) then |
76 return config_operator_role_set; |
114 return config_operator_role_set; |
77 elseif config_admin_jids:contains(bare_jid) then |
115 elseif config_admin_jids:contains(bare_jid) then |
78 return config_admin_role_set; |
116 return config_admin_role_set; |
79 end |
117 end |
80 local role_names = role_store:get(user); |
118 local role_names = role_store:get(user); |
81 if not role_names then return {}; end |
119 if not role_names then return default_role_set; end |
82 local roles = {}; |
120 local user_roles = {}; |
83 for role_name in pairs(role_names) do |
121 for role_name in pairs(role_names) do |
84 roles[role_name] = role_registry[role_name]; |
122 user_roles[role_name] = role_registry[role_name]; |
85 end |
123 end |
86 return roles; |
124 return user_roles; |
87 end |
125 end |
88 |
126 |
89 function set_user_roles(user, roles) |
127 function set_user_roles(user, user_roles) |
90 role_store:set(user, roles) |
128 role_store:set(user, user_roles) |
91 return true; |
129 return true; |
92 end |
130 end |
93 |
131 |
94 function get_user_default_role(user) |
132 function get_user_default_role(user) |
95 local roles = get_user_roles(user); |
133 local user_roles = get_user_roles(user); |
96 if not roles then return nil; end |
134 if not user_roles then return nil; end |
97 local default_role; |
135 local default_role; |
98 for role_name, role_info in pairs(roles) do --luacheck: ignore 213/role_name |
136 for role_name, role_info in pairs(user_roles) do --luacheck: ignore 213/role_name |
99 if role_info.default and (not default_role or role_info.priority > default_role.priority) then |
137 if role_info.default ~= false and (not default_role or role_info.priority > default_role.priority) then |
100 default_role = role_info; |
138 default_role = role_info; |
101 end |
139 end |
102 end |
140 end |
103 if not default_role then return nil; end |
141 if not default_role then return nil; end |
104 return default_role; |
142 return default_role; |