Mercurial > prosody-hg
comparison core/usermanager.lua @ 12658:7ca5645f46cd
usermanager: Remove concept of global authz provider
Rationale:
- Removes a bunch of code!
- We don't have many cases where an actor is not bound to one of our hosts
- A notable exception is the admin shell, but if we ever attempt to lock those
sessions down, there is a load of other work that also has to be done. And
it's not clear if we would need a global authz provider for that anyway.
- Removes an extra edge case from the necessary mental model for operators
- Sessions that aren't bound to a host generally are anonymous or have an
alternative auth model (such as by IP addres).
- With the encapsulation now provided by util.roles, ad-hoc "detached roles"
can still be created anyway by code that needs them.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 12 Aug 2022 16:21:57 +0100 |
| parents | 1ab845e80fe7 |
| children | c0eea4f6c739 |
comparison
equal
deleted
inserted
replaced
| 12657:1ab845e80fe7 | 12658:7ca5645f46cd |
|---|---|
| 7 -- | 7 -- |
| 8 | 8 |
| 9 local modulemanager = require "core.modulemanager"; | 9 local modulemanager = require "core.modulemanager"; |
| 10 local log = require "util.logger".init("usermanager"); | 10 local log = require "util.logger".init("usermanager"); |
| 11 local type = type; | 11 local type = type; |
| 12 local it = require "util.iterators"; | 12 local jid_split = require "util.jid".split; |
| 13 local jid_prep, jid_split = require "util.jid".prep, require "util.jid".split; | |
| 14 local config = require "core.configmanager"; | 13 local config = require "core.configmanager"; |
| 15 local sasl_new = require "util.sasl".new; | 14 local sasl_new = require "util.sasl".new; |
| 16 local storagemanager = require "core.storagemanager"; | 15 local storagemanager = require "core.storagemanager"; |
| 17 local set = require "util.set"; | |
| 18 | 16 |
| 19 local prosody = _G.prosody; | 17 local prosody = _G.prosody; |
| 20 local hosts = prosody.hosts; | 18 local hosts = prosody.hosts; |
| 21 | 19 |
| 22 local setmetatable = setmetatable; | 20 local setmetatable = setmetatable; |
| 32 return setmetatable({name = "null", get_sasl_handler = dummy_get_sasl_handler}, { | 30 return setmetatable({name = "null", get_sasl_handler = dummy_get_sasl_handler}, { |
| 33 __index = function(self, method) return dummy; end --luacheck: ignore 212 | 31 __index = function(self, method) return dummy; end --luacheck: ignore 212 |
| 34 }); | 32 }); |
| 35 end | 33 end |
| 36 | 34 |
| 37 local global_admins_config = config.get("*", "admins"); | 35 local fallback_authz_provider = { |
| 38 if type(global_admins_config) ~= "table" then | |
| 39 global_admins_config = nil; -- TODO: factor out moduleapi magic config handling and use it here | |
| 40 end | |
| 41 local global_admins = set.new(global_admins_config) / jid_prep; | |
| 42 | |
| 43 local admin_role = { ["prosody:admin"] = true }; | |
| 44 local global_authz_provider = { | |
| 45 get_user_roles = function (user) end; --luacheck: ignore 212/user | 36 get_user_roles = function (user) end; --luacheck: ignore 212/user |
| 46 get_jids_with_role = function (role) | 37 get_jids_with_role = function (role) end; --luacheck: ignore 212 |
| 47 if role ~= "prosody:admin" then return {}; end | |
| 48 return it.to_array(global_admins); | |
| 49 end; | |
| 50 set_user_roles = function (user, roles) end; -- luacheck: ignore 212 | 38 set_user_roles = function (user, roles) end; -- luacheck: ignore 212 |
| 51 set_jid_roles = function (jid, roles) end; -- luacheck: ignore 212 | 39 set_jid_roles = function (jid, roles) end; -- luacheck: ignore 212 |
| 52 | 40 |
| 53 get_user_default_role = function (user) end; -- luacheck: ignore 212 | 41 get_user_default_role = function (user) end; -- luacheck: ignore 212 |
| 54 get_users_with_role = function (role_name) end; -- luacheck: ignore 212 | 42 get_users_with_role = function (role_name) end; -- luacheck: ignore 212 |
| 64 local host_session = hosts[host]; | 52 local host_session = hosts[host]; |
| 65 | 53 |
| 66 local authz_provider_name = config.get(host, "authorization") or "internal"; | 54 local authz_provider_name = config.get(host, "authorization") or "internal"; |
| 67 | 55 |
| 68 local authz_mod = modulemanager.load(host, "authz_"..authz_provider_name); | 56 local authz_mod = modulemanager.load(host, "authz_"..authz_provider_name); |
| 69 host_session.authz = authz_mod or global_authz_provider; | 57 host_session.authz = authz_mod or fallback_authz_provider; |
| 70 | 58 |
| 71 if host_session.type ~= "local" then return; end | 59 if host_session.type ~= "local" then return; end |
| 72 | 60 |
| 73 host_session.events.add_handler("item-added/auth-provider", function (event) | 61 host_session.events.add_handler("item-added/auth-provider", function (event) |
| 74 local provider = event.item; | 62 local provider = event.item; |
| 153 -- Returns a map of { [role_name] = role, ... } that a user is allowed to assume | 141 -- Returns a map of { [role_name] = role, ... } that a user is allowed to assume |
| 154 local function get_user_roles(user, host) | 142 local function get_user_roles(user, host) |
| 155 if host and not hosts[host] then return false; end | 143 if host and not hosts[host] then return false; end |
| 156 if type(user) ~= "string" then return false; end | 144 if type(user) ~= "string" then return false; end |
| 157 | 145 |
| 158 host = host or "*"; | 146 return hosts[host].authz.get_user_roles(user); |
| 159 | |
| 160 local authz_provider = (host ~= "*" and hosts[host].authz) or global_authz_provider; | |
| 161 return authz_provider.get_user_roles(user); | |
| 162 end | 147 end |
| 163 | 148 |
| 164 local function get_user_default_role(user, host) | 149 local function get_user_default_role(user, host) |
| 165 if host and not hosts[host] then return false; end | 150 if host and not hosts[host] then return false; end |
| 166 if type(user) ~= "string" then return false; end | 151 if type(user) ~= "string" then return false; end |
| 167 | 152 |
| 168 host = host or "*"; | 153 return hosts[host].authz.get_user_default_role(user); |
| 169 | |
| 170 local authz_provider = (host ~= "*" and hosts[host].authz) or global_authz_provider; | |
| 171 return authz_provider.get_user_default_role(user); | |
| 172 end | 154 end |
| 173 | 155 |
| 174 -- Accepts a set of role names which the user is allowed to assume | 156 -- Accepts a set of role names which the user is allowed to assume |
| 175 local function set_user_roles(user, host, roles) | 157 local function set_user_roles(user, host, roles) |
| 176 if host and not hosts[host] then return false; end | 158 if host and not hosts[host] then return false; end |
| 177 if type(user) ~= "string" then return false; end | 159 if type(user) ~= "string" then return false; end |
| 178 | 160 |
| 179 host = host or "*"; | 161 local ok, err = hosts[host].authz.set_user_roles(user, roles); |
| 180 | |
| 181 local authz_provider = (host ~= "*" and hosts[host].authz) or global_authz_provider; | |
| 182 local ok, err = authz_provider.set_user_roles(user, roles); | |
| 183 if ok then | 162 if ok then |
| 184 prosody.events.fire_event("user-roles-changed", { | 163 prosody.events.fire_event("user-roles-changed", { |
| 185 username = user, host = host | 164 username = user, host = host |
| 186 }); | 165 }); |
| 187 end | 166 end |
| 188 return ok, err; | 167 return ok, err; |
| 189 end | 168 end |
| 190 | 169 |
| 191 local function get_jid_role(jid, host) | 170 local function get_jid_role(jid, host) |
| 192 host = host or "*"; | |
| 193 local authz_provider = (host ~= "*" and hosts[host].authz) or global_authz_provider; | |
| 194 local jid_node, jid_host = jid_split(jid); | 171 local jid_node, jid_host = jid_split(jid); |
| 195 if host == jid_host and jid_node then | 172 if host == jid_host and jid_node then |
| 196 return authz_provider.get_user_default_role(jid_node); | 173 return hosts[host].authz.get_user_default_role(jid_node); |
| 197 end | 174 end |
| 198 return authz_provider.get_jid_role(jid); | 175 return hosts[host].authz.get_jid_role(jid); |
| 199 end | 176 end |
| 200 | 177 |
| 201 local function set_jid_role(jid, host, role_name) | 178 local function set_jid_role(jid, host, role_name) |
| 202 host = host or "*"; | |
| 203 local authz_provider = (host ~= "*" and hosts[host].authz) or global_authz_provider; | |
| 204 local _, jid_host = jid_split(jid); | 179 local _, jid_host = jid_split(jid); |
| 205 if host == jid_host then | 180 if host == jid_host then |
| 206 return nil, "unexpected-local-jid"; | 181 return nil, "unexpected-local-jid"; |
| 207 end | 182 end |
| 208 return authz_provider.set_jid_role(jid, role_name) | 183 return hosts[host].authz.set_jid_role(jid, role_name) |
| 209 end | 184 end |
| 210 | 185 |
| 211 local function get_users_with_role(role, host) | 186 local function get_users_with_role(role, host) |
| 212 if not hosts[host] then return false; end | 187 if not hosts[host] then return false; end |
| 213 if type(role) ~= "string" then return false; end | 188 if type(role) ~= "string" then return false; end |
| 214 | |
| 215 return hosts[host].authz.get_users_with_role(role); | 189 return hosts[host].authz.get_users_with_role(role); |
| 216 end | 190 end |
| 217 | 191 |
| 218 local function get_jids_with_role(role, host) | 192 local function get_jids_with_role(role, host) |
| 219 if host and not hosts[host] then return false; end | 193 if host and not hosts[host] then return false; end |
| 220 if type(role) ~= "string" then return false; end | 194 if type(role) ~= "string" then return false; end |
| 221 | 195 return hosts[host].authz.get_jids_with_role(role); |
| 222 host = host or "*"; | |
| 223 | |
| 224 local authz_provider = (host ~= "*" and hosts[host].authz) or global_authz_provider; | |
| 225 return authz_provider.get_jids_with_role(role); | |
| 226 end | 196 end |
| 227 | 197 |
| 228 local function get_role_by_name(role_name, host) | 198 local function get_role_by_name(role_name, host) |
| 229 if host and not hosts[host] then return false; end | 199 if host and not hosts[host] then return false; end |
| 230 if type(role_name) ~= "string" then return false; end | 200 if type(role_name) ~= "string" then return false; end |
| 231 | 201 return hosts[host].authz.get_role_by_name(role_name); |
| 232 host = host or "*"; | |
| 233 | |
| 234 local authz_provider = (host ~= "*" and hosts[host].authz) or global_authz_provider; | |
| 235 return authz_provider.get_role_by_name(role_name); | |
| 236 end | 202 end |
| 237 | 203 |
| 238 return { | 204 return { |
| 239 new_null_provider = new_null_provider; | 205 new_null_provider = new_null_provider; |
| 240 initialize_host = initialize_host; | 206 initialize_host = initialize_host; |
