mod_http_oauth2/mod_http_oauth2.lua
changeset 5517 0005d4201030
parent 5516 1fbc8718bed6
child 5518 61b8d3eb91a4
equal deleted inserted replaced
5516:1fbc8718bed6 5517:0005d4201030
    26 	return function(k)
    26 	return function(k)
    27 		return t[k];
    27 		return t[k];
    28 	end
    28 	end
    29 end
    29 end
    30 
    30 
       
    31 local function strict_formdecode(query)
       
    32 	if not query then
       
    33 		return nil;
       
    34 	end
       
    35 	local params = http.formdecode(query);
       
    36 	if type(params) ~= "table" then
       
    37 		return nil, "no-pairs";
       
    38 	end
       
    39 	local dups = {};
       
    40 	for _, pair in ipairs(params) do
       
    41 		if dups[pair.name] then
       
    42 			return nil, "duplicate";
       
    43 		end
       
    44 		dups[pair.name] = true;
       
    45 	end
       
    46 	return params;
       
    47 end
       
    48 
    31 local function read_file(base_path, fn, required)
    49 local function read_file(base_path, fn, required)
    32 	local f, err = io.open(base_path .. "/" .. fn);
    50 	local f, err = io.open(base_path .. "/" .. fn);
    33 	if not f then
    51 	if not f then
    34 		module:log(required and "error" or "debug", "Unable to load template file: %s", err);
    52 		module:log(required and "error" or "debug", "Unable to load template file: %s", err);
    35 		if required then
    53 		if required then
   368 		return oauth_error("invalid_redirect_uri");
   386 		return oauth_error("invalid_redirect_uri");
   369 	end
   387 	end
   370 
   388 
   371 	local redirect = url.parse(redirect_uri);
   389 	local redirect = url.parse(redirect_uri);
   372 
   390 
   373 	local query = http.formdecode(redirect.query or "");
   391 	local query = strict_formdecode(redirect.query);
   374 	if type(query) ~= "table" then query = {}; end
   392 	if type(query) ~= "table" then query = {}; end
   375 	table.insert(query, { name = "code", value = code });
   393 	table.insert(query, { name = "code", value = code });
   376 	table.insert(query, { name = "iss", value = get_issuer() });
   394 	table.insert(query, { name = "iss", value = get_issuer() });
   377 	if params.state then
   395 	if params.state then
   378 		table.insert(query, { name = "state", value = params.state });
   396 		table.insert(query, { name = "state", value = params.state });
   531 local function get_auth_state(request)
   549 local function get_auth_state(request)
   532 	local form = request.method == "POST"
   550 	local form = request.method == "POST"
   533 	         and request.body
   551 	         and request.body
   534 	         and request.body ~= ""
   552 	         and request.body ~= ""
   535 	         and request.headers.content_type == "application/x-www-form-urlencoded"
   553 	         and request.headers.content_type == "application/x-www-form-urlencoded"
   536 	         and http.formdecode(request.body);
   554 	         and strict_formdecode(request.body);
   537 
   555 
   538 	if type(form) ~= "table" then return {}; end
   556 	if type(form) ~= "table" then return {}; end
   539 
   557 
   540 	if not form.user_token then
   558 	if not form.user_token then
   541 		-- First step: login
   559 		-- First step: login
   641 -- error directly to the user-agent.
   659 -- error directly to the user-agent.
   642 local function error_response(request, redirect_uri, err)
   660 local function error_response(request, redirect_uri, err)
   643 	if not redirect_uri or redirect_uri == oob_uri then
   661 	if not redirect_uri or redirect_uri == oob_uri then
   644 		return render_error(err);
   662 		return render_error(err);
   645 	end
   663 	end
   646 	local q = request.url.query and http.formdecode(request.url.query);
   664 	local q = strict_formdecode(request.url.query);
   647 	local redirect_query = url.parse(redirect_uri);
   665 	local redirect_query = url.parse(redirect_uri);
   648 	local sep = redirect_query.query and "&" or "?";
   666 	local sep = redirect_query.query and "&" or "?";
   649 	redirect_uri = redirect_uri
   667 	redirect_uri = redirect_uri
   650 		.. sep .. http.formencode(err.extra.oauth2_response)
   668 		.. sep .. http.formencode(err.extra.oauth2_response)
   651 		.. "&" .. http.formencode({ state = q.state, iss = get_issuer() });
   669 		.. "&" .. http.formencode({ state = q.state, iss = get_issuer() });
   695 	local credentials = get_request_credentials(event.request);
   713 	local credentials = get_request_credentials(event.request);
   696 
   714 
   697 	event.response.headers.content_type = "application/json";
   715 	event.response.headers.content_type = "application/json";
   698 	event.response.headers.cache_control = "no-store";
   716 	event.response.headers.cache_control = "no-store";
   699 	event.response.headers.pragma = "no-cache";
   717 	event.response.headers.pragma = "no-cache";
   700 	local params = http.formdecode(event.request.body);
   718 	local params = strict_formdecode(event.request.body);
   701 	if not params then
   719 	if not params then
   702 		return oauth_error("invalid_request");
   720 		return oauth_error("invalid_request");
   703 	end
   721 	end
   704 
   722 
   705 	if credentials and credentials.type == "basic" then
   723 	if credentials and credentials.type == "basic" then
   721 
   739 
   722 	-- Directly returning errors to the user before we have a validated client object
   740 	-- Directly returning errors to the user before we have a validated client object
   723 	if not request.url.query then
   741 	if not request.url.query then
   724 		return render_error(oauth_error("invalid_request", "Missing query parameters"));
   742 		return render_error(oauth_error("invalid_request", "Missing query parameters"));
   725 	end
   743 	end
   726 	local params = http.formdecode(request.url.query);
   744 	local params = strict_formdecode(request.url.query);
   727 	if not params then
   745 	if not params then
   728 		return render_error(oauth_error("invalid_request", "Invalid query parameters"));
   746 		return render_error(oauth_error("invalid_request", "Invalid query parameters"));
   729 	end
   747 	end
   730 
   748 
   731 	if not params.client_id then
   749 	if not params.client_id then
   823 		if not verify_client_secret(credentials.username, credentials.password) then
   841 		if not verify_client_secret(credentials.username, credentials.password) then
   824 			return 401;
   842 			return 401;
   825 		end
   843 		end
   826 	end
   844 	end
   827 
   845 
   828 	local form_data = http.formdecode(event.request.body or "");
   846 	local form_data = strict_formdecode(event.request.body);
   829 	if not form_data or not form_data.token then
   847 	if not form_data or not form_data.token then
   830 		response.headers.accept = "application/x-www-form-urlencoded";
   848 		response.headers.accept = "application/x-www-form-urlencoded";
   831 		return 415;
   849 		return 415;
   832 	end
   850 	end
   833 	local ok, err = tokens.revoke_token(form_data.token);
   851 	local ok, err = tokens.revoke_token(form_data.token);