Comparison

mod_http_oauth2/mod_http_oauth2.lua @ 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
parent 6292:28fd42866be9
child 6308:e1c54de06905
comparison
equal deleted inserted replaced
6306:fe0a58b863db 6307:aae94f82c56e
785 -- appending the error information to the redirect_uri and sending the 785 -- appending the error information to the redirect_uri and sending the
786 -- redirect to the user-agent. In some cases we can't do this, e.g. if 786 -- redirect to the user-agent. In some cases we can't do this, e.g. if
787 -- the redirect_uri is missing or invalid. In those cases, we render an 787 -- the redirect_uri is missing or invalid. In those cases, we render an
788 -- error directly to the user-agent. 788 -- error directly to the user-agent.
789 local function error_response(request, redirect_uri, err) 789 local function error_response(request, redirect_uri, err)
790 if not redirect_uri or redirect_uri == oob_uri or redirect_uri == device_uri then 790 if not redirect_uri or redirect_uri == oob_uri then
791 return render_error(err); 791 return render_error(err);
792 end 792 end
793 local q = strict_formdecode(request.url.query); 793 local params = strict_formdecode(request.url.query);
794 if redirect_uri == device_uri then
795 local is_device, device_state = verify_device_token(params.state);
796 if is_device then
797 local device_code = b64url(hashes.hmac_sha256(verification_key, device_state.user_code));
798 local code = codes:get("device_code:" .. params.client_id .. "#" .. device_code);
799 code.error = err;
800 code.expires = os.time() + 60;
801 codes:set("device_code:" .. params.client_id .. "#" .. device_code, code);
802 end
803 return render_error(err);
804 end
794 local redirect_query = url.parse(redirect_uri); 805 local redirect_query = url.parse(redirect_uri);
795 local sep = redirect_query.query and "&" or "?"; 806 local sep = redirect_query.query and "&" or "?";
796 redirect_uri = redirect_uri 807 redirect_uri = redirect_uri
797 .. sep .. http.formencode(err.extra.oauth2_response) 808 .. sep .. http.formencode(err.extra.oauth2_response)
798 .. "&" .. http.formencode({ state = q.state, iss = get_issuer() }); 809 .. "&" .. http.formencode({ state = params.state, iss = get_issuer() });
799 module:log("debug", "Sending error response to client via redirect to %s", redirect_uri); 810 module:log("debug", "Sending error response to client via redirect to %s", redirect_uri);
800 return { 811 return {
801 status_code = 303; 812 status_code = 303;
802 headers = { 813 headers = {
803 cache_control = "no-store"; 814 cache_control = "no-store";
1000 -- Render consent page 1011 -- Render consent page
1001 return render_page(templates.consent, { state = auth_state; client = client; scopes = scopes+roles }, true); 1012 return render_page(templates.consent, { state = auth_state; client = client; scopes = scopes+roles }, true);
1002 end 1013 end
1003 elseif not auth_state.consent then 1014 elseif not auth_state.consent then
1004 -- Notify client of rejection 1015 -- Notify client of rejection
1005 if redirect_uri == device_uri then
1006 local is_device, device_state = verify_device_token(params.state);
1007 if is_device then
1008 local device_code = b64url(hashes.hmac_sha256(verification_key, device_state.user_code));
1009 local code = codes:get("device_code:" .. params.client_id .. "#" .. device_code);
1010 code.error = oauth_error("access_denied");
1011 code.expires = os.time() + 60;
1012 codes:set("device_code:" .. params.client_id .. "#" .. device_code, code);
1013 end
1014 end
1015 return error_response(request, redirect_uri, oauth_error("access_denied")); 1016 return error_response(request, redirect_uri, oauth_error("access_denied"));
1016 end 1017 end
1017 -- else auth_state.consent == true 1018 -- else auth_state.consent == true
1018 1019
1019 local granted_scopes = auth_state.scopes 1020 local granted_scopes = auth_state.scopes