doorkeeper 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. checksums.yaml +5 -5
  2. data/.hound.yml +2 -1
  3. data/.rubocop.yml +37 -4
  4. data/.travis.yml +16 -21
  5. data/Appraisals +29 -7
  6. data/Dangerfile +67 -0
  7. data/Gemfile +19 -5
  8. data/NEWS.md +107 -10
  9. data/README.md +75 -470
  10. data/Rakefile +10 -8
  11. data/app/controllers/doorkeeper/application_controller.rb +3 -2
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -13
  13. data/app/controllers/doorkeeper/applications_controller.rb +21 -7
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +3 -3
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -0
  16. data/app/controllers/doorkeeper/token_info_controller.rb +4 -2
  17. data/app/controllers/doorkeeper/tokens_controller.rb +13 -11
  18. data/app/helpers/doorkeeper/dashboard_helper.rb +3 -1
  19. data/app/validators/redirect_uri_validator.rb +7 -2
  20. data/app/views/doorkeeper/applications/_form.html.erb +6 -0
  21. data/app/views/doorkeeper/applications/show.html.erb +1 -1
  22. data/app/views/layouts/doorkeeper/admin.html.erb +5 -3
  23. data/bin/console +16 -0
  24. data/config/locales/en.yml +1 -0
  25. data/doorkeeper.gemspec +28 -24
  26. data/gemfiles/rails_5_0.gemfile +9 -4
  27. data/gemfiles/rails_5_1.gemfile +9 -4
  28. data/gemfiles/rails_5_2.gemfile +10 -5
  29. data/gemfiles/rails_6_0.gemfile +17 -0
  30. data/gemfiles/rails_master.gemfile +9 -9
  31. data/lib/doorkeeper/config/option.rb +64 -0
  32. data/lib/doorkeeper/config.rb +197 -76
  33. data/lib/doorkeeper/engine.rb +3 -1
  34. data/lib/doorkeeper/errors.rb +17 -0
  35. data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
  36. data/lib/doorkeeper/grape/helpers.rb +5 -3
  37. data/lib/doorkeeper/helpers/controller.rb +5 -2
  38. data/lib/doorkeeper/models/access_grant_mixin.rb +25 -6
  39. data/lib/doorkeeper/models/access_token_mixin.rb +68 -22
  40. data/lib/doorkeeper/models/application_mixin.rb +45 -1
  41. data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
  42. data/lib/doorkeeper/models/concerns/expirable.rb +6 -2
  43. data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
  44. data/lib/doorkeeper/models/concerns/ownership.rb +3 -6
  45. data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
  46. data/lib/doorkeeper/models/concerns/revocable.rb +4 -1
  47. data/lib/doorkeeper/models/concerns/scopes.rb +7 -1
  48. data/lib/doorkeeper/models/concerns/secret_storable.rb +108 -0
  49. data/lib/doorkeeper/oauth/authorization/code.rb +4 -2
  50. data/lib/doorkeeper/oauth/authorization/context.rb +2 -0
  51. data/lib/doorkeeper/oauth/authorization/token.rb +14 -7
  52. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +3 -1
  53. data/lib/doorkeeper/oauth/authorization_code_request.rb +8 -4
  54. data/lib/doorkeeper/oauth/base_request.rb +2 -0
  55. data/lib/doorkeeper/oauth/base_response.rb +2 -0
  56. data/lib/doorkeeper/oauth/client/credentials.rb +2 -0
  57. data/lib/doorkeeper/oauth/client.rb +3 -1
  58. data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -0
  59. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +2 -0
  60. data/lib/doorkeeper/oauth/client_credentials/validation.rb +7 -4
  61. data/lib/doorkeeper/oauth/client_credentials_request.rb +3 -1
  62. data/lib/doorkeeper/oauth/code_request.rb +2 -0
  63. data/lib/doorkeeper/oauth/code_response.rb +4 -2
  64. data/lib/doorkeeper/oauth/error.rb +2 -0
  65. data/lib/doorkeeper/oauth/error_response.rb +20 -6
  66. data/lib/doorkeeper/oauth/forbidden_token_response.rb +10 -3
  67. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +25 -8
  68. data/lib/doorkeeper/oauth/helpers/unique_token.rb +15 -1
  69. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +42 -3
  70. data/lib/doorkeeper/oauth/invalid_token_response.rb +22 -0
  71. data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -2
  72. data/lib/doorkeeper/oauth/pre_authorization.rb +13 -5
  73. data/lib/doorkeeper/oauth/refresh_token_request.rb +15 -4
  74. data/lib/doorkeeper/oauth/scopes.rb +7 -3
  75. data/lib/doorkeeper/oauth/token.rb +4 -2
  76. data/lib/doorkeeper/oauth/token_introspection.rb +76 -8
  77. data/lib/doorkeeper/oauth/token_request.rb +2 -0
  78. data/lib/doorkeeper/oauth/token_response.rb +11 -9
  79. data/lib/doorkeeper/oauth.rb +5 -5
  80. data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -13
  81. data/lib/doorkeeper/orm/active_record/access_token.rb +6 -13
  82. data/lib/doorkeeper/orm/active_record/application.rb +26 -7
  83. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
  84. data/lib/doorkeeper/orm/active_record.rb +8 -6
  85. data/lib/doorkeeper/rails/helpers.rb +5 -1
  86. data/lib/doorkeeper/rails/routes/mapper.rb +2 -0
  87. data/lib/doorkeeper/rails/routes/mapping.rb +9 -7
  88. data/lib/doorkeeper/rails/routes.rb +19 -12
  89. data/lib/doorkeeper/rake/db.rake +17 -17
  90. data/lib/doorkeeper/rake.rb +1 -1
  91. data/lib/doorkeeper/request/authorization_code.rb +2 -0
  92. data/lib/doorkeeper/request/client_credentials.rb +2 -0
  93. data/lib/doorkeeper/request/code.rb +2 -0
  94. data/lib/doorkeeper/request/password.rb +2 -0
  95. data/lib/doorkeeper/request/refresh_token.rb +2 -0
  96. data/lib/doorkeeper/request/strategy.rb +2 -0
  97. data/lib/doorkeeper/request/token.rb +2 -0
  98. data/lib/doorkeeper/request.rb +3 -1
  99. data/lib/doorkeeper/secret_storing/base.rb +64 -0
  100. data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
  101. data/lib/doorkeeper/secret_storing/plain.rb +33 -0
  102. data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
  103. data/lib/doorkeeper/server.rb +2 -0
  104. data/lib/doorkeeper/stale_records_cleaner.rb +20 -0
  105. data/lib/doorkeeper/validations.rb +2 -0
  106. data/lib/doorkeeper/version.rb +4 -2
  107. data/lib/doorkeeper.rb +69 -59
  108. data/lib/generators/doorkeeper/application_owner_generator.rb +10 -9
  109. data/lib/generators/doorkeeper/confidential_applications_generator.rb +10 -9
  110. data/lib/generators/doorkeeper/install_generator.rb +11 -9
  111. data/lib/generators/doorkeeper/migration_generator.rb +9 -9
  112. data/lib/generators/doorkeeper/pkce_generator.rb +10 -9
  113. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +10 -9
  114. data/lib/generators/doorkeeper/templates/initializer.rb +138 -13
  115. data/lib/generators/doorkeeper/templates/migration.rb.erb +17 -10
  116. data/lib/generators/doorkeeper/views_generator.rb +6 -4
  117. data/spec/controllers/application_metal_controller_spec.rb +24 -10
  118. data/spec/controllers/applications_controller_spec.rb +76 -78
  119. data/spec/controllers/authorizations_controller_spec.rb +189 -142
  120. data/spec/controllers/protected_resources_controller_spec.rb +111 -67
  121. data/spec/controllers/token_info_controller_spec.rb +14 -12
  122. data/spec/controllers/tokens_controller_spec.rb +170 -112
  123. data/spec/dummy/Rakefile +3 -1
  124. data/spec/dummy/app/controllers/application_controller.rb +3 -1
  125. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +3 -1
  126. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -2
  127. data/spec/dummy/app/controllers/home_controller.rb +6 -5
  128. data/spec/dummy/app/controllers/metal_controller.rb +2 -0
  129. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +4 -2
  130. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  131. data/spec/dummy/app/models/user.rb +2 -0
  132. data/spec/dummy/config/application.rb +26 -2
  133. data/spec/dummy/config/boot.rb +2 -4
  134. data/spec/dummy/config/environment.rb +1 -1
  135. data/spec/dummy/config/environments/development.rb +2 -0
  136. data/spec/dummy/config/environments/production.rb +2 -0
  137. data/spec/dummy/config/environments/test.rb +4 -2
  138. data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
  139. data/spec/dummy/config/initializers/doorkeeper.rb +7 -3
  140. data/spec/dummy/config/initializers/secret_token.rb +3 -1
  141. data/spec/dummy/config/initializers/session_store.rb +3 -1
  142. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
  143. data/spec/dummy/config.ru +3 -1
  144. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +20 -13
  145. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +1 -1
  146. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +2 -0
  147. data/spec/dummy/db/schema.rb +1 -1
  148. data/spec/dummy/script/rails +7 -4
  149. data/spec/factories.rb +11 -9
  150. data/spec/generators/application_owner_generator_spec.rb +13 -26
  151. data/spec/generators/confidential_applications_generator_spec.rb +12 -28
  152. data/spec/generators/install_generator_spec.rb +19 -14
  153. data/spec/generators/migration_generator_spec.rb +13 -26
  154. data/spec/generators/pkce_generator_spec.rb +11 -26
  155. data/spec/generators/previous_refresh_token_generator_spec.rb +16 -29
  156. data/spec/generators/templates/routes.rb +2 -1
  157. data/spec/generators/views_generator_spec.rb +14 -12
  158. data/spec/grape/grape_integration_spec.rb +35 -33
  159. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +9 -7
  160. data/spec/lib/config_spec.rb +290 -104
  161. data/spec/lib/doorkeeper_spec.rb +8 -6
  162. data/spec/lib/models/expirable_spec.rb +22 -8
  163. data/spec/lib/models/reusable_spec.rb +40 -0
  164. data/spec/lib/models/revocable_spec.rb +8 -6
  165. data/spec/lib/models/scopes_spec.rb +27 -13
  166. data/spec/lib/models/secret_storable_spec.rb +135 -0
  167. data/spec/lib/oauth/authorization/uri_builder_spec.rb +17 -15
  168. data/spec/lib/oauth/authorization_code_request_spec.rb +43 -17
  169. data/spec/lib/oauth/base_request_spec.rb +24 -12
  170. data/spec/lib/oauth/base_response_spec.rb +3 -1
  171. data/spec/lib/oauth/client/credentials_spec.rb +26 -24
  172. data/spec/lib/oauth/client_credentials/creator_spec.rb +56 -10
  173. data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -20
  174. data/spec/lib/oauth/client_credentials/validation_spec.rb +21 -15
  175. data/spec/lib/oauth/client_credentials_integration_spec.rb +8 -6
  176. data/spec/lib/oauth/client_credentials_request_spec.rb +27 -21
  177. data/spec/lib/oauth/client_spec.rb +15 -13
  178. data/spec/lib/oauth/code_request_spec.rb +10 -8
  179. data/spec/lib/oauth/code_response_spec.rb +9 -7
  180. data/spec/lib/oauth/error_response_spec.rb +19 -11
  181. data/spec/lib/oauth/error_spec.rb +4 -2
  182. data/spec/lib/oauth/forbidden_token_response_spec.rb +7 -5
  183. data/spec/lib/oauth/helpers/scope_checker_spec.rb +68 -31
  184. data/spec/lib/oauth/helpers/unique_token_spec.rb +8 -6
  185. data/spec/lib/oauth/helpers/uri_checker_spec.rb +124 -93
  186. data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
  187. data/spec/lib/oauth/password_access_token_request_spec.rb +95 -34
  188. data/spec/lib/oauth/pre_authorization_spec.rb +80 -54
  189. data/spec/lib/oauth/refresh_token_request_spec.rb +46 -39
  190. data/spec/lib/oauth/scopes_spec.rb +63 -61
  191. data/spec/lib/oauth/token_request_spec.rb +80 -25
  192. data/spec/lib/oauth/token_response_spec.rb +40 -38
  193. data/spec/lib/oauth/token_spec.rb +64 -45
  194. data/spec/lib/request/strategy_spec.rb +3 -1
  195. data/spec/lib/secret_storing/base_spec.rb +60 -0
  196. data/spec/lib/secret_storing/bcrypt_spec.rb +49 -0
  197. data/spec/lib/secret_storing/plain_spec.rb +44 -0
  198. data/spec/lib/secret_storing/sha256_hash_spec.rb +48 -0
  199. data/spec/lib/server_spec.rb +20 -18
  200. data/spec/lib/{orm/active_record/stale_records_cleaner_spec.rb → stale_records_cleaner_spec.rb} +28 -18
  201. data/spec/models/doorkeeper/access_grant_spec.rb +80 -15
  202. data/spec/models/doorkeeper/access_token_spec.rb +212 -83
  203. data/spec/models/doorkeeper/application_spec.rb +146 -49
  204. data/spec/requests/applications/applications_request_spec.rb +100 -68
  205. data/spec/requests/applications/authorized_applications_spec.rb +20 -18
  206. data/spec/requests/endpoints/authorization_spec.rb +27 -25
  207. data/spec/requests/endpoints/token_spec.rb +38 -36
  208. data/spec/requests/flows/authorization_code_errors_spec.rb +27 -25
  209. data/spec/requests/flows/authorization_code_spec.rb +260 -158
  210. data/spec/requests/flows/client_credentials_spec.rb +54 -52
  211. data/spec/requests/flows/implicit_grant_errors_spec.rb +11 -9
  212. data/spec/requests/flows/implicit_grant_spec.rb +27 -25
  213. data/spec/requests/flows/password_spec.rb +64 -56
  214. data/spec/requests/flows/refresh_token_spec.rb +91 -32
  215. data/spec/requests/flows/revoke_token_spec.rb +49 -63
  216. data/spec/requests/flows/skip_authorization_spec.rb +23 -21
  217. data/spec/requests/protected_resources/metal_spec.rb +7 -5
  218. data/spec/requests/protected_resources/private_api_spec.rb +37 -35
  219. data/spec/routing/custom_controller_routes_spec.rb +71 -65
  220. data/spec/routing/default_routes_spec.rb +22 -20
  221. data/spec/routing/scoped_routes_spec.rb +20 -18
  222. data/spec/spec_helper.rb +15 -13
  223. data/spec/spec_helper_integration.rb +3 -1
  224. data/spec/support/dependencies/factory_bot.rb +3 -1
  225. data/spec/support/doorkeeper_rspec.rb +5 -2
  226. data/spec/support/helpers/access_token_request_helper.rb +3 -1
  227. data/spec/support/helpers/authorization_request_helper.rb +4 -2
  228. data/spec/support/helpers/config_helper.rb +2 -0
  229. data/spec/support/helpers/model_helper.rb +11 -5
  230. data/spec/support/helpers/request_spec_helper.rb +5 -3
  231. data/spec/support/helpers/url_helper.rb +20 -18
  232. data/spec/support/http_method_shim.rb +4 -9
  233. data/spec/support/orm/active_record.rb +3 -1
  234. data/spec/support/shared/controllers_shared_context.rb +68 -10
  235. data/spec/support/shared/hashing_shared_context.rb +36 -0
  236. data/spec/support/shared/models_shared_examples.rb +12 -10
  237. data/spec/validators/redirect_uri_validator_spec.rb +76 -47
  238. data/spec/version/version_spec.rb +7 -5
  239. metadata +70 -21
  240. data/gemfiles/rails_4_2.gemfile +0 -13
  241. data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -10
@@ -1,17 +1,19 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper
4
6
  module OAuth
5
7
  describe CodeResponse do
6
- describe '.redirect_uri' do
7
- context 'when generating the redirect URI for an implicit grant' do
8
+ describe ".redirect_uri" do
9
+ context "when generating the redirect URI for an implicit grant" do
8
10
  let :pre_auth do
9
11
  double(
10
12
  :pre_auth,
11
13
  client: double(:application, id: 1),
12
- redirect_uri: 'http://tst.com/cb',
14
+ redirect_uri: "http://tst.com/cb",
13
15
  state: nil,
14
- scopes: Scopes.from_string('public'),
16
+ scopes: Scopes.from_string("public")
15
17
  )
16
18
  end
17
19
 
@@ -24,8 +26,8 @@ module Doorkeeper
24
26
 
25
27
  subject { CodeResponse.new(pre_auth, auth, response_on_fragment: true).redirect_uri }
26
28
 
27
- it 'includes the remaining TTL of the token relative to the time the token was generated' do
28
- expect(subject).to include('expires_in=3600')
29
+ it "includes the remaining TTL of the token relative to the time the token was generated" do
30
+ expect(subject).to include("expires_in=3600")
29
31
  end
30
32
  end
31
33
  end
@@ -1,50 +1,58 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth
4
6
  describe ErrorResponse do
5
- describe '#status' do
6
- it 'should have a status of unauthorized' do
7
+ describe "#status" do
8
+ it "should have a status of bad_request" do
9
+ expect(subject.status).to eq(:bad_request)
10
+ end
11
+
12
+ it "should have a status of unauthorized for an invalid_client error" do
13
+ subject = described_class.new(name: :invalid_client)
14
+
7
15
  expect(subject.status).to eq(:unauthorized)
8
16
  end
9
17
  end
10
18
 
11
19
  describe :from_request do
12
- it 'has the error from request' do
20
+ it "has the error from request" do
13
21
  error = ErrorResponse.from_request double(error: :some_error)
14
22
  expect(error.name).to eq(:some_error)
15
23
  end
16
24
 
17
- it 'ignores state if request does not respond to state' do
25
+ it "ignores state if request does not respond to state" do
18
26
  error = ErrorResponse.from_request double(error: :some_error)
19
27
  expect(error.state).to be_nil
20
28
  end
21
29
 
22
- it 'has state if request responds to state' do
30
+ it "has state if request responds to state" do
23
31
  error = ErrorResponse.from_request double(error: :some_error, state: :hello)
24
32
  expect(error.state).to eq(:hello)
25
33
  end
26
34
  end
27
35
 
28
- it 'ignores empty error values' do
36
+ it "ignores empty error values" do
29
37
  subject = ErrorResponse.new(error: :some_error, state: nil)
30
38
  expect(subject.body).not_to have_key(:state)
31
39
  end
32
40
 
33
- describe '.body' do
41
+ describe ".body" do
34
42
  subject { ErrorResponse.new(name: :some_error, state: :some_state).body }
35
43
 
36
- describe '#body' do
44
+ describe "#body" do
37
45
  it { expect(subject).to have_key(:error) }
38
46
  it { expect(subject).to have_key(:error_description) }
39
47
  it { expect(subject).to have_key(:state) }
40
48
  end
41
49
  end
42
50
 
43
- describe '.headers' do
51
+ describe ".headers" do
44
52
  let(:error_response) { ErrorResponse.new(name: :some_error, state: :some_state) }
45
53
  subject { error_response.headers }
46
54
 
47
- it { expect(subject).to include 'WWW-Authenticate' }
55
+ it { expect(subject).to include "WWW-Authenticate" }
48
56
 
49
57
  describe "WWW-Authenticate header" do
50
58
  subject { error_response.headers["WWW-Authenticate"] }
@@ -1,4 +1,6 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth
4
6
  describe Error do
@@ -8,7 +10,7 @@ module Doorkeeper::OAuth
8
10
  it { expect(subject).to respond_to(:state) }
9
11
 
10
12
  describe :description do
11
- it 'is translated from translation messages' do
13
+ it "is translated from translation messages" do
12
14
  expect(I18n).to receive(:translate).with(
13
15
  :some_error,
14
16
  scope: %i[doorkeeper errors messages],
@@ -1,19 +1,21 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth
4
6
  describe ForbiddenTokenResponse do
5
- describe '#name' do
7
+ describe "#name" do
6
8
  it { expect(subject.name).to eq(:invalid_scope) }
7
9
  end
8
10
 
9
- describe '#status' do
11
+ describe "#status" do
10
12
  it { expect(subject.status).to eq(:forbidden) }
11
13
  end
12
14
 
13
15
  describe :from_scopes do
14
- it 'should have a list of acceptable scopes' do
16
+ it "should have a list of acceptable scopes" do
15
17
  response = ForbiddenTokenResponse.from_scopes(["public"])
16
- expect(response.description).to include('public')
18
+ expect(response.description).to include("public")
17
19
  end
18
20
  end
19
21
  end
@@ -1,60 +1,97 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth::Helpers
4
- describe ScopeChecker, '.valid?' do
6
+ describe ScopeChecker, ".valid?" do
5
7
  let(:server_scopes) { Doorkeeper::OAuth::Scopes.new }
6
8
 
7
- it 'is valid if scope is present' do
9
+ it "is valid if scope is present" do
8
10
  server_scopes.add :scope
9
- expect(ScopeChecker.valid?('scope', server_scopes)).to be_truthy
11
+ expect(ScopeChecker.valid?(scope_str: "scope", server_scopes: server_scopes)).to be_truthy
10
12
  end
11
13
 
12
- it 'is invalid if includes tabs space' do
13
- expect(ScopeChecker.valid?("\tsomething", server_scopes)).to be_falsey
14
+ it "is invalid if includes tabs space" do
15
+ expect(ScopeChecker.valid?(scope_str: "\tsomething", server_scopes: server_scopes)).to be_falsey
14
16
  end
15
17
 
16
- it 'is invalid if scope is not present' do
17
- expect(ScopeChecker.valid?(nil, server_scopes)).to be_falsey
18
+ it "is invalid if scope is not present" do
19
+ expect(ScopeChecker.valid?(scope_str: nil, server_scopes: server_scopes)).to be_falsey
18
20
  end
19
21
 
20
- it 'is invalid if scope is blank' do
21
- expect(ScopeChecker.valid?(' ', server_scopes)).to be_falsey
22
+ it "is invalid if scope is blank" do
23
+ expect(ScopeChecker.valid?(scope_str: " ", server_scopes: server_scopes)).to be_falsey
22
24
  end
23
25
 
24
- it 'is invalid if includes return space' do
25
- expect(ScopeChecker.valid?("scope\r", server_scopes)).to be_falsey
26
+ it "is invalid if includes return space" do
27
+ expect(ScopeChecker.valid?(scope_str: "scope\r", server_scopes: server_scopes)).to be_falsey
26
28
  end
27
29
 
28
- it 'is invalid if includes new lines' do
29
- expect(ScopeChecker.valid?("scope\nanother", server_scopes)).to be_falsey
30
+ it "is invalid if includes new lines" do
31
+ expect(ScopeChecker.valid?(scope_str: "scope\nanother", server_scopes: server_scopes)).to be_falsey
30
32
  end
31
33
 
32
- it 'is invalid if any scope is not included in server scopes' do
33
- expect(ScopeChecker.valid?('scope another', server_scopes)).to be_falsey
34
+ it "is invalid if any scope is not included in server scopes" do
35
+ expect(ScopeChecker.valid?(scope_str: "scope another", server_scopes: server_scopes)).to be_falsey
34
36
  end
35
37
 
36
- context 'with application_scopes' do
38
+ context "with application_scopes" do
37
39
  let(:server_scopes) do
38
- Doorkeeper::OAuth::Scopes.from_string 'common svr'
40
+ Doorkeeper::OAuth::Scopes.from_string "common svr"
39
41
  end
40
42
  let(:application_scopes) do
41
- Doorkeeper::OAuth::Scopes.from_string 'app123'
43
+ Doorkeeper::OAuth::Scopes.from_string "app123"
44
+ end
45
+
46
+ it "is valid if scope is included in the application scope list" do
47
+ expect(ScopeChecker.valid?(scope_str: "app123",
48
+ server_scopes: server_scopes,
49
+ app_scopes: application_scopes)).to be_truthy
50
+ end
51
+
52
+ it "is invalid if any scope is not included in the application" do
53
+ expect(ScopeChecker.valid?(scope_str: "svr",
54
+ server_scopes: server_scopes,
55
+ app_scopes: application_scopes)).to be_falsey
56
+ end
57
+ end
58
+
59
+ context "with grant_type" do
60
+ let(:server_scopes) do
61
+ Doorkeeper::OAuth::Scopes.from_string "scope1 scope2"
42
62
  end
43
63
 
44
- it 'is valid if scope is included in the application scope list' do
45
- expect(ScopeChecker.valid?(
46
- 'app123',
47
- server_scopes,
48
- application_scopes
49
- )).to be_truthy
64
+ context "with scopes_by_grant_type not configured for grant_type" do
65
+ it "is valid if the scope is in server scopes" do
66
+ expect(ScopeChecker.valid?(scope_str: "scope1",
67
+ server_scopes: server_scopes,
68
+ grant_type: Doorkeeper::OAuth::PASSWORD)).to be_truthy
69
+ end
70
+
71
+ it "is invalid if the scope is not in server scopes" do
72
+ expect(ScopeChecker.valid?(scope_str: "unknown",
73
+ server_scopes: server_scopes,
74
+ grant_type: Doorkeeper::OAuth::PASSWORD)).to be_falsey
75
+ end
50
76
  end
51
77
 
52
- it 'is invalid if any scope is not included in the application' do
53
- expect(ScopeChecker.valid?(
54
- 'svr',
55
- server_scopes,
56
- application_scopes
57
- )).to be_falsey
78
+ context "when scopes_by_grant_type configured for grant_type" do
79
+ before do
80
+ allow(Doorkeeper.configuration).to receive(:scopes_by_grant_type)
81
+ .and_return(password: [:scope1])
82
+ end
83
+
84
+ it "is valid if the scope is permitted for grant_type" do
85
+ expect(ScopeChecker.valid?(scope_str: "scope1",
86
+ server_scopes: server_scopes,
87
+ grant_type: Doorkeeper::OAuth::PASSWORD)).to be_truthy
88
+ end
89
+
90
+ it "is invalid if the scope is permitted for grant_type" do
91
+ expect(ScopeChecker.valid?(scope_str: "scope2",
92
+ server_scopes: server_scopes,
93
+ grant_type: Doorkeeper::OAuth::PASSWORD)).to be_falsey
94
+ end
58
95
  end
59
96
  end
60
97
  end
@@ -1,19 +1,21 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth::Helpers
4
6
  describe UniqueToken do
5
7
  let :generator do
6
- ->(size) { 'a' * size }
8
+ ->(size) { "a" * size }
7
9
  end
8
10
 
9
- it 'is able to customize the generator method' do
11
+ it "is able to customize the generator method" do
10
12
  token = UniqueToken.generate(generator: generator)
11
- expect(token).to eq('a' * 32)
13
+ expect(token).to eq("a" * 32)
12
14
  end
13
15
 
14
- it 'is able to customize the size of the token' do
16
+ it "is able to customize the size of the token" do
15
17
  token = UniqueToken.generate(generator: generator, size: 2)
16
- expect(token).to eq('aa')
18
+ expect(token).to eq("aa")
17
19
  end
18
20
  end
19
21
  end
@@ -1,215 +1,246 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth::Helpers
4
6
  describe URIChecker do
5
- describe '.valid?' do
6
- it 'is valid for valid uris' do
7
- uri = 'http://app.co'
7
+ describe ".valid?" do
8
+ it "is valid for valid uris" do
9
+ uri = "http://app.co"
8
10
  expect(URIChecker.valid?(uri)).to be_truthy
9
11
  end
10
12
 
11
- it 'is valid if include path param' do
12
- uri = 'http://app.co/path'
13
+ it "is valid if include path param" do
14
+ uri = "http://app.co/path"
13
15
  expect(URIChecker.valid?(uri)).to be_truthy
14
16
  end
15
17
 
16
- it 'is valid if include query param' do
17
- uri = 'http://app.co/?query=1'
18
+ it "is valid if include query param" do
19
+ uri = "http://app.co/?query=1"
18
20
  expect(URIChecker.valid?(uri)).to be_truthy
19
21
  end
20
22
 
21
- it 'is invalid if uri includes fragment' do
22
- uri = 'http://app.co/test#fragment'
23
+ it "is invalid if uri includes fragment" do
24
+ uri = "http://app.co/test#fragment"
23
25
  expect(URIChecker.valid?(uri)).to be_falsey
24
26
  end
25
27
 
26
- it 'is invalid if scheme is missing' do
27
- uri = 'app.co'
28
+ it "is invalid if scheme is missing" do
29
+ uri = "app.co"
28
30
  expect(URIChecker.valid?(uri)).to be_falsey
29
31
  end
30
32
 
31
- it 'is invalid if is a relative uri' do
32
- uri = '/abc/123'
33
+ it "is invalid if is a relative uri" do
34
+ uri = "/abc/123"
33
35
  expect(URIChecker.valid?(uri)).to be_falsey
34
36
  end
35
37
 
36
- it 'is invalid if is not a url' do
37
- uri = 'http://'
38
+ it "is invalid if is not a url" do
39
+ uri = "http://"
38
40
  expect(URIChecker.valid?(uri)).to be_falsey
39
41
  end
40
42
 
41
- it 'is invalid if is not an uri' do
42
- uri = ' '
43
+ it "is invalid if is not an uri" do
44
+ uri = " "
43
45
  expect(URIChecker.valid?(uri)).to be_falsey
44
46
  end
45
47
 
46
- it 'is valid for native uris' do
47
- uri = 'urn:ietf:wg:oauth:2.0:oob'
48
+ it "is valid for native uris" do
49
+ uri = "urn:ietf:wg:oauth:2.0:oob"
48
50
  expect(URIChecker.valid?(uri)).to be_truthy
49
51
  end
50
52
  end
51
53
 
52
- describe '.matches?' do
53
- it 'is true if both url matches' do
54
- uri = client_uri = 'http://app.co/aaa'
54
+ describe ".matches?" do
55
+ it "is true if both url matches" do
56
+ uri = client_uri = "http://app.co/aaa"
55
57
  expect(URIChecker.matches?(uri, client_uri)).to be_truthy
56
58
  end
57
59
 
58
- it 'ignores query parameter on comparsion' do
59
- uri = 'http://app.co/?query=hello'
60
- client_uri = 'http://app.co'
60
+ it "ignores query parameter on comparsion" do
61
+ uri = "http://app.co/?query=hello"
62
+ client_uri = "http://app.co"
61
63
  expect(URIChecker.matches?(uri, client_uri)).to be_truthy
62
64
  end
63
65
 
64
- it 'doesn\'t allow non-matching domains through' do
65
- uri = 'http://app.abc/?query=hello'
66
- client_uri = 'http://app.co'
66
+ it "doesn't allow non-matching domains through" do
67
+ uri = "http://app.abc/?query=hello"
68
+ client_uri = "http://app.co"
67
69
  expect(URIChecker.matches?(uri, client_uri)).to be_falsey
68
70
  end
69
71
 
70
- it 'doesn\'t allow non-matching domains that don\'t start at the beginning' do
71
- uri = 'http://app.co/?query=hello'
72
- client_uri = 'http://example.com?app.co=test'
72
+ it "doesn't allow non-matching domains that don't start at the beginning" do
73
+ uri = "http://app.co/?query=hello"
74
+ client_uri = "http://example.com?app.co=test"
73
75
  expect(URIChecker.matches?(uri, client_uri)).to be_falsey
74
76
  end
75
77
 
78
+ context "loopback IP redirect URIs" do
79
+ it "ignores port for same URIs" do
80
+ uri = "http://127.0.0.1:5555/auth/callback"
81
+ client_uri = "http://127.0.0.1:48599/auth/callback"
82
+ expect(URIChecker.matches?(uri, client_uri)).to be_truthy
83
+
84
+ uri = "http://[::1]:5555/auth/callback"
85
+ client_uri = "http://[::1]:5555/auth/callback"
86
+ expect(URIChecker.matches?(uri, client_uri)).to be_truthy
87
+ end
88
+
89
+ it "doesn't ignore port for URIs with different queries" do
90
+ uri = "http://127.0.0.1:5555/auth/callback"
91
+ client_uri = "http://127.0.0.1:48599/auth/callback2"
92
+ expect(URIChecker.matches?(uri, client_uri)).to be_falsey
93
+ end
94
+ end
95
+
76
96
  context "client registered query params" do
77
97
  it "doesn't allow query being absent" do
78
- uri = 'http://app.co'
79
- client_uri = 'http://app.co/?vendorId=AJ4L7XXW9'
98
+ uri = "http://app.co"
99
+ client_uri = "http://app.co/?vendorId=AJ4L7XXW9"
80
100
  expect(URIChecker.matches?(uri, client_uri)).to be_falsey
81
101
  end
82
102
 
83
103
  it "is false if query values differ but key same" do
84
- uri = 'http://app.co/?vendorId=pancakes'
85
- client_uri = 'http://app.co/?vendorId=waffles'
104
+ uri = "http://app.co/?vendorId=pancakes"
105
+ client_uri = "http://app.co/?vendorId=waffles"
86
106
  expect(URIChecker.matches?(uri, client_uri)).to be_falsey
87
107
  end
88
108
 
89
109
  it "is false if query values same but key differs" do
90
- uri = 'http://app.co/?foo=pancakes'
91
- client_uri = 'http://app.co/?bar=pancakes'
110
+ uri = "http://app.co/?foo=pancakes"
111
+ client_uri = "http://app.co/?bar=pancakes"
92
112
  expect(URIChecker.matches?(uri, client_uri)).to be_falsey
93
113
  end
94
114
 
95
115
  it "is false if query present and match, but unknown queries present" do
96
- uri = 'http://app.co/?vendorId=pancakes&unknown=query'
97
- client_uri = 'http://app.co/?vendorId=waffles'
116
+ uri = "http://app.co/?vendorId=pancakes&unknown=query"
117
+ client_uri = "http://app.co/?vendorId=waffles"
98
118
  expect(URIChecker.matches?(uri, client_uri)).to be_falsey
99
119
  end
100
120
 
101
121
  it "is true if queries are present and matche" do
102
- uri = 'http://app.co/?vendorId=AJ4L7XXW9&foo=bar'
103
- client_uri = 'http://app.co/?vendorId=AJ4L7XXW9&foo=bar'
122
+ uri = "http://app.co/?vendorId=AJ4L7XXW9&foo=bar"
123
+ client_uri = "http://app.co/?vendorId=AJ4L7XXW9&foo=bar"
104
124
  expect(URIChecker.matches?(uri, client_uri)).to be_truthy
105
125
  end
106
126
 
107
127
  it "is true if queries are present, match and in different order" do
108
- uri = 'http://app.co/?bing=bang&foo=bar'
109
- client_uri = 'http://app.co/?foo=bar&bing=bang'
128
+ uri = "http://app.co/?bing=bang&foo=bar"
129
+ client_uri = "http://app.co/?foo=bar&bing=bang"
110
130
  expect(URIChecker.matches?(uri, client_uri)).to be_truthy
111
131
  end
112
132
  end
113
133
  end
114
134
 
115
- describe '.valid_for_authorization?' do
116
- it 'is true if valid and matches' do
117
- uri = client_uri = 'http://app.co/aaa'
135
+ describe ".valid_for_authorization?" do
136
+ it "is true if valid and matches" do
137
+ uri = client_uri = "http://app.co/aaa"
138
+ expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_truthy
139
+
140
+ uri = client_uri = "http://app.co/aaa?b=c"
141
+ expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_truthy
142
+ end
143
+
144
+ it "is true if uri includes blank query" do
145
+ uri = client_uri = "http://app.co/aaa?"
146
+ expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_truthy
147
+
148
+ uri = "http://app.co/aaa?"
149
+ client_uri = "http://app.co/aaa"
150
+ expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_truthy
151
+
152
+ uri = "http://app.co/aaa"
153
+ client_uri = "http://app.co/aaa?"
118
154
  expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_truthy
119
155
  end
120
156
 
121
- it 'is false if valid and mismatches' do
122
- uri = 'http://app.co/aaa'
123
- client_uri = 'http://app.co/bbb'
157
+ it "is false if valid and mismatches" do
158
+ uri = "http://app.co/aaa"
159
+ client_uri = "http://app.co/bbb"
124
160
  expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_falsey
125
161
  end
126
162
 
127
- it 'is true if valid and included in array' do
128
- uri = 'http://app.co/aaa'
163
+ it "is true if valid and included in array" do
164
+ uri = "http://app.co/aaa"
129
165
  client_uri = "http://example.com/bbb\nhttp://app.co/aaa"
130
166
  expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_truthy
131
167
  end
132
168
 
133
- it 'is false if valid and not included in array' do
134
- uri = 'http://app.co/aaa'
169
+ it "is false if valid and not included in array" do
170
+ uri = "http://app.co/aaa"
135
171
  client_uri = "http://example.com/bbb\nhttp://app.co/cc"
136
172
  expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_falsey
137
173
  end
138
174
 
139
- it 'is true if valid and matches' do
140
- uri = client_uri = 'http://app.co/aaa'
141
- expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be true
142
- end
143
-
144
- it 'is false if invalid' do
145
- uri = 'http://app.co/aaa?pankcakes=abc'
146
- client_uri = 'http://app.co/aaa?waffles=abc'
175
+ it "is false if queries does not match" do
176
+ uri = "http://app.co/aaa?pankcakes=abc"
177
+ client_uri = "http://app.co/aaa?waffles=abc"
147
178
  expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be false
148
179
  end
149
180
 
150
- it 'calls .matches?' do
151
- uri = 'http://app.co/aaa?pankcakes=abc'
152
- client_uri = 'http://app.co/aaa?waffles=abc'
181
+ it "calls .matches?" do
182
+ uri = "http://app.co/aaa?pankcakes=abc"
183
+ client_uri = "http://app.co/aaa?waffles=abc"
153
184
  expect(URIChecker).to receive(:matches?).with(uri, client_uri).once
154
185
  URIChecker.valid_for_authorization?(uri, client_uri)
155
186
  end
156
187
 
157
- it 'calls .valid?' do
158
- uri = 'http://app.co/aaa?pankcakes=abc'
159
- client_uri = 'http://app.co/aaa?waffles=abc'
188
+ it "calls .valid?" do
189
+ uri = "http://app.co/aaa?pankcakes=abc"
190
+ client_uri = "http://app.co/aaa?waffles=abc"
160
191
  expect(URIChecker).to receive(:valid?).with(uri).once
161
192
  URIChecker.valid_for_authorization?(uri, client_uri)
162
193
  end
163
194
  end
164
195
 
165
- describe '.query_matches?' do
166
- it 'is true if no queries' do
167
- expect(URIChecker.query_matches?('', '')).to be_truthy
196
+ describe ".query_matches?" do
197
+ it "is true if no queries" do
198
+ expect(URIChecker.query_matches?("", "")).to be_truthy
168
199
  expect(URIChecker.query_matches?(nil, nil)).to be_truthy
169
200
  end
170
201
 
171
- it 'is true if same query' do
172
- expect(URIChecker.query_matches?('foo', 'foo')).to be_truthy
202
+ it "is true if same query" do
203
+ expect(URIChecker.query_matches?("foo", "foo")).to be_truthy
173
204
  end
174
205
 
175
- it 'is false if different query' do
176
- expect(URIChecker.query_matches?('foo', 'bar')).to be_falsey
206
+ it "is false if different query" do
207
+ expect(URIChecker.query_matches?("foo", "bar")).to be_falsey
177
208
  end
178
209
 
179
- it 'is true if same queries' do
180
- expect(URIChecker.query_matches?('foo&bar', 'foo&bar')).to be_truthy
210
+ it "is true if same queries" do
211
+ expect(URIChecker.query_matches?("foo&bar", "foo&bar")).to be_truthy
181
212
  end
182
213
 
183
- it 'is true if same queries, different order' do
184
- expect(URIChecker.query_matches?('foo&bar', 'bar&foo')).to be_truthy
214
+ it "is true if same queries, different order" do
215
+ expect(URIChecker.query_matches?("foo&bar", "bar&foo")).to be_truthy
185
216
  end
186
217
 
187
- it 'is false if one different query' do
188
- expect(URIChecker.query_matches?('foo&bang', 'foo&bing')).to be_falsey
218
+ it "is false if one different query" do
219
+ expect(URIChecker.query_matches?("foo&bang", "foo&bing")).to be_falsey
189
220
  end
190
221
 
191
- it 'is true if same query with same value' do
192
- expect(URIChecker.query_matches?('foo=bar', 'foo=bar')).to be_truthy
222
+ it "is true if same query with same value" do
223
+ expect(URIChecker.query_matches?("foo=bar", "foo=bar")).to be_truthy
193
224
  end
194
225
 
195
- it 'is true if same queries with same values' do
196
- expect(URIChecker.query_matches?('foo=bar&bing=bang', 'foo=bar&bing=bang')).to be_truthy
226
+ it "is true if same queries with same values" do
227
+ expect(URIChecker.query_matches?("foo=bar&bing=bang", "foo=bar&bing=bang")).to be_truthy
197
228
  end
198
229
 
199
- it 'is true if same queries with same values, different order' do
200
- expect(URIChecker.query_matches?('foo=bar&bing=bang', 'bing=bang&foo=bar')).to be_truthy
230
+ it "is true if same queries with same values, different order" do
231
+ expect(URIChecker.query_matches?("foo=bar&bing=bang", "bing=bang&foo=bar")).to be_truthy
201
232
  end
202
233
 
203
- it 'is false if same query with different value' do
204
- expect(URIChecker.query_matches?('foo=bar', 'foo=bang')).to be_falsey
234
+ it "is false if same query with different value" do
235
+ expect(URIChecker.query_matches?("foo=bar", "foo=bang")).to be_falsey
205
236
  end
206
237
 
207
- it 'is false if some queries missing' do
208
- expect(URIChecker.query_matches?('foo=bar', 'foo=bar&bing=bang')).to be_falsey
238
+ it "is false if some queries missing" do
239
+ expect(URIChecker.query_matches?("foo=bar", "foo=bar&bing=bang")).to be_falsey
209
240
  end
210
241
 
211
- it 'is false if some queries different value' do
212
- expect(URIChecker.query_matches?('foo=bar&bing=bang', 'foo=bar&bing=banana')).to be_falsey
242
+ it "is false if some queries different value" do
243
+ expect(URIChecker.query_matches?("foo=bar&bing=bang", "foo=bar&bing=banana")).to be_falsey
213
244
  end
214
245
  end
215
246
  end