Annotate

plugins/mod_tokenauth.lua @ 13742:47e537e340c4 default tip

Merge 13.0->trunk
author Matthew Wild <mwild1@gmail.com>
date Mon, 17 Feb 2025 23:06:26 +0000
parent 13638:94462d8f2fa9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12977
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12959
diff changeset
1 local base64 = require "prosody.util.encodings".base64;
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12959
diff changeset
2 local hashes = require "prosody.util.hashes";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12959
diff changeset
3 local id = require "prosody.util.id";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12959
diff changeset
4 local jid = require "prosody.util.jid";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12959
diff changeset
5 local random = require "prosody.util.random";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12959
diff changeset
6 local usermanager = require "prosody.core.usermanager";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12959
diff changeset
7 local generate_identifier = require "prosody.util.id".short;
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
9 local token_store = module:open_store("auth_tokens", "keyval+");
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10
13209
c8d949cf6b09 plugins: Switch to :get_option_period() for time range options
Kim Alvefur <zash@zash.se>
parents: 13099
diff changeset
11 local access_time_granularity = module:get_option_period("token_auth_access_time_granularity", 60);
13273
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
diff changeset
12 local empty_grant_lifetime = module:get_option_period("tokenless_grant_ttl", "2w");
12980
6ebad8e16b3b mod_tokenauth: Track last access time (last time a token was used)
Matthew Wild <mwild1@gmail.com>
parents: 12977
diff changeset
13
13099
a1ba503610ed mod_tokenauth: Support selection of _no_ role at all
Kim Alvefur <zash@zash.se>
parents: 13098
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: 13098
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: 13098
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: 13098
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: 13098
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: 13098
diff changeset
19 return role;
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
20 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
21
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
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: 12997
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: 12997
diff changeset
25 module:log("debug", "Actor <%s> is not permitted to create a token granting access to JID <%s>", actor_jid, grant_jid);
10668
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
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
29 local grant_username, grant_host, grant_resource = jid.split(grant_jid);
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
31 if grant_host ~= module.host then
10668
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
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
35 local grant_id = id.short();
12980
6ebad8e16b3b mod_tokenauth: Track last access time (last time a token was used)
Matthew Wild <mwild1@gmail.com>
parents: 12977
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: 12977
diff changeset
37
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
38 local grant = {
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
39 id = grant_id;
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
40
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 owner = actor_jid;
12980
6ebad8e16b3b mod_tokenauth: Track last access time (last time a token was used)
Matthew Wild <mwild1@gmail.com>
parents: 12977
diff changeset
42 created = now;
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
43 expires = grant_ttl and (now + grant_ttl) or nil;
12980
6ebad8e16b3b mod_tokenauth: Track last access time (last time a token was used)
Matthew Wild <mwild1@gmail.com>
parents: 12977
diff changeset
44 accessed = now;
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
45
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
46 jid = grant_jid;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
47 resource = grant_resource;
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
49 data = grant_data;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
50
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
52 tokens = {};
10668
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
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
55 local ok, err = token_store:set_key(grant_username, grant_id, grant);
12996
e8716515405e mod_tokenauth: return error if storage of new token fails
Matthew Wild <mwild1@gmail.com>
parents: 12980
diff changeset
56 if not ok then
e8716515405e mod_tokenauth: return error if storage of new token fails
Matthew Wild <mwild1@gmail.com>
parents: 12980
diff changeset
57 return nil, err;
e8716515405e mod_tokenauth: return error if storage of new token fails
Matthew Wild <mwild1@gmail.com>
parents: 12980
diff changeset
58 end
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59
13003
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
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: 13000
diff changeset
61 id = grant_id;
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
62 grant = grant;
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
63 username = grant_username;
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
64 host = grant_host;
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
65 });
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
66
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
67 return grant;
10668
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
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
70 function create_token(grant_jid, grant, token_role, token_ttl, token_purpose, token_data)
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
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: 12996
diff changeset
72 return nil, "bad-request";
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
73 end
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
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: 12997
diff changeset
76 return nil, "invalid-host";
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
77 end
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
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: 12997
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: 12997
diff changeset
81 end
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
82
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
83 if not grant.tokens then return nil, "internal-server-error"; end -- old-style token?
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
84
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
85 local now = os.time();
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
87 if token_ttl then -- explicit lifetime requested
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
88 if expires then
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
89 -- Grant has an expiry, so limit to that or shorter
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
90 expires = math.min(now + token_ttl, expires);
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
91 else
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
92 -- Grant never expires, just use whatever expiry is requested for the token
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
93 expires = now + token_ttl;
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
94 end
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
95 end
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
96
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
97 local token_info = {
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
98 role = token_role;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
99
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
100 created = now;
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
101 expires = expires;
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
102 purpose = token_purpose;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
103
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
104 data = token_data;
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
105 };
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
106
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
108 grant.tokens["sha256:"..hashes.sha256(token_secret, true)] = token_info;
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
109
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
110 local ok, err = token_store:set_key(grant_username, grant.id, grant);
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
111 if not ok then
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
112 return nil, err;
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
113 end
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
114
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
116 return token_string, token_info;
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
117 end
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
118
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 local function parse_token(encoded_token)
12917
e4de42495fb7 mod_tokenauth: Gracefully handle missing tokens
Matthew Wild <mwild1@gmail.com>
parents: 12915
diff changeset
120 if not encoded_token then return nil; end
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
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: 12952
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: 12952
diff changeset
123 local token = base64.decode(encoded_data);
10668
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
13074
794a5ad5495e mod_tokenauth: Fix parsing binary part of tokens
Kim Alvefur <zash@zash.se>
parents: 13073
diff changeset
125 local token_id, token_secret, token_jid = token:match("^2;([^;]+);(..................);(.+)$");
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
126 if not token_id then return nil; end
10668
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);
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
128 return token_id, token_user, token_host, token_secret;
10668
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
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
132 local updated;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
133 now = now or os.time();
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
134 for secret, token_info in pairs(grant.tokens) do
12999
c87ac7d1967f mod_tokenauth: Fix traceback when checking expiry of tokens with no expiry
Matthew Wild <mwild1@gmail.com>
parents: 12998
diff changeset
135 local expires = token_info.expires;
13638
94462d8f2fa9 mod_tokenauth: Fix expiry lasting one second too much
Rémi Bardon <remi@remibardon.name>
parents: 13356
diff changeset
136 if expires and expires <= now then
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
137 grant.tokens[secret] = nil;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
138 updated = true;
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
139 end
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
140 end
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
141 return updated;
12997
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
142 end
0a56b84ec4ad mod_tokenauth: Support for creating sub-tokens
Matthew Wild <mwild1@gmail.com>
parents: 12996
diff changeset
143
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
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: 13006
diff changeset
145 if type(grant) == "string" then
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
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: 13006
diff changeset
147 end
13356
bbbda8819331 mod_tokenauth: Ignore invalid grants in storage that have no id
Matthew Wild <mwild1@gmail.com>
parents: 13321
diff changeset
148 if not grant or not grant.created or not grant.id then return nil; end
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
149
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
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: 13006
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: 13006
diff changeset
152 local password_updated_at = account_info and account_info.password_updated;
13272
8535a6105919 mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents: 13271
diff changeset
153 local now = os.time();
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
154 if password_updated_at and grant.created < password_updated_at then
13321
19c814d4dd3a mod_tokenauth: Include more details in debug logs
Kim Alvefur <zash@zash.se>
parents: 13305
diff changeset
155 module:log("debug", "Token grant %s of %s issued before last password change, invalidating it now", grant.id, username);
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
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: 13006
diff changeset
157 return nil, "not-authorized";
13638
94462d8f2fa9 mod_tokenauth: Fix expiry lasting one second too much
Rémi Bardon <remi@remibardon.name>
parents: 13356
diff changeset
158 elseif grant.expires and grant.expires <= now then
13321
19c814d4dd3a mod_tokenauth: Include more details in debug logs
Kim Alvefur <zash@zash.se>
parents: 13305
diff changeset
159 module:log("debug", "Token grant %s of %s expired, cleaning up", grant.id, username);
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
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: 13006
diff changeset
161 return nil, "expired";
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
162 end
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
163
13271
56c1d2498d66 mod_tokenauth: Delete grants in the wrong formats on retrieval
Kim Alvefur <zash@zash.se>
parents: 13246
diff changeset
164 if not grant.tokens then
13321
19c814d4dd3a mod_tokenauth: Include more details in debug logs
Kim Alvefur <zash@zash.se>
parents: 13305
diff changeset
165 module:log("debug", "Token grant %s of %s without tokens, cleaning up", grant.id, username);
13271
56c1d2498d66 mod_tokenauth: Delete grants in the wrong formats on retrieval
Kim Alvefur <zash@zash.se>
parents: 13246
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: 13246
diff changeset
167 return nil, "invalid";
56c1d2498d66 mod_tokenauth: Delete grants in the wrong formats on retrieval
Kim Alvefur <zash@zash.se>
parents: 13246
diff changeset
168 end
13305
852a61c720d0 mod_tokenauth: Fix saving grants after clearing expired tokens
Kim Alvefur <zash@zash.se>
parents: 13276
diff changeset
169
852a61c720d0 mod_tokenauth: Fix saving grants after clearing expired tokens
Kim Alvefur <zash@zash.se>
parents: 13276
diff changeset
170 local found_expired = false
13272
8535a6105919 mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents: 13271
diff changeset
171 for secret_hash, token_info in pairs(grant.tokens) do
13638
94462d8f2fa9 mod_tokenauth: Fix expiry lasting one second too much
Rémi Bardon <remi@remibardon.name>
parents: 13356
diff changeset
172 if token_info.expires and token_info.expires <= now then
13321
19c814d4dd3a mod_tokenauth: Include more details in debug logs
Kim Alvefur <zash@zash.se>
parents: 13305
diff changeset
173 module:log("debug", "Token %s of grant %s of %s has expired, cleaning it up", secret_hash:sub(-8), grant.id, username);
13272
8535a6105919 mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents: 13271
diff changeset
174 grant.tokens[secret_hash] = nil;
13275
5db61e0dfc62 mod_tokenauth: Save grant after removing expired tokens
Kim Alvefur <zash@zash.se>
parents: 13274
diff changeset
175 found_expired = true;
5db61e0dfc62 mod_tokenauth: Save grant after removing expired tokens
Kim Alvefur <zash@zash.se>
parents: 13274
diff changeset
176 end
13272
8535a6105919 mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents: 13271
diff changeset
177 end
13273
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
diff changeset
178
13638
94462d8f2fa9 mod_tokenauth: Fix expiry lasting one second too much
Rémi Bardon <remi@remibardon.name>
parents: 13356
diff changeset
179 if not grant.expires and next(grant.tokens) == nil and grant.accessed + empty_grant_lifetime <= now then
13321
19c814d4dd3a mod_tokenauth: Include more details in debug logs
Kim Alvefur <zash@zash.se>
parents: 13305
diff changeset
180 module:log("debug", "Token %s of %s grant has no tokens, discarding", grant.id, username);
13273
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
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: 13272
diff changeset
182 return nil, "expired";
13305
852a61c720d0 mod_tokenauth: Fix saving grants after clearing expired tokens
Kim Alvefur <zash@zash.se>
parents: 13276
diff changeset
183 elseif found_expired then
852a61c720d0 mod_tokenauth: Fix saving grants after clearing expired tokens
Kim Alvefur <zash@zash.se>
parents: 13276
diff changeset
184 token_store:set_key(username, grant.id, grant);
13273
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
diff changeset
185 end
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
diff changeset
186
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
187 return grant;
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
188 end
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
189
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
190 local function _get_validated_token_info(token_id, token_user, token_host, token_secret)
10668
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
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
196 if not grant or not grant.tokens then
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 if err then
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
198 module:log("error", "Unable to read from token storage: %s", err);
10668
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
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
201 module:log("warn", "Invalid token in storage (%s / %s)", token_user, token_id);
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
202 return nil, "not-authorized";
10668
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
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
205 -- Check provided secret
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
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: 12997
diff changeset
208 if not token_info then
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
210 return nil, "not-authorized";
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
211 end
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
212
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
213 -- Check expiry
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
214 local now = os.time();
13638
94462d8f2fa9 mod_tokenauth: Fix expiry lasting one second too much
Rémi Bardon <remi@remibardon.name>
parents: 13356
diff changeset
215 if token_info.expires and token_info.expires <= now then
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
217 grant.tokens[secret_hash] = nil;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
218 token_store:set_key(token_user, token_id, grant);
10668
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
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
222 -- Verify grant validity (expiry, etc.)
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
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: 13006
diff changeset
224 if not grant then
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
225 return nil, "not-authorized";
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
226 end
12742
126aefd2c4c6 mod_tokenauth: Invalidate tokens issued before most recent password change
Matthew Wild <mwild1@gmail.com>
parents: 12662
diff changeset
227
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
229 local last_accessed = grant.accessed;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
diff changeset
231 grant.accessed = now;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
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: 12997
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: 12997
diff changeset
234 end
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
235
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
236 token_info.id = token_id;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
237 token_info.grant = grant;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
238 token_info.jid = grant.jid;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
239
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
240 return token_info;
10668
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
13010
3e454af3615d mod_tokenauth: Add API to inspect individual grants or all of a user's grants
Matthew Wild <mwild1@gmail.com>
parents: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
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: 13009
diff changeset
260 end
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
261
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
262 function get_token_info(token)
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
263 local token_id, token_user, token_host, token_secret = parse_token(token);
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
264 if not token_id then
12952
a668bc1aa39d mod_tokenauth: Log error when token validation fails
Matthew Wild <mwild1@gmail.com>
parents: 12938
diff changeset
265 module:log("warn", "Failed to verify access token: %s", token_user);
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
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: 10675
diff changeset
267 end
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
268 return _get_validated_token_info(token_id, token_user, token_host, token_secret);
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
269 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
270
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
271 function get_token_session(token, resource)
12959
e331210beeb2 mod_tokenauth: Fix traceback in get_token_session()
Kim Alvefur <zash@zash.se>
parents: 12953
diff changeset
272 local token_id, token_user, token_host, token_secret = parse_token(token);
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
273 if not token_id then
12952
a668bc1aa39d mod_tokenauth: Log error when token validation fails
Matthew Wild <mwild1@gmail.com>
parents: 12938
diff changeset
274 module:log("warn", "Failed to verify access token: %s", token_user);
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
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: 10675
diff changeset
276 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
277
12959
e331210beeb2 mod_tokenauth: Fix traceback in get_token_session()
Kim Alvefur <zash@zash.se>
parents: 12953
diff changeset
278 local token_info, err = _get_validated_token_info(token_id, token_user, token_host, token_secret);
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
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: 10675
diff changeset
280
13098
65d2ff6e674e mod_tokenauth: Return error instead of session for token without role
Kim Alvefur <zash@zash.se>
parents: 13074
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: 13074
diff changeset
282 if not role then return nil, "not-authorized"; end
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
283 return {
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
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: 10675
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: 10675
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: 10675
diff changeset
287
13098
65d2ff6e674e mod_tokenauth: Return error instead of session for token without role
Kim Alvefur <zash@zash.se>
parents: 13074
diff changeset
288 role = role;
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
289 };
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
290 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
291
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
292 function revoke_token(token)
13246
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
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: 13209
diff changeset
294 if not grant_id then
12952
a668bc1aa39d mod_tokenauth: Log error when token validation fails
Matthew Wild <mwild1@gmail.com>
parents: 12938
diff changeset
295 module:log("warn", "Failed to verify access token: %s", token_user);
10668
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
13246
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
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: 13209
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: 13209
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: 13209
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: 13209
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: 13209
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: 13209
diff changeset
307 end
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
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: 13209
diff changeset
309 local ok, err = token_store:set_key(token_user, grant_id, grant);
13003
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
310 if not ok then
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
311 return nil, err;
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
312 end
13246
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
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: 13209
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: 13209
diff changeset
315 grant = grant;
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
316 info = token_info;
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
317 username = token_user;
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
318 host = token_host;
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
319 });
13003
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
320 return true;
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
321 end
12915
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
diff changeset
322
13024
7558fd152459 mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents: 13010
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: 13010
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: 13010
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: 13010
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: 13010
diff changeset
327 return true;
7558fd152459 mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents: 13010
diff changeset
328 end
7558fd152459 mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents: 13010
diff changeset
329
12915
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
diff changeset
330 function sasl_handler(auth_provider, purpose, extra)
12938
055b03d3059b util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents: 12919
diff changeset
331 return function (sasl, token, realm, _authzid)
12915
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
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: 12914
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: 12914
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: 12914
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: 12914
diff changeset
336 end
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
337 local token_user, token_host, resource = jid.split(token_info.grant.jid);
12938
055b03d3059b util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents: 12919
diff changeset
338 if realm ~= token_host or (purpose and token_info.purpose ~= purpose) then
12915
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
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: 12914
diff changeset
340 end
12938
055b03d3059b util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents: 12919
diff changeset
341 if auth_provider.is_enabled and not auth_provider.is_enabled(token_user) then
12915
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
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: 12914
diff changeset
343 end
12938
055b03d3059b util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents: 12919
diff changeset
344 sasl.resource = resource;
055b03d3059b util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents: 12919
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: 12919
diff changeset
346 return token_user, true, token_info;
12915
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
diff changeset
347 end;
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
diff changeset
348 end
13274
ddfe07041fc5 mod_tokenauth: Periodically clear out expired tokens and grants
Kim Alvefur <zash@zash.se>
parents: 13273
diff changeset
349
13276
c34266c061c9 mod_tokenauth: Set name/description on cleanup job
Kim Alvefur <zash@zash.se>
parents: 13275
diff changeset
350 module:daily("clear expired grants", function()
13274
ddfe07041fc5 mod_tokenauth: Periodically clear out expired tokens and grants
Kim Alvefur <zash@zash.se>
parents: 13273
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: 13273
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: 13273
diff changeset
353 end
ddfe07041fc5 mod_tokenauth: Periodically clear out expired tokens and grants
Kim Alvefur <zash@zash.se>
parents: 13273
diff changeset
354 end)