Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* [#2786](https://github.com/ruby-grape/grape/pull/2786): Make route `requirements` and `anchor` explicit keyword arguments and first-class endpoint inputs instead of opaque `route_options` keys - [@ericproulx](https://github.com/ericproulx).
* [#2788](https://github.com/ruby-grape/grape/pull/2788): Compare the base API instead of `to_s` when refreshing a mounted app - [@ericproulx](https://github.com/ericproulx).
* [#2796](https://github.com/ruby-grape/grape/pull/2796): Remove `Grape::Util::ReverseStackableValues`, storing rescue handlers in plain per-scope hashes merged over `InheritableSetting#parent` - [@ericproulx](https://github.com/ericproulx).
* [#2808](https://github.com/ruby-grape/grape/pull/2808): Internalize `build_params_with` and `auth` behind `Grape::Util::InheritableSetting` accessors - [@ericproulx](https://github.com/ericproulx).
* Your contribution here.

#### Fixes
Expand Down
4 changes: 4 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ A route's declared params were previously carried inside the `route_options` bag

Like `params` above, a route's `requirements` and `anchor` were previously carried inside the `route_options` bag. They are now composed into their own endpoint inputs (`Grape::Endpoint::Options` gains `:requirements` and `:anchor` members, and `Grape::Endpoint.new` gains `requirements:` and `anchor:` keywords) and exposed only through the `route.requirements` and `route.anchor` readers. `route.options[:requirements]` and `route.options[:anchor]` now return `nil` — including for a mount's `anchor: false`. Nothing in Grape or grape-swagger read them that way, so this only affects code that reached into the options Hash for these keys directly.

#### `build_params_with` and `auth` are recorded through `InheritableSetting` accessors

The params-builder strategy written by `build_with` (both the API-level and the params-block DSL) and the authentication configuration written by the `auth` DSL are now recorded and read through dedicated accessors on `Grape::Util::InheritableSetting` (`build_params_with` / `build_params_with=`, `auth` / `auth=`) instead of raw `namespace_inheritable` keys, completing the per-key `namespace_inheritable` cleanup. The keys' storage is unchanged for now, so `namespace_inheritable[:build_params_with]` and `namespace_inheritable[:auth]` still return the same values, but they should be considered internal.

### Upgrading to >= 3.3

#### Minimum required Ruby is now 3.3
Expand Down
2 changes: 1 addition & 1 deletion lib/grape/dsl/parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module Parameters
# end
# end
def build_with(build_with)
@api.inheritable_setting.namespace_inheritable[:build_params_with] = build_with
@api.inheritable_setting.build_params_with = build_with
end

# Include reusable params rules among current.
Expand Down
2 changes: 1 addition & 1 deletion lib/grape/dsl/routing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def scope(_name = nil, &block)
end

def build_with(build_with)
inheritable_setting.namespace_inheritable[:build_params_with] = build_with
inheritable_setting.build_params_with = build_with
end

# Do not route HEAD requests to GET requests automatically.
Expand Down
4 changes: 2 additions & 2 deletions lib/grape/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def compile!
@after_validations = stackable[:after_validations]
@afters = stackable[:afters]
@finallies = stackable[:finallies]
@build_params_with = inheritable_setting.namespace_inheritable[:build_params_with]
@build_params_with = inheritable_setting.build_params_with
end

def to_routes
Expand Down Expand Up @@ -406,7 +406,7 @@ def build_helpers
# inherited settings. Warn so this bypass isn't silent.
def warn_unauthenticated_mounted_app
return unless bare_rack_app?
return unless inheritable_setting.namespace_inheritable[:auth]
return unless inheritable_setting.auth

warn "Grape: #{config.app} is mounted under an API that declares authentication, but authentication " \
'middleware does not wrap mounted Rack applications. Requests to this mount are not authenticated by Grape.'
Expand Down
7 changes: 3 additions & 4 deletions lib/grape/middleware/auth/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ module Middleware
module Auth
module DSL
def auth(type = nil, *legacy_options, **options, &block)
namespace_inheritable = inheritable_setting.namespace_inheritable
return namespace_inheritable[:auth] unless type
return inheritable_setting.auth unless type

options = merge_legacy_auth_options(:auth, legacy_options, options)
namespace_inheritable[:auth] = { type: type.to_sym, proc: block }.merge!(options)
use Grape::Middleware::Auth::Base, namespace_inheritable[:auth]
inheritable_setting.auth = { type: type.to_sym, proc: block }.merge!(options)
use Grape::Middleware::Auth::Base, inheritable_setting.auth
end

# Add HTTP Basic authorization to the API.
Expand Down
26 changes: 26 additions & 0 deletions lib/grape/util/inheritable_setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,32 @@ def namespace_stackable_with_hash(key)
data.each_with_object({}) { |value, result| result.deep_merge!(value) }
end

# The params-builder strategy set by +build_with+ (both the
# API-level DSL::Routing#build_with and the params-block
# DSL::Parameters#build_with write it), consumed when the endpoint
# builds its Grape::Request. Nearest-wins scalar; nil when never set;
# the backing store is an internal detail.
def build_params_with
namespace_inheritable[:build_params_with]
end

def build_params_with=(strategy)
namespace_inheritable[:build_params_with] = strategy
end

# The authentication configuration Hash recorded by the +auth+ DSL
# (see Middleware::Auth::DSL): {type:, proc:, **options}. Nearest-wins
# scalar; nil when no authenticator is declared — Endpoint uses that
# to warn about unauthenticated bare Rack mounts; the backing store is
# an internal detail.
def auth
namespace_inheritable[:auth]
end

def auth=(auth_options)
namespace_inheritable[:auth] = auth_options
end

# Rescue-handler maps registered by +rescue_from+, keyed by exception
# class and merged so a nested scope's handler wins. Record them with
# #add_rescue_handlers; the backing store is an internal detail.
Expand Down
Loading