author | Kim Alvefur <zash@zash.se> |
Sun, 05 Nov 2023 16:10:40 +0100 | |
changeset 13309 | 852a61c720d0 |
parent 13280 | c34266c061c9 |
child 13325 | 19c814d4dd3a |
permissions | -rw-r--r-- |
12981
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12963
diff
changeset
|
1 |
local base64 = require "prosody.util.encodings".base64; |
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12963
diff
changeset
|
2 |
local hashes = require "prosody.util.hashes"; |
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12963
diff
changeset
|
3 |
local id = require "prosody.util.id"; |
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12963
diff
changeset
|
4 |
local jid = require "prosody.util.jid"; |
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12963
diff
changeset
|
5 |
local random = require "prosody.util.random"; |
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12963
diff
changeset
|
6 |
local usermanager = require "prosody.core.usermanager"; |
74b9e05af71e
plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents:
12963
diff
changeset
|
7 |
local generate_identifier = require "prosody.util.id".short; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
9 |
local token_store = module:open_store("auth_tokens", "keyval+"); |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 |
|
13213
c8d949cf6b09
plugins: Switch to :get_option_period() for time range options
Kim Alvefur <zash@zash.se>
parents:
13103
diff
changeset
|
11 |
local access_time_granularity = module:get_option_period("token_auth_access_time_granularity", 60); |
13277
a1c927323f06
mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents:
13276
diff
changeset
|
12 |
local empty_grant_lifetime = module:get_option_period("tokenless_grant_ttl", "2w"); |
12984
6ebad8e16b3b
mod_tokenauth: Track last access time (last time a token was used)
Matthew Wild <mwild1@gmail.com>
parents:
12981
diff
changeset
|
13 |
|
13103
a1ba503610ed
mod_tokenauth: Support selection of _no_ role at all
Kim Alvefur <zash@zash.se>
parents:
13102
diff
changeset
|
14 |
local function select_role(username, host, role_name) |
a1ba503610ed
mod_tokenauth: Support selection of _no_ role at all
Kim Alvefur <zash@zash.se>
parents:
13102
diff
changeset
|
15 |
if not role_name then return end |
a1ba503610ed
mod_tokenauth: Support selection of _no_ role at all
Kim Alvefur <zash@zash.se>
parents:
13102
diff
changeset
|
16 |
local role = usermanager.get_role_by_name(role_name, host); |
a1ba503610ed
mod_tokenauth: Support selection of _no_ role at all
Kim Alvefur <zash@zash.se>
parents:
13102
diff
changeset
|
17 |
if not role then return end |
a1ba503610ed
mod_tokenauth: Support selection of _no_ role at all
Kim Alvefur <zash@zash.se>
parents:
13102
diff
changeset
|
18 |
if not usermanager.user_can_assume_role(username, host, role.name) then return end |
a1ba503610ed
mod_tokenauth: Support selection of _no_ role at all
Kim Alvefur <zash@zash.se>
parents:
13102
diff
changeset
|
19 |
return role; |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
20 |
end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
21 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
22 |
function create_grant(actor_jid, grant_jid, grant_ttl, grant_data) |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
23 |
grant_jid = jid.prep(grant_jid); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
24 |
if not actor_jid or actor_jid ~= grant_jid and not jid.compare(grant_jid, actor_jid) then |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
25 |
module:log("debug", "Actor <%s> is not permitted to create a token granting access to JID <%s>", actor_jid, grant_jid); |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 |
return nil, "not-authorized"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
29 |
local grant_username, grant_host, grant_resource = jid.split(grant_jid); |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
31 |
if grant_host ~= module.host then |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 |
return nil, "invalid-host"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
35 |
local grant_id = id.short(); |
12984
6ebad8e16b3b
mod_tokenauth: Track last access time (last time a token was used)
Matthew Wild <mwild1@gmail.com>
parents:
12981
diff
changeset
|
36 |
local now = os.time(); |
6ebad8e16b3b
mod_tokenauth: Track last access time (last time a token was used)
Matthew Wild <mwild1@gmail.com>
parents:
12981
diff
changeset
|
37 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
38 |
local grant = { |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
39 |
id = grant_id; |
12957
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
40 |
|
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 |
owner = actor_jid; |
12984
6ebad8e16b3b
mod_tokenauth: Track last access time (last time a token was used)
Matthew Wild <mwild1@gmail.com>
parents:
12981
diff
changeset
|
42 |
created = now; |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
43 |
expires = grant_ttl and (now + grant_ttl) or nil; |
12984
6ebad8e16b3b
mod_tokenauth: Track last access time (last time a token was used)
Matthew Wild <mwild1@gmail.com>
parents:
12981
diff
changeset
|
44 |
accessed = now; |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
45 |
|
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
46 |
jid = grant_jid; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
47 |
resource = grant_resource; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
49 |
data = grant_data; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
50 |
|
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
51 |
-- tokens[<hash-name>..":"..<secret>] = token_info |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
52 |
tokens = {}; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 |
}; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
55 |
local ok, err = token_store:set_key(grant_username, grant_id, grant); |
13000
e8716515405e
mod_tokenauth: return error if storage of new token fails
Matthew Wild <mwild1@gmail.com>
parents:
12984
diff
changeset
|
56 |
if not ok then |
e8716515405e
mod_tokenauth: return error if storage of new token fails
Matthew Wild <mwild1@gmail.com>
parents:
12984
diff
changeset
|
57 |
return nil, err; |
e8716515405e
mod_tokenauth: return error if storage of new token fails
Matthew Wild <mwild1@gmail.com>
parents:
12984
diff
changeset
|
58 |
end |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 |
|
13007
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
60 |
module:fire_event("token-grant-created", { |
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
61 |
id = grant_id; |
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
62 |
grant = grant; |
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
63 |
username = grant_username; |
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
64 |
host = grant_host; |
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
65 |
}); |
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
66 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
67 |
return grant; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
70 |
function create_token(grant_jid, grant, token_role, token_ttl, token_purpose, token_data) |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
71 |
if (token_data and type(token_data) ~= "table") or (token_purpose and type(token_purpose) ~= "string") then |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
72 |
return nil, "bad-request"; |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
73 |
end |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
74 |
local grant_username, grant_host = jid.split(grant_jid); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
75 |
if grant_host ~= module.host then |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
76 |
return nil, "invalid-host"; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
77 |
end |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
78 |
if type(grant) == "string" then -- lookup by id |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
79 |
grant = token_store:get_key(grant_username, grant); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
80 |
if not grant then return nil; end |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
81 |
end |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
82 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
83 |
if not grant.tokens then return nil, "internal-server-error"; end -- old-style token? |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
84 |
|
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
85 |
local now = os.time(); |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
86 |
local expires = grant.expires; -- Default to same expiry as grant |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
87 |
if token_ttl then -- explicit lifetime requested |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
88 |
if expires then |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
89 |
-- Grant has an expiry, so limit to that or shorter |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
90 |
expires = math.min(now + token_ttl, expires); |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
91 |
else |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
92 |
-- Grant never expires, just use whatever expiry is requested for the token |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
93 |
expires = now + token_ttl; |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
94 |
end |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
95 |
end |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
96 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
97 |
local token_info = { |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
98 |
role = token_role; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
99 |
|
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
100 |
created = now; |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
101 |
expires = expires; |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
102 |
purpose = token_purpose; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
103 |
|
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
104 |
data = token_data; |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
105 |
}; |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
106 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
107 |
local token_secret = random.bytes(18); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
108 |
grant.tokens["sha256:"..hashes.sha256(token_secret, true)] = token_info; |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
109 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
110 |
local ok, err = token_store:set_key(grant_username, grant.id, grant); |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
111 |
if not ok then |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
112 |
return nil, err; |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
113 |
end |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
114 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
115 |
local token_string = "secret-token:"..base64.encode("2;"..grant.id..";"..token_secret..";"..grant.jid); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
116 |
return token_string, token_info; |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
117 |
end |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
118 |
|
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
119 |
local function parse_token(encoded_token) |
12921
e4de42495fb7
mod_tokenauth: Gracefully handle missing tokens
Matthew Wild <mwild1@gmail.com>
parents:
12919
diff
changeset
|
120 |
if not encoded_token then return nil; end |
12957
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
121 |
local encoded_data = encoded_token:match("^secret%-token:(.+)$"); |
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
122 |
if not encoded_data then return nil; end |
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
123 |
local token = base64.decode(encoded_data); |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
124 |
if not token then return nil; end |
13078
794a5ad5495e
mod_tokenauth: Fix parsing binary part of tokens
Kim Alvefur <zash@zash.se>
parents:
13077
diff
changeset
|
125 |
local token_id, token_secret, token_jid = token:match("^2;([^;]+);(..................);(.+)$"); |
12957
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
126 |
if not token_id then return nil; end |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
127 |
local token_user, token_host = jid.split(token_jid); |
12957
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
128 |
return token_id, token_user, token_host, token_secret; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
129 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
130 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
131 |
local function clear_expired_grant_tokens(grant, now) |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
132 |
local updated; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
133 |
now = now or os.time(); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
134 |
for secret, token_info in pairs(grant.tokens) do |
13003
c87ac7d1967f
mod_tokenauth: Fix traceback when checking expiry of tokens with no expiry
Matthew Wild <mwild1@gmail.com>
parents:
13002
diff
changeset
|
135 |
local expires = token_info.expires; |
c87ac7d1967f
mod_tokenauth: Fix traceback when checking expiry of tokens with no expiry
Matthew Wild <mwild1@gmail.com>
parents:
13002
diff
changeset
|
136 |
if expires and expires < now then |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
137 |
grant.tokens[secret] = nil; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
138 |
updated = true; |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
139 |
end |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
140 |
end |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
141 |
return updated; |
13001
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
142 |
end |
0a56b84ec4ad
mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents:
13000
diff
changeset
|
143 |
|
13013
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
144 |
local function _get_validated_grant_info(username, grant) |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
145 |
if type(grant) == "string" then |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
146 |
grant = token_store:get_key(username, grant); |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
147 |
end |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
148 |
if not grant or not grant.created then return nil; end |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
149 |
|
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
150 |
-- Invalidate grants from before last password change |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
151 |
local account_info = usermanager.get_account_info(username, module.host); |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
152 |
local password_updated_at = account_info and account_info.password_updated; |
13276
8535a6105919
mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents:
13275
diff
changeset
|
153 |
local now = os.time(); |
13013
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
154 |
if password_updated_at and grant.created < password_updated_at then |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
155 |
module:log("debug", "Token grant issued before last password change, invalidating it now"); |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
156 |
token_store:set_key(username, grant.id, nil); |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
157 |
return nil, "not-authorized"; |
13276
8535a6105919
mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents:
13275
diff
changeset
|
158 |
elseif grant.expires and grant.expires < now then |
13013
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
159 |
module:log("debug", "Token grant expired, cleaning up"); |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
160 |
token_store:set_key(username, grant.id, nil); |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
161 |
return nil, "expired"; |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
162 |
end |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
163 |
|
13275
56c1d2498d66
mod_tokenauth: Delete grants in the wrong formats on retrieval
Kim Alvefur <zash@zash.se>
parents:
13250
diff
changeset
|
164 |
if not grant.tokens then |
56c1d2498d66
mod_tokenauth: Delete grants in the wrong formats on retrieval
Kim Alvefur <zash@zash.se>
parents:
13250
diff
changeset
|
165 |
module:log("debug", "Token grant without tokens, cleaning up"); |
56c1d2498d66
mod_tokenauth: Delete grants in the wrong formats on retrieval
Kim Alvefur <zash@zash.se>
parents:
13250
diff
changeset
|
166 |
token_store:set_key(username, grant.id, nil); |
56c1d2498d66
mod_tokenauth: Delete grants in the wrong formats on retrieval
Kim Alvefur <zash@zash.se>
parents:
13250
diff
changeset
|
167 |
return nil, "invalid"; |
56c1d2498d66
mod_tokenauth: Delete grants in the wrong formats on retrieval
Kim Alvefur <zash@zash.se>
parents:
13250
diff
changeset
|
168 |
end |
13309
852a61c720d0
mod_tokenauth: Fix saving grants after clearing expired tokens
Kim Alvefur <zash@zash.se>
parents:
13280
diff
changeset
|
169 |
|
852a61c720d0
mod_tokenauth: Fix saving grants after clearing expired tokens
Kim Alvefur <zash@zash.se>
parents:
13280
diff
changeset
|
170 |
local found_expired = false |
13276
8535a6105919
mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents:
13275
diff
changeset
|
171 |
for secret_hash, token_info in pairs(grant.tokens) do |
8535a6105919
mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents:
13275
diff
changeset
|
172 |
if token_info.expires and token_info.expires < now then |
8535a6105919
mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents:
13275
diff
changeset
|
173 |
module:log("debug", "Token has expired, cleaning it up"); |
8535a6105919
mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents:
13275
diff
changeset
|
174 |
grant.tokens[secret_hash] = nil; |
13279
5db61e0dfc62
mod_tokenauth: Save grant after removing expired tokens
Kim Alvefur <zash@zash.se>
parents:
13278
diff
changeset
|
175 |
found_expired = true; |
5db61e0dfc62
mod_tokenauth: Save grant after removing expired tokens
Kim Alvefur <zash@zash.se>
parents:
13278
diff
changeset
|
176 |
end |
13276
8535a6105919
mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents:
13275
diff
changeset
|
177 |
end |
13277
a1c927323f06
mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents:
13276
diff
changeset
|
178 |
|
a1c927323f06
mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents:
13276
diff
changeset
|
179 |
if not grant.expires and next(grant.tokens) == nil and grant.accessed + empty_grant_lifetime < now then |
a1c927323f06
mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents:
13276
diff
changeset
|
180 |
module:log("debug", "Token grant has no tokens, discarding"); |
a1c927323f06
mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents:
13276
diff
changeset
|
181 |
token_store:set_key(username, grant.id, nil); |
a1c927323f06
mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents:
13276
diff
changeset
|
182 |
return nil, "expired"; |
13309
852a61c720d0
mod_tokenauth: Fix saving grants after clearing expired tokens
Kim Alvefur <zash@zash.se>
parents:
13280
diff
changeset
|
183 |
elseif found_expired then |
852a61c720d0
mod_tokenauth: Fix saving grants after clearing expired tokens
Kim Alvefur <zash@zash.se>
parents:
13280
diff
changeset
|
184 |
token_store:set_key(username, grant.id, grant); |
13277
a1c927323f06
mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents:
13276
diff
changeset
|
185 |
end |
a1c927323f06
mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents:
13276
diff
changeset
|
186 |
|
13013
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
187 |
return grant; |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
188 |
end |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
189 |
|
12957
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
190 |
local function _get_validated_token_info(token_id, token_user, token_host, token_secret) |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
191 |
if token_host ~= module.host then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
192 |
return nil, "invalid-host"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
193 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
194 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
195 |
local grant, err = token_store:get_key(token_user, token_id); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
196 |
if not grant or not grant.tokens then |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
197 |
if err then |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
198 |
module:log("error", "Unable to read from token storage: %s", err); |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
199 |
return nil, "internal-error"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
200 |
end |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
201 |
module:log("warn", "Invalid token in storage (%s / %s)", token_user, token_id); |
12957
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
202 |
return nil, "not-authorized"; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
203 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
204 |
|
12957
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
205 |
-- Check provided secret |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
206 |
local secret_hash = "sha256:"..hashes.sha256(token_secret, true); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
207 |
local token_info = grant.tokens[secret_hash]; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
208 |
if not token_info then |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
209 |
module:log("debug", "No tokens matched the given secret"); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
210 |
return nil, "not-authorized"; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
211 |
end |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
212 |
|
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
213 |
-- Check expiry |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
214 |
local now = os.time(); |
13077
9e5802b45b9e
mod_tokenauth: Only check if expiry of expiring tokens
Kim Alvefur <zash@zash.se>
parents:
13028
diff
changeset
|
215 |
if token_info.expires and token_info.expires < now then |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
216 |
module:log("debug", "Token has expired, cleaning it up"); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
217 |
grant.tokens[secret_hash] = nil; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
218 |
token_store:set_key(token_user, token_id, grant); |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
219 |
return nil, "not-authorized"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
220 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
221 |
|
13013
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
222 |
-- Verify grant validity (expiry, etc.) |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
223 |
grant = _get_validated_grant_info(token_user, grant); |
a70ff0c524c9
mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents:
13010
diff
changeset
|
224 |
if not grant then |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
225 |
return nil, "not-authorized"; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
226 |
end |
12746
126aefd2c4c6
mod_tokenauth: Invalidate tokens issued before most recent password change
Matthew Wild <mwild1@gmail.com>
parents:
12666
diff
changeset
|
227 |
|
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
228 |
-- Update last access time if necessary |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
229 |
local last_accessed = grant.accessed; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
230 |
if not last_accessed or (now - last_accessed) > access_time_granularity then |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
231 |
grant.accessed = now; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
232 |
clear_expired_grant_tokens(grant); -- Clear expired tokens while we're here |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
233 |
token_store:set_key(token_user, token_id, grant); |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
234 |
end |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
235 |
|
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
236 |
token_info.id = token_id; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
237 |
token_info.grant = grant; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
238 |
token_info.jid = grant.jid; |
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
239 |
|
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
240 |
return token_info; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
241 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
242 |
|
13014
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
243 |
function get_grant_info(username, grant_id) |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
244 |
local grant = _get_validated_grant_info(username, grant_id); |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
245 |
if not grant then return nil; end |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
246 |
|
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
247 |
-- Caller is only interested in the grant, no need to expose token stuff to them |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
248 |
grant.tokens = nil; |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
249 |
|
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
250 |
return grant; |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
251 |
end |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
252 |
|
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
253 |
function get_user_grants(username) |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
254 |
local grants = token_store:get(username); |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
255 |
if not grants then return nil; end |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
256 |
for grant_id, grant in pairs(grants) do |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
257 |
grants[grant_id] = _get_validated_grant_info(username, grant); |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
258 |
end |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
259 |
return grants; |
3e454af3615d
mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents:
13013
diff
changeset
|
260 |
end |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
261 |
|
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
262 |
function get_token_info(token) |
12957
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
263 |
local token_id, token_user, token_host, token_secret = parse_token(token); |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
264 |
if not token_id then |
12956
a668bc1aa39d
mod_tokenauth: Log error when token validation fails
Matthew Wild <mwild1@gmail.com>
parents:
12942
diff
changeset
|
265 |
module:log("warn", "Failed to verify access token: %s", token_user); |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
266 |
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
|
267 |
end |
12957
ebe3b2f96cad
mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents:
12956
diff
changeset
|
268 |
return _get_validated_token_info(token_id, token_user, token_host, token_secret); |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
269 |
end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
270 |
|
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
271 |
function get_token_session(token, resource) |
12963
e331210beeb2
mod_tokenauth: Fix traceback in get_token_session()
Kim Alvefur <zash@zash.se>
parents:
12957
diff
changeset
|
272 |
local token_id, token_user, token_host, token_secret = parse_token(token); |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
273 |
if not token_id then |
12956
a668bc1aa39d
mod_tokenauth: Log error when token validation fails
Matthew Wild <mwild1@gmail.com>
parents:
12942
diff
changeset
|
274 |
module:log("warn", "Failed to verify access token: %s", token_user); |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
275 |
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
|
276 |
end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
277 |
|
12963
e331210beeb2
mod_tokenauth: Fix traceback in get_token_session()
Kim Alvefur <zash@zash.se>
parents:
12957
diff
changeset
|
278 |
local token_info, err = _get_validated_token_info(token_id, token_user, token_host, token_secret); |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
279 |
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
|
280 |
|
13102
65d2ff6e674e
mod_tokenauth: Return error instead of session for token without role
Kim Alvefur <zash@zash.se>
parents:
13078
diff
changeset
|
281 |
local role = select_role(token_user, token_host, token_info.role); |
65d2ff6e674e
mod_tokenauth: Return error instead of session for token without role
Kim Alvefur <zash@zash.se>
parents:
13078
diff
changeset
|
282 |
if not role then return nil, "not-authorized"; end |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
283 |
return { |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
284 |
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
|
285 |
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
|
286 |
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
|
287 |
|
13102
65d2ff6e674e
mod_tokenauth: Return error instead of session for token without role
Kim Alvefur <zash@zash.se>
parents:
13078
diff
changeset
|
288 |
role = role; |
12653
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
289 |
}; |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
290 |
end |
86e1187f6274
mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents:
10679
diff
changeset
|
291 |
|
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
292 |
function revoke_token(token) |
13250
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
293 |
local grant_id, token_user, token_host, token_secret = parse_token(token); |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
294 |
if not grant_id then |
12956
a668bc1aa39d
mod_tokenauth: Log error when token validation fails
Matthew Wild <mwild1@gmail.com>
parents:
12942
diff
changeset
|
295 |
module:log("warn", "Failed to verify access token: %s", token_user); |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
296 |
return nil, "invalid-token-format"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
297 |
end |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
298 |
if token_host ~= module.host then |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
299 |
return nil, "invalid-host"; |
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
300 |
end |
13250
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
301 |
local grant, err = _get_validated_grant_info(token_user, grant_id); |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
302 |
if not grant then return grant, err; end |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
303 |
local secret_hash = "sha256:"..hashes.sha256(token_secret, true); |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
304 |
local token_info = grant.tokens[secret_hash]; |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
305 |
if not grant or not token_info then |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
306 |
return nil, "item-not-found"; |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
307 |
end |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
308 |
grant.tokens[secret_hash] = nil; |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
309 |
local ok, err = token_store:set_key(token_user, grant_id, grant); |
13007
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
310 |
if not ok then |
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
311 |
return nil, err; |
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
312 |
end |
13250
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
313 |
module:fire_event("token-revoked", { |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
314 |
grant_id = grant_id; |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
315 |
grant = grant; |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
316 |
info = token_info; |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
317 |
username = token_user; |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
318 |
host = token_host; |
2e04d54fb013
mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents:
13213
diff
changeset
|
319 |
}); |
13007
34ed17ef1c1a
mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents:
13004
diff
changeset
|
320 |
return true; |
10672
25c84c0a66fd
mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
321 |
end |
12919
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
322 |
|
13028
7558fd152459
mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents:
13014
diff
changeset
|
323 |
function revoke_grant(username, grant_id) |
7558fd152459
mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents:
13014
diff
changeset
|
324 |
local ok, err = token_store:set_key(username, grant_id, nil); |
7558fd152459
mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents:
13014
diff
changeset
|
325 |
if not ok then return nil, err; end |
7558fd152459
mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents:
13014
diff
changeset
|
326 |
module:fire_event("token-grant-revoked", { id = grant_id, username = username, host = module.host }); |
7558fd152459
mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents:
13014
diff
changeset
|
327 |
return true; |
7558fd152459
mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents:
13014
diff
changeset
|
328 |
end |
7558fd152459
mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents:
13014
diff
changeset
|
329 |
|
12919
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
330 |
function sasl_handler(auth_provider, purpose, extra) |
12942
055b03d3059b
util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents:
12923
diff
changeset
|
331 |
return function (sasl, token, realm, _authzid) |
12919
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
332 |
local token_info, err = get_token_info(token); |
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
333 |
if not token_info then |
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
334 |
module:log("debug", "SASL handler failed to verify token: %s", err); |
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
335 |
return nil, nil, extra; |
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
336 |
end |
13002
601d9a375b86
mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents:
13001
diff
changeset
|
337 |
local token_user, token_host, resource = jid.split(token_info.grant.jid); |
12942
055b03d3059b
util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents:
12923
diff
changeset
|
338 |
if realm ~= token_host or (purpose and token_info.purpose ~= purpose) then |
12919
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
339 |
return nil, nil, extra; |
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
340 |
end |
12942
055b03d3059b
util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents:
12923
diff
changeset
|
341 |
if auth_provider.is_enabled and not auth_provider.is_enabled(token_user) then |
12919
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
342 |
return true, false, token_info; |
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
343 |
end |
12942
055b03d3059b
util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents:
12923
diff
changeset
|
344 |
sasl.resource = resource; |
055b03d3059b
util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents:
12923
diff
changeset
|
345 |
sasl.token_info = token_info; |
055b03d3059b
util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents:
12923
diff
changeset
|
346 |
return token_user, true, token_info; |
12919
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
347 |
end; |
70f6a8dceb1d
mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents:
12918
diff
changeset
|
348 |
end |
13278
ddfe07041fc5
mod_tokenauth: Periodically clear out expired tokens and grants
Kim Alvefur <zash@zash.se>
parents:
13277
diff
changeset
|
349 |
|
13280
c34266c061c9
mod_tokenauth: Set name/description on cleanup job
Kim Alvefur <zash@zash.se>
parents:
13279
diff
changeset
|
350 |
module:daily("clear expired grants", function() |
13278
ddfe07041fc5
mod_tokenauth: Periodically clear out expired tokens and grants
Kim Alvefur <zash@zash.se>
parents:
13277
diff
changeset
|
351 |
for username in token_store:items() do |
ddfe07041fc5
mod_tokenauth: Periodically clear out expired tokens and grants
Kim Alvefur <zash@zash.se>
parents:
13277
diff
changeset
|
352 |
get_user_grants(username); -- clears out expired grants |
ddfe07041fc5
mod_tokenauth: Periodically clear out expired tokens and grants
Kim Alvefur <zash@zash.se>
parents:
13277
diff
changeset
|
353 |
end |
ddfe07041fc5
mod_tokenauth: Periodically clear out expired tokens and grants
Kim Alvefur <zash@zash.se>
parents:
13277
diff
changeset
|
354 |
end) |