mod_http_oauth2/mod_http_oauth2.lua
changeset 4264 c539334dd01a
parent 4263 721b528c01e1
child 4267 d3af5f94d6df
equal deleted inserted replaced
4263:721b528c01e1 4264:c539334dd01a
     8 local encodings = require "util.encodings";
     8 local encodings = require "util.encodings";
     9 local base64 = encodings.base64;
     9 local base64 = encodings.base64;
    10 
    10 
    11 local tokens = module:depends("tokenauth");
    11 local tokens = module:depends("tokenauth");
    12 
    12 
    13 local clients = module:open_store("oauth2_clients");
    13 local clients = module:open_store("oauth2_clients", "map");
    14 local codes = module:open_store("oauth2_codes", "map");
    14 local codes = module:open_store("oauth2_codes", "map");
    15 
    15 
    16 local function oauth_error(err_name, err_desc)
    16 local function oauth_error(err_name, err_desc)
    17 	return errors.new({
    17 	return errors.new({
    18 		type = "modify";
    18 		type = "modify";
    58 	if not params.redirect_uri then return oauth_error("invalid_request", "missing 'redirect_uri'"); end
    58 	if not params.redirect_uri then return oauth_error("invalid_request", "missing 'redirect_uri'"); end
    59 	if params.scope and params.scope ~= "" then
    59 	if params.scope and params.scope ~= "" then
    60 		return oauth_error("invalid_scope", "unknown scope requested");
    60 		return oauth_error("invalid_scope", "unknown scope requested");
    61 	end
    61 	end
    62 
    62 
    63 	local client, err = clients:get(params.client_id);
    63 	local client_owner, client_host, client_id = jid.prepped_split(params.client_id);
    64 	module:log("debug", "clients:get(%q) --> %q, %q", params.client_id, client, err);
    64 	if client_host ~= module.host then
       
    65 		return oauth_error("invalid_client", "incorrect credentials");
       
    66 	end
       
    67 	local client, err = clients:get(client_owner, client_id);
    65 	if err then error(err); end
    68 	if err then error(err); end
    66 	if not client then
    69 	if not client then
    67 		return oauth_error("invalid_client", "incorrect credentials");
    70 		return oauth_error("invalid_client", "incorrect credentials");
    68 	end
    71 	end
    69 
    72 
    70 	local code = uuid.generate();
    73 	local code = uuid.generate();
    71 	assert(codes:set(params.client_id, code, { issued = os.time(), granted_jid = granted_jid, }));
    74 	assert(codes:set(client_owner, client_id .. "#" .. code, {issued = os.time(); granted_jid = granted_jid}));
    72 
    75 
    73 	local redirect = url.parse(params.redirect_uri);
    76 	local redirect = url.parse(params.redirect_uri);
    74 	local query = http.formdecode(redirect.query or "");
    77 	local query = http.formdecode(redirect.query or "");
    75 	if type(query) ~= "table" then query = {}; end
    78 	if type(query) ~= "table" then query = {}; end
    76 	table.insert(query, { name = "code", value = code })
    79 	table.insert(query, { name = "code", value = code })
    93 	if not params.code then return oauth_error("invalid_request", "missing 'code'"); end
    96 	if not params.code then return oauth_error("invalid_request", "missing 'code'"); end
    94 	if params.scope and params.scope ~= "" then
    97 	if params.scope and params.scope ~= "" then
    95 		return oauth_error("invalid_scope", "unknown scope requested");
    98 		return oauth_error("invalid_scope", "unknown scope requested");
    96 	end
    99 	end
    97 
   100 
    98 	local client, err = clients:get(params.client_id);
   101 	local client_owner, client_host, client_id = jid.prepped_split(params.client_id);
       
   102 	if client_host ~= module.host then
       
   103 		module:log("debug", "%q ~= %q", client_host, module.host);
       
   104 		return oauth_error("invalid_client", "incorrect credentials");
       
   105 	end
       
   106 	local client, err = clients:get(client_owner, client_id);
    99 	if err then error(err); end
   107 	if err then error(err); end
   100 	if not client or client.secret ~= params.client_secret then
   108 	if not client or client.client_secret ~= params.client_secret then
   101 		return oauth_error("invalid_client", "incorrect credentials");
   109 		module:log("debug", "client_secret mismatch");
   102 	end
   110 		return oauth_error("invalid_client", "incorrect credentials");
   103 	local code, err = codes:get(params.client_id, params.code);
   111 	end
       
   112 	local code, err = codes:get(client_owner, client_id .. "#" .. params.code);
   104 	if err then error(err); end
   113 	if err then error(err); end
   105 	if not code or type(code) ~= "table" or os.difftime(os.time(), code.issued) > 900 then
   114 	if not code or type(code) ~= "table" or os.difftime(os.time(), code.issued) > 900 then
   106 		return oauth_error("invalid_client", "incorrect credentials");
   115 		module:log("debug", "authorization_code invalid or expired: %q", code);
   107 	end
   116 		return oauth_error("invalid_client", "incorrect credentials");
   108 	assert(codes:set(params.client_id, params.code, nil));
   117 	end
   109 
   118 	assert(codes:set(client_owner, client_id .. "#" .. params.code, nil));
   110 
   119 
   111 	return json.encode(new_access_token(code.granted_jid, nil, nil));
   120 	return json.encode(new_access_token(code.granted_jid, nil, nil));
   112 end
   121 end
   113 
   122 
   114 local function check_credentials(request)
   123 local function check_credentials(request)