Skip to content

Commit 4638481

Browse files
dblockCopilot
andauthored
Fix UnknownAuthStrategy raised when custom auth strategy inherits from Grape::Middleware::Auth::Base (#2674)
When a custom auth strategy class inherits from Grape::Middleware::Auth::Base and is registered via Grape::Middleware::Auth::Strategies.add, it would raise Grape::Exceptions::UnknownAuthStrategy with a blank strategy name upon being instantiated by StrategyInfo#create. The root cause: PR #2563 moved the strategy lookup from request-time (_call) to initialization-time (initialize). When StrategyInfo#create instantiates the custom class via auth_class.new(app) (without options), the inherited initialize tries to look up options[:type] which is nil, causing the error. The fix: guard the strategy lookup so it only runs when :type is present in options. This preserves compile-time validation for the outer middleware wrapper while allowing subclasses to be instantiated as actual strategies. Fixes #2669. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent fe3b4f8 commit 4638481

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#### Fixes
1818

19+
* [#2670](https://github.com/ruby-grape/grape/pull/2670): Fix `UnknownAuthStrategy` raised when custom auth strategy class inherits from `Grape::Middleware::Auth::Base` - [@dblock](https://github.com/dblock).
1920
* [#2655](https://github.com/ruby-grape/grape/pull/2655): Fix `before_each` method to handle `nil` parameter correctly - [@ericproulx](https://github.com/ericproulx).
2021
* [#2660](https://github.com/ruby-grape/grape/pull/2660): Fix thread safety: move mutable `ParamsScope` state (`index`, `params_meeting_dependency`) into a per-request `ParamScopeTracker` stored in `Fiber[]` - [@ericproulx](https://github.com/ericproulx).
2122
* [#2666](https://github.com/ruby-grape/grape/pull/2666): Endpoint cleanup and minor optimizations - [@ericproulx](https://github.com/ericproulx).

lib/grape/middleware/auth/base.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ module Auth
66
class Base < Grape::Middleware::Base
77
def initialize(app, **options)
88
super
9+
return unless options.key?(:type)
10+
911
@auth_strategy = Grape::Middleware::Auth::Strategies[options[:type]].tap do |auth_strategy|
1012
raise Grape::Exceptions::UnknownAuthStrategy.new(strategy: options[:type]) unless auth_strategy
1113
end

spec/grape/middleware/auth/strategies_spec.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,39 @@
4242
end
4343
end
4444
end
45+
46+
describe 'Custom Auth strategy inheriting from Grape::Middleware::Auth::Base' do
47+
let(:custom_auth_middleware) do
48+
Class.new(Grape::Middleware::Auth::Base) do
49+
def call(env)
50+
if env['HTTP_AUTHORIZATION'] == 'valid-token'
51+
@app.call(env)
52+
else
53+
[401, {}, ['Unauthorized']]
54+
end
55+
end
56+
end
57+
end
58+
59+
let(:app) do
60+
middleware = custom_auth_middleware
61+
62+
Class.new(Grape::API) do
63+
Grape::Middleware::Auth::Strategies.add(:custom_token, middleware)
64+
auth(:custom_token) {}
65+
get('/whatever') { 'Hello there.' }
66+
end
67+
end
68+
69+
it 'allows access with valid token' do
70+
get '/whatever', {}, 'HTTP_AUTHORIZATION' => 'valid-token'
71+
expect(last_response).to be_successful
72+
expect(last_response.body).to eq('Hello there.')
73+
end
74+
75+
it 'denies access without valid token' do
76+
get '/whatever'
77+
expect(last_response).to be_unauthorized
78+
end
79+
end
4580
end

0 commit comments

Comments
 (0)