lib/rodauth/features/oauth.rb in rodauth-oauth-0.3.0 vs lib/rodauth/features/oauth.rb in rodauth-oauth-0.4.0

- old
+ new

@@ -82,10 +82,11 @@ auth_value_method :use_oauth_pkce?, true auth_value_method :use_oauth_access_type?, true auth_value_method :oauth_require_pkce, false auth_value_method :oauth_pkce_challenge_method, "S256" + auth_value_method :oauth_response_mode, "query" auth_value_method :oauth_valid_uri_schemes, %w[https] auth_value_method :oauth_scope_separator, " " @@ -98,10 +99,11 @@ translatable_method :"#{param}_label", param.gsub("_", " ").capitalize end button "Register", "oauth_application" button "Authorize", "oauth_authorize" button "Revoke", "oauth_token_revoke" + button "Back to Client Application", "oauth_authorize_post" # OAuth Token auth_value_method :oauth_tokens_path, "oauth-tokens" auth_value_method :oauth_tokens_table, :oauth_tokens auth_value_method :oauth_tokens_id_column, :id @@ -311,15 +313,45 @@ end r.post do redirect_url = URI.parse(redirect_uri) - transaction do + params, mode = transaction do before_authorize - do_authorize(redirect_url) + do_authorize end - redirect(redirect_url.to_s) + + case mode + when "query" + params = params.map { |k, v| "#{k}=#{v}" } + params << redirect_url.query if redirect_url.query + redirect_url.query = params.join("&") + redirect(redirect_url.to_s) + when "fragment" + params = params.map { |k, v| "#{k}=#{v}" } + params << redirect_url.query if redirect_url.query + redirect_url.fragment = params.join("&") + redirect(redirect_url.to_s) + when "form_post" + scope.view layout: false, inline: <<-FORM + <html> + <head><title>Authorized</title></head> + <body onload="javascript:document.forms[0].submit()"> + <form method="post" action="#{redirect_uri}"> + #{ + params.map do |name, value| + "<input type=\"hidden\" name=\"#{name}\" value=\"#{scope.h(value)}\" />" + end.join + } + <input type="submit" class="btn btn-outline-primary" value="#{scope.h(oauth_authorize_post_button)}"/> + </form> + </body> + </html> + FORM + when "none" + redirect(redirect_url.to_s) + end end end def oauth_server_metadata(issuer = nil) request.on(".well-known") do @@ -846,10 +878,13 @@ check_valid_approval_prompt? && check_valid_response_type? redirect_response_error("invalid_request") end redirect_response_error("invalid_scope") unless check_valid_scopes? + if (response_mode = param_or_nil("response_mode")) && response_mode != "form_post" + redirect_response_error("invalid_request") + end validate_pkce_challenge_params if use_oauth_pkce? end def try_approval_prompt approval_prompt = param_or_nil("approval_prompt") @@ -897,32 +932,30 @@ __insert_and_return__(ds, oauth_grants_id_column, create_params) end create_params[oauth_grants_code_column] end - def do_authorize(redirect_url, query_params = [], fragment_params = []) + def do_authorize(response_params = {}, response_mode = param_or_nil("response_mode")) case param("response_type") when "token" redirect_response_error("invalid_request") unless use_oauth_implicit_grant_type? - fragment_params.replace(_do_authorize_token.map { |k, v| "#{k}=#{v}" }) - when "code", "", nil - query_params.replace(_do_authorize_code.map { |k, v| "#{k}=#{v}" }) + response_mode ||= "fragment" + response_params.replace(_do_authorize_token) + when "code" + response_mode ||= "query" + response_params.replace(_do_authorize_code) + when "none" + response_mode ||= "none" + when "", nil + response_mode ||= oauth_response_mode + response_params.replace(_do_authorize_code) end - if param_or_nil("state") - if !fragment_params.empty? - fragment_params << "state=#{param('state')}" - else - query_params << "state=#{param('state')}" - end - end + response_params["state"] = param("state") if param_or_nil("state") - query_params << redirect_url.query if redirect_url.query - - redirect_url.query = query_params.join("&") unless query_params.empty? - redirect_url.fragment = fragment_params.join("&") unless fragment_params.empty? + [response_params, response_mode] end def _do_authorize_code { "code" => create_oauth_grant } end @@ -1294,10 +1327,10 @@ def oauth_server_metadata_body(path) issuer = base_url issuer += "/#{path}" if path responses_supported = %w[code] - response_modes_supported = %w[query] + response_modes_supported = %w[query form_post] grant_types_supported = %w[authorization_code] if use_oauth_implicit_grant_type? responses_supported << "token" response_modes_supported << "fragment"