Software / code / prosody-modules
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 |