mod_http_oauth2/mod_http_oauth2.lua
changeset 4275 9623b99bb8d2
parent 4274 243f7b0dbf35
child 4276 91b951fb3018
equal deleted inserted replaced
4274:243f7b0dbf35 4275: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