author | Matthew Wild <mwild1@gmail.com> |
Thu, 06 Oct 2022 15:59:07 +0100 | |
changeset 12746 | 126aefd2c4c6 |
parent 12666 | 07424992d7fc |
child 12747 | 19113f232423 |
permissions | -rw-r--r-- |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 |
local id = require "util.id"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 |
local jid = require "util.jid"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 |
local base64 = require "util.encodings".base64; |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
4 |
local usermanager = require "core.usermanager"; |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
5 |
local generate_identifier = require "util.id".short; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 |
|
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 |
local token_store = module:open_store("auth_tokens", "map"); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
|
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
9 |
local function select_role(username, host, role) |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
10 |
if role then |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
11 |
return prosody.hosts[host].authz.get_role_by_name(role); |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
12 |
end |
12666
07424992d7fc
mod_authz_internal, and more: New iteration of role API
Matthew Wild <mwild1@gmail.com>
parents:
12653
diff
changeset
|
13 |
return usermanager.get_user_role(username, host); |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
14 |
end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
15 |
|
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
16 |
function create_jid_token(actor_jid, token_jid, token_role, token_ttl) |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 |
token_jid = jid.prep(token_jid); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 |
if not actor_jid or token_jid ~= actor_jid and not jid.compare(token_jid, actor_jid) then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 |
return nil, "not-authorized"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 |
|
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 |
local token_username, token_host, token_resource = jid.split(token_jid); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 |
|
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 |
if token_host ~= module.host then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 |
return nil, "invalid-host"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 |
|
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 |
local token_info = { |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 |
owner = actor_jid; |
10679
5efd6865486c
mod_tokenauth: Track creation time of tokens
Matthew Wild <mwild1@gmail.com>
parents:
10678
diff
changeset
|
30 |
created = os.time(); |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 |
expires = token_ttl and (os.time() + token_ttl) or nil; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 |
jid = token_jid; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 |
|
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
34 |
resource = token_resource; |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
35 |
role = token_role; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 |
}; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 |
|
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 |
local token_id = id.long(); |
10678
4459afac4d13
mod_tokenauth: Handle tokens issued to bare hosts (eg components)
Kim Alvefur <zash@zash.se>
parents:
10673
diff
changeset
|
39 |
local token = base64.encode("1;"..jid.join(token_username, token_host)..";"..token_id); |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 |
token_store:set(token_username, token_id, token_info); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 |
|
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 |
return token, token_info; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 |
|
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 |
local function parse_token(encoded_token) |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 |
local token = base64.decode(encoded_token); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 |
if not token then return nil; end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 |
local token_jid, token_id = token:match("^1;([^;]+);(.+)$"); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 |
if not token_jid then return nil; end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 |
local token_user, token_host = jid.split(token_jid); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 |
return token_id, token_user, token_host; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 |
|
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
54 |
local function _get_parsed_token_info(token_id, token_user, token_host) |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 |
if token_host ~= module.host then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 |
return nil, "invalid-host"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 |
|
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 |
local token_info, err = token_store:get(token_user, token_id); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 |
if not token_info then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 |
if err then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 |
return nil, "internal-error"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 |
return nil, "not-authorized"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 |
|
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 |
if token_info.expires and token_info.expires < os.time() then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 |
return nil, "not-authorized"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 |
|
12746
126aefd2c4c6
mod_tokenauth: Invalidate tokens issued before most recent password change
Matthew Wild <mwild1@gmail.com>
parents:
12666
diff
changeset
|
71 |
local account_info = usermanager.get_account_info(token_user, module.host); |
126aefd2c4c6
mod_tokenauth: Invalidate tokens issued before most recent password change
Matthew Wild <mwild1@gmail.com>
parents:
12666
diff
changeset
|
72 |
local password_updated_at = account_info and account_info.password_updated; |
126aefd2c4c6
mod_tokenauth: Invalidate tokens issued before most recent password change
Matthew Wild <mwild1@gmail.com>
parents:
12666
diff
changeset
|
73 |
if password_updated_at and password_updated_at > token_info.created then |
126aefd2c4c6
mod_tokenauth: Invalidate tokens issued before most recent password change
Matthew Wild <mwild1@gmail.com>
parents:
12666
diff
changeset
|
74 |
return nil, "not-authorized"; |
126aefd2c4c6
mod_tokenauth: Invalidate tokens issued before most recent password change
Matthew Wild <mwild1@gmail.com>
parents:
12666
diff
changeset
|
75 |
end |
126aefd2c4c6
mod_tokenauth: Invalidate tokens issued before most recent password change
Matthew Wild <mwild1@gmail.com>
parents:
12666
diff
changeset
|
76 |
|
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 |
return token_info |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 |
|
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
80 |
function get_token_info(token) |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
81 |
local token_id, token_user, token_host = parse_token(token); |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
82 |
if not token_id then |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
83 |
return nil, "invalid-token-format"; |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
84 |
end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
85 |
return _get_parsed_token_info(token_id, token_user, token_host); |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
86 |
end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
87 |
|
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
88 |
function get_token_session(token, resource) |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
89 |
local token_id, token_user, token_host = parse_token(token); |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
90 |
if not token_id then |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
91 |
return nil, "invalid-token-format"; |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
92 |
end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
93 |
|
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
94 |
local token_info, err = _get_parsed_token_info(token_id, token_user, token_host); |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
95 |
if not token_info then return nil, err; end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
96 |
|
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
97 |
return { |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
98 |
username = token_user; |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
99 |
host = token_host; |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
100 |
resource = token_info.resource or resource or generate_identifier(); |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
101 |
|
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
102 |
role = select_role(token_user, token_host, token_info.role); |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
103 |
}; |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
104 |
end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
105 |
|
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
106 |
|
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
107 |
function revoke_token(token) |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
108 |
local token_id, token_user, token_host = parse_token(token); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
109 |
if not token_id then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
110 |
return nil, "invalid-token-format"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
111 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
112 |
if token_host ~= module.host then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
113 |
return nil, "invalid-host"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
114 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
115 |
return token_store:set(token_user, token_id, nil); |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
116 |
end |