Annotate

plugins/mod_tokenauth.lua @ 13273:a1c927323f06

mod_tokenauth: Delete grants without tokens after period Generally it is expected that a grant would have at least one token as long as the grant is in active use. Refresh tokens issued by mod_http_oauth2 have a lifetime of one week by default, so the idea here is that if that refresh token expired and another week goes by without the grant being used, then the whole grant can be removed.
author Kim Alvefur <zash@zash.se>
date Mon, 16 Oct 2023 23:51:52 +0200
parent 13272:8535a6105919
child 13274:ddfe07041fc5
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;
c87ac7d1967f mod_tokenauth: Fix traceback when checking expiry of tokens with no expiry
Matthew Wild <mwild1@gmail.com>
parents: 12998
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
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
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: 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
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
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: 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";
13272
8535a6105919 mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents: 13271
diff changeset
158 elseif grant.expires and grant.expires < now then
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
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: 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
56c1d2498d66 mod_tokenauth: Delete grants in the wrong formats on retrieval
Kim Alvefur <zash@zash.se>
parents: 13246
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: 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
13272
8535a6105919 mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents: 13271
diff changeset
169 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: 13271
diff changeset
170 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: 13271
diff changeset
171 module:log("debug", "Token has expired, cleaning it up");
8535a6105919 mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents: 13271
diff changeset
172 grant.tokens[secret_hash] = nil;
8535a6105919 mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents: 13271
diff changeset
173 end
8535a6105919 mod_tokenauth: Clear expired tokens on grant retrieval
Kim Alvefur <zash@zash.se>
parents: 13271
diff changeset
174 end
13273
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
diff changeset
175
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
diff changeset
176 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: 13272
diff changeset
177 module:log("debug", "Token grant has no tokens, discarding");
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
diff changeset
178 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
179 return nil, "expired";
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
diff changeset
180 end
a1c927323f06 mod_tokenauth: Delete grants without tokens after period
Kim Alvefur <zash@zash.se>
parents: 13272
diff changeset
181
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
182 return grant;
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
183 end
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
184
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
185 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
186 if token_host ~= module.host then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187 return nil, "invalid-host";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
190 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
191 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
192 if err then
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
193 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
194 return nil, "internal-error";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 end
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
196 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
197 return nil, "not-authorized";
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
200 -- Check provided secret
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
201 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
202 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
203 if not token_info then
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
204 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
205 return nil, "not-authorized";
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
206 end
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
207
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
208 -- Check expiry
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
209 local now = os.time();
13073
9e5802b45b9e mod_tokenauth: Only check if expiry of expiring tokens
Kim Alvefur <zash@zash.se>
parents: 13024
diff changeset
210 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
211 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
212 grant.tokens[secret_hash] = nil;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
213 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
214 return nil, "not-authorized";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
215 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
216
13009
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
217 -- Verify grant validity (expiry, etc.)
a70ff0c524c9 mod_tokenauth: Move grant validation to a reusable function
Matthew Wild <mwild1@gmail.com>
parents: 13006
diff changeset
218 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
219 if not grant then
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
220 return nil, "not-authorized";
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
221 end
12742
126aefd2c4c6 mod_tokenauth: Invalidate tokens issued before most recent password change
Matthew Wild <mwild1@gmail.com>
parents: 12662
diff changeset
222
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
223 -- 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
224 local last_accessed = grant.accessed;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
225 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
226 grant.accessed = now;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
227 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
228 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
229 end
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
230
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
231 token_info.id = token_id;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
232 token_info.grant = grant;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
233 token_info.jid = grant.jid;
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
234
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
235 return token_info;
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
236 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
237
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
238 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
239 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
240 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
241
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
242 -- 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
243 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
244
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 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
246 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
247
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 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
249 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
250 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
251 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
252 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
253 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
254 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
255 end
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
256
12649
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
257 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
258 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
259 if not token_id then
12952
a668bc1aa39d mod_tokenauth: Log error when token validation fails
Matthew Wild <mwild1@gmail.com>
parents: 12938
diff changeset
260 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
261 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
262 end
12953
ebe3b2f96cad mod_tokenauth: Switch to new token format (invalidates existing tokens!)
Matthew Wild <mwild1@gmail.com>
parents: 12952
diff changeset
263 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
264 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
265
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
266 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
267 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
268 if not token_id then
12952
a668bc1aa39d mod_tokenauth: Log error when token validation fails
Matthew Wild <mwild1@gmail.com>
parents: 12938
diff changeset
269 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
270 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
271 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
272
12959
e331210beeb2 mod_tokenauth: Fix traceback in get_token_session()
Kim Alvefur <zash@zash.se>
parents: 12953
diff changeset
273 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
274 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
275
13098
65d2ff6e674e mod_tokenauth: Return error instead of session for token without role
Kim Alvefur <zash@zash.se>
parents: 13074
diff changeset
276 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
277 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
278 return {
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
279 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
280 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
281 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
282
13098
65d2ff6e674e mod_tokenauth: Return error instead of session for token without role
Kim Alvefur <zash@zash.se>
parents: 13074
diff changeset
283 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
284 };
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
285 end
86e1187f6274 mod_tokenauth: New API that better fits how modules are using token auth
Matthew Wild <mwild1@gmail.com>
parents: 10675
diff changeset
286
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
287 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
288 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
289 if not grant_id then
12952
a668bc1aa39d mod_tokenauth: Log error when token validation fails
Matthew Wild <mwild1@gmail.com>
parents: 12938
diff changeset
290 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
291 return nil, "invalid-token-format";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
292 end
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
293 if token_host ~= module.host then
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
294 return nil, "invalid-host";
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
295 end
13246
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
296 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
297 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
298 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
299 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
300 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
301 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
302 end
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
303 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
304 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
305 if not ok then
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
306 return nil, err;
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
307 end
13246
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
308 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
309 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
310 grant = grant;
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
311 info = token_info;
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
312 username = token_user;
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
313 host = token_host;
2e04d54fb013 mod_tokenauth: Fix revoking a single token without revoking whole grant
Kim Alvefur <zash@zash.se>
parents: 13209
diff changeset
314 });
13003
34ed17ef1c1a mod_tokenauth: Fire events on grant creation and revocation
Matthew Wild <mwild1@gmail.com>
parents: 13000
diff changeset
315 return true;
10668
25c84c0a66fd mod_authtokens: New module for managing auth tokens
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
316 end
12915
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
diff changeset
317
13024
7558fd152459 mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents: 13010
diff changeset
318 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
319 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
320 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
321 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
322 return true;
7558fd152459 mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents: 13010
diff changeset
323 end
7558fd152459 mod_tokenauth: Add API method to revoke a grant by id
Matthew Wild <mwild1@gmail.com>
parents: 13010
diff changeset
324
12915
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
diff changeset
325 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
326 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
327 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
328 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
329 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
330 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
331 end
12998
601d9a375b86 mod_tokenauth: Refactor API to separate tokens and grants
Matthew Wild <mwild1@gmail.com>
parents: 12997
diff changeset
332 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
333 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
334 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
335 end
12938
055b03d3059b util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents: 12919
diff changeset
336 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
337 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
338 end
12938
055b03d3059b util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents: 12919
diff changeset
339 sasl.resource = resource;
055b03d3059b util.sasl.oauthbearer: Return username from callback instead using authzid (BC)
Kim Alvefur <zash@zash.se>
parents: 12919
diff changeset
340 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
341 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
342 end;
70f6a8dceb1d mod_tokenauth: Add SASL handler backend that can accept and verify tokens
Matthew Wild <mwild1@gmail.com>
parents: 12914
diff changeset
343 end