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"