lib/rodauth/features/oauth_base.rb in rodauth-oauth-1.0.0.pre.beta1 vs lib/rodauth/features/oauth_base.rb in rodauth-oauth-1.0.0.pre.beta2

- old
+ new

@@ -1,10 +1,11 @@ # frozen_string_literal: true require "time" require "base64" require "securerandom" +require "cgi" require "rodauth/version" require "rodauth/oauth" require "rodauth/oauth/database_extensions" require "rodauth/oauth/http_extensions" @@ -15,12 +16,10 @@ EMPTY_HASH = {}.freeze auth_value_methods(:http_request) auth_value_methods(:http_request_cache) - SCOPES = %w[profile.read].freeze - before "token" error_flash "Please authorize to continue", "require_authorization" error_flash "You are not authorized to revoke this token", "revoke_unauthorized_account" @@ -80,11 +79,11 @@ auth_value_method :oauth_authorization_required_error_status, 401 auth_value_method :oauth_invalid_response_status, 400 auth_value_method :oauth_already_in_use_response_status, 409 # Feature options - auth_value_method :oauth_application_scopes, SCOPES + auth_value_method :oauth_application_scopes, [] auth_value_method :oauth_token_type, "bearer" auth_value_method :oauth_refresh_token_protection_policy, "rotation" # can be: none, sender_constrained, rotation translatable_method :oauth_invalid_client_message, "Invalid client" translatable_method :oauth_invalid_grant_type_message, "Invalid grant type" @@ -226,32 +225,39 @@ db[oauth_applications_table].filter(oauth_applications_client_id_column => client_id).first end end def fetch_access_token - value = request.env["HTTP_AUTHORIZATION"] + if (token = request.params["access_token"]) + if request.post? && !(request.content_type.start_with?("application/x-www-form-urlencoded") && + request.params.size == 1) + return + end + else + value = request.env["HTTP_AUTHORIZATION"] - return unless value && !value.empty? + return unless value && !value.empty? - scheme, token = value.split(" ", 2) + scheme, token = value.split(" ", 2) - return unless scheme.downcase == oauth_token_type + return unless scheme.downcase == oauth_token_type + end return if token.nil? || token.empty? token end def authorization_token return @authorization_token if defined?(@authorization_token) # check if there is a token - bearer_token = fetch_access_token + access_token = fetch_access_token - return unless bearer_token + return unless access_token - @authorization_token = oauth_grant_by_token(bearer_token) + @authorization_token = oauth_grant_by_token(access_token) end def require_oauth_authorization(*scopes) authorization_required unless authorization_token @@ -756,26 +762,35 @@ else redirect_url = URI.parse(redirect_url) query_params = [] query_params << if respond_to?(:"oauth_#{error_code}_error_code") - "error=#{send(:"oauth_#{error_code}_error_code")}" + ["error", send(:"oauth_#{error_code}_error_code")] else - "error=#{error_code}" + ["error", error_code] end if respond_to?(:"oauth_#{error_code}_message") message = send(:"oauth_#{error_code}_message") - query_params << ["error_description=#{CGI.escape(message)}"] + query_params << ["error_description", CGI.escape(message)] end - query_params << redirect_url.query if redirect_url.query - redirect_url.query = query_params.join("&") - redirect(redirect_url.to_s) + state = param_or_nil("state") + + query_params << ["state", state] if state + + _redirect_response_error(redirect_url, query_params) end end + def _redirect_response_error(redirect_url, query_params) + query_params = query_params.map { |k, v| "#{k}=#{v}" } + query_params << redirect_url.query if redirect_url.query + redirect_url.query = query_params.join("&") + redirect(redirect_url.to_s) + end + def json_response_success(body, cache = false) response.status = 200 response["Content-Type"] ||= json_response_content_type if cache # defaulting to 1-day for everyone, for now at least @@ -831,9 +846,13 @@ (scopes - oauth_application[oauth_applications_scopes_column].split(oauth_scope_separator)).empty? end def check_valid_uri?(uri) URI::DEFAULT_PARSER.make_regexp(oauth_valid_uri_schemes).match?(uri) + end + + def check_valid_no_fragment_uri?(uri) + check_valid_uri?(uri) && URI.parse(uri).fragment.nil? end # Resource server mode def authorization_server_metadata