Skip to content

Commit 4fd8ef2

Browse files
authored
Merge pull request #1033 from doorkeeper-gem/force_ssl_redirect_uri_callable
Allow #force_ssl_in_redirect_uri to be callable
2 parents 4ea1fa1 + a28df12 commit 4fd8ef2

File tree

6 files changed

+66
-13
lines changed

6 files changed

+66
-13
lines changed

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ User-visible changes worth mentioning.
44

55
## master
66

7+
- [#1033] Allow Doorkeeper configuration option #force_ssl_in_redirect_uri to be a callable object.
78
- Fix Grape integration & add specs for it
89
- [#913] Deferred ORM (ActiveRecord) models loading
910
- [#943] Fix Access Token token generation when certain errors occur in custom token generators

app/validators/redirect_uri_validator.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def validate_each(record, attribute, value)
1111
else
1212
value.split.each do |val|
1313
uri = ::URI.parse(val)
14-
return if native_redirect_uri?(uri)
14+
return false if native_redirect_uri?(uri)
1515
record.errors.add(attribute, :fragment_present) unless uri.fragment.nil?
1616
record.errors.add(attribute, :relative_uri) if uri.scheme.nil? || uri.host.nil?
1717
record.errors.add(attribute, :secured_uri) if invalid_ssl_uri?(uri)
@@ -29,6 +29,11 @@ def native_redirect_uri?(uri)
2929

3030
def invalid_ssl_uri?(uri)
3131
forces_ssl = Doorkeeper.configuration.force_ssl_in_redirect_uri
32-
forces_ssl && uri.try(:scheme) == 'http'
32+
33+
if forces_ssl.respond_to?(:call)
34+
forces_ssl.call(uri)
35+
else
36+
forces_ssl && uri.try(:scheme) == 'http'
37+
end
3338
end
3439
end

lib/doorkeeper/rails/helpers.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ def doorkeeper_render_error
2828
def doorkeeper_render_error_with(error)
2929
options = doorkeeper_render_options(error) || {}
3030
status = doorkeeper_status_for_error(
31-
error, options.delete(:respond_not_found_when_forbidden))
31+
error, options.delete(:respond_not_found_when_forbidden)
32+
)
3233
if options.blank?
3334
head status
3435
else

lib/generators/doorkeeper/templates/initializer.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,13 @@
8282
# by default in non-development environments). OAuth2 delegates security in
8383
# communication to the HTTPS protocol so it is wise to keep this enabled.
8484
#
85+
# Callable objects such as proc, lambda, block or any object that responds to
86+
# #call can be used in order to allow conditional checks (to allow non-SSL
87+
# redirects to localhost for example).
88+
#
8589
# force_ssl_in_redirect_uri !Rails.env.development?
90+
#
91+
# force_ssl_in_redirect_uri { |uri| uri.host != 'localhost' }
8692

8793
# Specify what grant flows are enabled in array of Strings. The valid
8894
# strings and the flows they enable are:

spec/lib/config_spec.rb

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
orm DOORKEEPER_ORM
1111
resource_owner_authenticator(&block)
1212
end
13+
1314
expect(subject.authenticate_resource_owner).to eq(block)
1415
end
1516
end
@@ -37,6 +38,7 @@
3738
orm DOORKEEPER_ORM
3839
admin_authenticator(&block)
3940
end
41+
4042
expect(subject.authenticate_admin).to eq(block)
4143
end
4244
end
@@ -59,6 +61,7 @@
5961
orm DOORKEEPER_ORM
6062
access_token_expires_in nil
6163
end
64+
6265
expect(subject.access_token_expires_in).to be_nil
6366
end
6467
end
@@ -69,6 +72,7 @@
6972
orm DOORKEEPER_ORM
7073
default_scopes :public
7174
end
75+
7276
expect(subject.default_scopes).to include('public')
7377
end
7478

@@ -77,6 +81,7 @@
7781
orm DOORKEEPER_ORM
7882
optional_scopes :write, :update
7983
end
84+
8085
expect(subject.optional_scopes).to include('write', 'update')
8186
end
8287

@@ -86,6 +91,7 @@
8691
default_scopes :normal
8792
optional_scopes :admin
8893
end
94+
8995
expect(subject.scopes).to include('normal', 'admin')
9096
end
9197
end
@@ -100,6 +106,7 @@
100106
orm DOORKEEPER_ORM
101107
use_refresh_token
102108
end
109+
103110
expect(subject.refresh_token_enabled?).to be_truthy
104111
end
105112

@@ -131,6 +138,7 @@
131138
orm DOORKEEPER_ORM
132139
client_credentials :from_digest, :from_params
133140
end
141+
134142
expect(subject.client_credentials_methods).to eq([:from_digest, :from_params])
135143
end
136144
end
@@ -145,8 +153,20 @@
145153
orm DOORKEEPER_ORM
146154
force_ssl_in_redirect_uri(false)
147155
end
156+
148157
expect(subject.force_ssl_in_redirect_uri).to be_falsey
149158
end
159+
160+
it 'can be a callable object' do
161+
block = proc { false }
162+
Doorkeeper.configure do
163+
orm DOORKEEPER_ORM
164+
force_ssl_in_redirect_uri(&block)
165+
end
166+
167+
expect(subject.force_ssl_in_redirect_uri).to eq(block)
168+
expect(subject.force_ssl_in_redirect_uri.call).to be_falsey
169+
end
150170
end
151171

152172
describe 'access_token_methods' do
@@ -159,6 +179,7 @@
159179
orm DOORKEEPER_ORM
160180
access_token_methods :from_access_token_param, :from_bearer_param
161181
end
182+
162183
expect(subject.access_token_methods).to eq([:from_access_token_param, :from_bearer_param])
163184
end
164185
end
@@ -175,9 +196,11 @@
175196
enable_application_owner
176197
end
177198
end
199+
178200
it 'adds support for application owner' do
179201
expect(Doorkeeper::Application.new).to respond_to :owner
180202
end
203+
181204
it 'Doorkeeper.configuration.confirm_application_owner? returns false' do
182205
expect(Doorkeeper.configuration.confirm_application_owner?).not_to be_truthy
183206
end
@@ -190,9 +213,11 @@
190213
enable_application_owner confirmation: true
191214
end
192215
end
216+
193217
it 'adds support for application owner' do
194218
expect(Doorkeeper::Application.new).to respond_to :owner
195219
end
220+
196221
it 'Doorkeeper.configuration.confirm_application_owner? returns true' do
197222
expect(Doorkeeper.configuration.confirm_application_owner?).to be_truthy
198223
end
@@ -209,6 +234,7 @@
209234
orm DOORKEEPER_ORM
210235
realm 'Example'
211236
end
237+
212238
expect(subject.realm).to eq('Example')
213239
end
214240
end
@@ -220,19 +246,20 @@
220246
end
221247

222248
it "can change the value" do
223-
Doorkeeper.configure {
249+
Doorkeeper.configure do
224250
orm DOORKEEPER_ORM
225251
grant_flows ['authorization_code', 'implicit']
226-
}
252+
end
253+
227254
expect(subject.grant_flows).to eq ['authorization_code', 'implicit']
228255
end
229256

230257
context "when including 'authorization_code'" do
231258
before do
232-
Doorkeeper.configure {
259+
Doorkeeper.configure do
233260
orm DOORKEEPER_ORM
234261
grant_flows ['authorization_code']
235-
}
262+
end
236263
end
237264

238265
it "includes 'code' in authorization_response_types" do
@@ -246,10 +273,10 @@
246273

247274
context "when including 'implicit'" do
248275
before do
249-
Doorkeeper.configure {
276+
Doorkeeper.configure do
250277
orm DOORKEEPER_ORM
251278
grant_flows ['implicit']
252-
}
279+
end
253280
end
254281

255282
it "includes 'token' in authorization_response_types" do
@@ -259,10 +286,10 @@
259286

260287
context "when including 'password'" do
261288
before do
262-
Doorkeeper.configure {
289+
Doorkeeper.configure do
263290
orm DOORKEEPER_ORM
264291
grant_flows ['password']
265-
}
292+
end
266293
end
267294

268295
it "includes 'password' in token_grant_types" do
@@ -272,10 +299,10 @@
272299

273300
context "when including 'client_credentials'" do
274301
before do
275-
Doorkeeper.configure {
302+
Doorkeeper.configure do
276303
orm DOORKEEPER_ORM
277304
grant_flows ['client_credentials']
278-
}
305+
end
279306
end
280307

281308
it "includes 'client_credentials' in token_grant_types" do

spec/validators/redirect_uri_validator_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@
6868
expect(subject).to be_valid
6969
end
7070

71+
it 'accepts a non secured protocol when conditional option defined' do
72+
Doorkeeper.configure do
73+
orm DOORKEEPER_ORM
74+
force_ssl_in_redirect_uri { |uri| uri.host != 'localhost' }
75+
end
76+
77+
application = FactoryBot.build(:application, redirect_uri: 'http://localhost/callback')
78+
expect(application).to be_valid
79+
80+
application = FactoryBot.build(:application, redirect_uri: 'http://localhost2/callback')
81+
expect(application).not_to be_valid
82+
end
83+
7184
it 'invalidates the uri when the uri does not use a secure protocol' do
7285
subject.redirect_uri = 'http://example.com/callback'
7386
expect(subject).not_to be_valid

0 commit comments

Comments
 (0)