comparison mod_http_oauth2/mod_http_oauth2.lua @ 4271:9623b99bb8d2

mod_http_oauth2: Keep authorization codes in memory instead of storage Seems excessive to have them in persistent storage for such a short time. Prevents them from leaking in case they never get cashed out.
author Kim Alvefur <zash@zash.se>
date Sun, 22 Nov 2020 18:49:31 +0100
parents 243f7b0dbf35
children 91b951fb3018
comparison
equal deleted inserted replaced
4270:243f7b0dbf35 4271:9623b99bb8d2
1 local hashes = require "util.hashes"; 1 local hashes = require "util.hashes";
2 local cache = require "util.cache";
2 local http = require "util.http"; 3 local http = require "util.http";
3 local jid = require "util.jid"; 4 local jid = require "util.jid";
4 local json = require "util.json"; 5 local json = require "util.json";
5 local usermanager = require "core.usermanager"; 6 local usermanager = require "core.usermanager";
6 local errors = require "util.error"; 7 local errors = require "util.error";
10 local base64 = encodings.base64; 11 local base64 = encodings.base64;
11 12
12 local tokens = module:depends("tokenauth"); 13 local tokens = module:depends("tokenauth");
13 14
14 local clients = module:open_store("oauth2_clients", "map"); 15 local clients = module:open_store("oauth2_clients", "map");
15 local codes = module:open_store("oauth2_codes", "map");
16 16
17 local function code_expired(code) 17 local function code_expired(code)
18 return os.difftime(os.time(), code.issued) > 120; 18 return os.difftime(os.time(), code.issued) > 120;
19 end 19 end
20
21 local codes = cache.new(10000, function (_, code)
22 return code_expired(code)
23 end);
20 24
21 local function oauth_error(err_name, err_desc) 25 local function oauth_error(err_name, err_desc)
22 return errors.new({ 26 return errors.new({
23 type = "modify"; 27 type = "modify";
24 condition = "bad-request"; 28 condition = "bad-request";
74 if not client then 78 if not client then
75 return oauth_error("invalid_client", "incorrect credentials"); 79 return oauth_error("invalid_client", "incorrect credentials");
76 end 80 end
77 81
78 local code = uuid.generate(); 82 local code = uuid.generate();
79 assert(codes:set(client_owner, client_id .. "#" .. code, {issued = os.time(); granted_jid = granted_jid})); 83 assert(codes:set(params.client_id .. "#" .. code, {issued = os.time(); granted_jid = granted_jid}));
80 84
81 local redirect = url.parse(params.redirect_uri); 85 local redirect = url.parse(params.redirect_uri);
82 local query = http.formdecode(redirect.query or ""); 86 local query = http.formdecode(redirect.query or "");
83 if type(query) ~= "table" then query = {}; end 87 if type(query) ~= "table" then query = {}; end
84 table.insert(query, { name = "code", value = code }) 88 table.insert(query, { name = "code", value = code })
118 if err then error(err); end 122 if err then error(err); end
119 if not client or not verify_secret(client.secret_hash, client.salt, client.iteration_count, params.client_secret) then 123 if not client or not verify_secret(client.secret_hash, client.salt, client.iteration_count, params.client_secret) then
120 module:log("debug", "client_secret mismatch"); 124 module:log("debug", "client_secret mismatch");
121 return oauth_error("invalid_client", "incorrect credentials"); 125 return oauth_error("invalid_client", "incorrect credentials");
122 end 126 end
123 local code, err = codes:get(client_owner, client_id .. "#" .. params.code); 127 local code, err = codes:get(params.client_id .. "#" .. params.code);
124 if err then error(err); end 128 if err then error(err); end
125 if not code or type(code) ~= "table" or code_expired(code) then 129 if not code or type(code) ~= "table" or code_expired(code) then
126 module:log("debug", "authorization_code invalid or expired: %q", code); 130 module:log("debug", "authorization_code invalid or expired: %q", code);
127 return oauth_error("invalid_client", "incorrect credentials"); 131 return oauth_error("invalid_client", "incorrect credentials");
128 end 132 end