Changeset

6307:aae94f82c56e

mod_http_oauth2: Refactor to return all errors to Device clients Previously only a single case was returned to device clients, now all error conditions that pass trough the error_response() are covered.
author Kim Alvefur <zash@zash.se>
date Fri, 13 Jun 2025 21:30:56 +0200
parents 6306:fe0a58b863db
children 6308:e1c54de06905
files mod_http_oauth2/mod_http_oauth2.lua
diffstat 1 files changed, 14 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/mod_http_oauth2/mod_http_oauth2.lua	Fri Jun 13 12:52:28 2025 +0200
+++ b/mod_http_oauth2/mod_http_oauth2.lua	Fri Jun 13 21:30:56 2025 +0200
@@ -787,15 +787,26 @@
 -- the redirect_uri is missing or invalid. In those cases, we render an
 -- error directly to the user-agent.
 local function error_response(request, redirect_uri, err)
-	if not redirect_uri or redirect_uri == oob_uri or redirect_uri == device_uri then
+	if not redirect_uri or redirect_uri == oob_uri then
 		return render_error(err);
 	end
-	local q = strict_formdecode(request.url.query);
+	local params = strict_formdecode(request.url.query);
+	if redirect_uri == device_uri then
+		local is_device, device_state = verify_device_token(params.state);
+		if is_device then
+			local device_code = b64url(hashes.hmac_sha256(verification_key, device_state.user_code));
+			local code = codes:get("device_code:" .. params.client_id .. "#" .. device_code);
+			code.error = err;
+			code.expires = os.time() + 60;
+			codes:set("device_code:" .. params.client_id .. "#" .. device_code, code);
+		end
+		return render_error(err);
+	end
 	local redirect_query = url.parse(redirect_uri);
 	local sep = redirect_query.query and "&" or "?";
 	redirect_uri = redirect_uri
 		.. sep .. http.formencode(err.extra.oauth2_response)
-		.. "&" .. http.formencode({ state = q.state, iss = get_issuer() });
+		.. "&" .. http.formencode({ state = params.state, iss = get_issuer() });
 	module:log("debug", "Sending error response to client via redirect to %s", redirect_uri);
 	return {
 		status_code = 303;
@@ -1002,16 +1013,6 @@
 		end
 	elseif not auth_state.consent then
 		-- Notify client of rejection
-		if redirect_uri == device_uri then
-			local is_device, device_state = verify_device_token(params.state);
-			if is_device then
-				local device_code = b64url(hashes.hmac_sha256(verification_key, device_state.user_code));
-				local code = codes:get("device_code:" .. params.client_id .. "#" .. device_code);
-				code.error = oauth_error("access_denied");
-				code.expires = os.time() + 60;
-				codes:set("device_code:" .. params.client_id .. "#" .. device_code, code);
-			end
-		end
 		return error_response(request, redirect_uri, oauth_error("access_denied"));
 	end
 	-- else auth_state.consent == true