doorkeeper 4.2.5 → 5.0.0.rc1

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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +25 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +17 -0
  4. data/.gitignore +2 -1
  5. data/.hound.yml +2 -13
  6. data/.rubocop.yml +17 -0
  7. data/.travis.yml +19 -4
  8. data/Appraisals +8 -4
  9. data/CODE_OF_CONDUCT.md +46 -0
  10. data/Gemfile +1 -1
  11. data/NEWS.md +81 -0
  12. data/README.md +169 -34
  13. data/RELEASING.md +5 -12
  14. data/Rakefile +6 -0
  15. data/SECURITY.md +15 -0
  16. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  17. data/app/controllers/doorkeeper/application_controller.rb +2 -5
  18. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -0
  19. data/app/controllers/doorkeeper/applications_controller.rb +47 -13
  20. data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
  21. data/app/controllers/doorkeeper/authorized_applications_controller.rb +15 -1
  22. data/app/controllers/doorkeeper/tokens_controller.rb +15 -7
  23. data/app/helpers/doorkeeper/dashboard_helper.rb +8 -6
  24. data/app/validators/redirect_uri_validator.rb +13 -2
  25. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  26. data/app/views/doorkeeper/applications/_form.html.erb +31 -19
  27. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  28. data/app/views/doorkeeper/applications/index.html.erb +18 -6
  29. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  30. data/app/views/doorkeeper/applications/show.html.erb +8 -5
  31. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  32. data/app/views/doorkeeper/authorizations/new.html.erb +5 -1
  33. data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
  34. data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
  35. data/config/locales/en.yml +18 -6
  36. data/doorkeeper.gemspec +6 -6
  37. data/gemfiles/rails_4_2.gemfile +6 -4
  38. data/gemfiles/rails_5_0.gemfile +4 -4
  39. data/gemfiles/rails_5_1.gemfile +6 -7
  40. data/gemfiles/rails_5_2.gemfile +12 -0
  41. data/gemfiles/rails_master.gemfile +14 -0
  42. data/lib/doorkeeper/config.rb +107 -68
  43. data/lib/doorkeeper/engine.rb +7 -3
  44. data/lib/doorkeeper/errors.rb +20 -5
  45. data/lib/doorkeeper/grape/helpers.rb +14 -9
  46. data/lib/doorkeeper/helpers/controller.rb +16 -22
  47. data/lib/doorkeeper/models/access_grant_mixin.rb +52 -23
  48. data/lib/doorkeeper/models/access_token_mixin.rb +51 -52
  49. data/lib/doorkeeper/models/application_mixin.rb +16 -30
  50. data/lib/doorkeeper/models/concerns/expirable.rb +7 -5
  51. data/lib/doorkeeper/models/concerns/orderable.rb +13 -0
  52. data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
  53. data/lib/doorkeeper/oauth/authorization/code.rb +31 -8
  54. data/lib/doorkeeper/oauth/authorization/context.rb +15 -0
  55. data/lib/doorkeeper/oauth/authorization/token.rb +41 -20
  56. data/lib/doorkeeper/oauth/authorization_code_request.rb +33 -3
  57. data/lib/doorkeeper/oauth/base_request.rb +22 -7
  58. data/lib/doorkeeper/oauth/client/credentials.rb +6 -4
  59. data/lib/doorkeeper/oauth/client.rb +2 -2
  60. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +6 -1
  61. data/lib/doorkeeper/oauth/client_credentials/validation.rb +4 -2
  62. data/lib/doorkeeper/oauth/error.rb +2 -2
  63. data/lib/doorkeeper/oauth/error_response.rb +11 -4
  64. data/lib/doorkeeper/oauth/forbidden_token_response.rb +1 -1
  65. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +0 -8
  66. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +15 -0
  67. data/lib/doorkeeper/oauth/invalid_token_response.rb +3 -4
  68. data/lib/doorkeeper/oauth/password_access_token_request.rb +8 -4
  69. data/lib/doorkeeper/oauth/pre_authorization.rb +45 -13
  70. data/lib/doorkeeper/oauth/refresh_token_request.rb +7 -1
  71. data/lib/doorkeeper/oauth/scopes.rb +19 -9
  72. data/lib/doorkeeper/oauth/token.rb +6 -3
  73. data/lib/doorkeeper/oauth/token_introspection.rb +128 -0
  74. data/lib/doorkeeper/oauth/token_response.rb +4 -2
  75. data/lib/doorkeeper/oauth.rb +13 -0
  76. data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -0
  77. data/lib/doorkeeper/orm/active_record/access_token.rb +21 -20
  78. data/lib/doorkeeper/orm/active_record/application.rb +34 -0
  79. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
  80. data/lib/doorkeeper/orm/active_record.rb +21 -8
  81. data/lib/doorkeeper/rails/helpers.rb +7 -10
  82. data/lib/doorkeeper/rails/routes.rb +21 -7
  83. data/lib/doorkeeper/rake/db.rake +40 -0
  84. data/lib/doorkeeper/rake/setup.rake +6 -0
  85. data/lib/doorkeeper/rake.rb +14 -0
  86. data/lib/doorkeeper/request/password.rb +1 -11
  87. data/lib/doorkeeper/request.rb +29 -23
  88. data/lib/doorkeeper/validations.rb +3 -2
  89. data/lib/doorkeeper/version.rb +14 -1
  90. data/lib/doorkeeper.rb +6 -17
  91. data/lib/generators/doorkeeper/application_owner_generator.rb +26 -12
  92. data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
  93. data/lib/generators/doorkeeper/install_generator.rb +17 -9
  94. data/lib/generators/doorkeeper/migration_generator.rb +26 -9
  95. data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
  96. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +31 -20
  97. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  98. data/lib/generators/doorkeeper/templates/{add_owner_to_application_migration.rb → add_owner_to_application_migration.rb.erb} +1 -1
  99. data/lib/generators/doorkeeper/templates/{add_previous_refresh_token_to_access_tokens.rb → add_previous_refresh_token_to_access_tokens.rb.erb} +1 -1
  100. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
  101. data/lib/generators/doorkeeper/templates/initializer.rb +88 -10
  102. data/lib/generators/doorkeeper/templates/{migration.rb → migration.rb.erb} +2 -1
  103. data/lib/generators/doorkeeper/views_generator.rb +3 -1
  104. data/spec/controllers/application_metal_controller_spec.rb +50 -0
  105. data/spec/controllers/applications_controller_spec.rb +141 -17
  106. data/spec/controllers/authorizations_controller_spec.rb +277 -27
  107. data/spec/controllers/protected_resources_controller_spec.rb +44 -35
  108. data/spec/controllers/token_info_controller_spec.rb +17 -21
  109. data/spec/controllers/tokens_controller_spec.rb +142 -10
  110. data/spec/dummy/app/assets/config/manifest.js +2 -0
  111. data/spec/dummy/config/environments/test.rb +4 -5
  112. data/spec/dummy/config/initializers/doorkeeper.rb +18 -1
  113. data/spec/dummy/config/initializers/{active_record_belongs_to_required_by_default.rb → new_framework_defaults.rb} +5 -1
  114. data/spec/dummy/config/initializers/secret_token.rb +0 -1
  115. data/spec/dummy/config/routes.rb +3 -42
  116. data/spec/dummy/db/migrate/20111122132257_create_users.rb +3 -1
  117. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +3 -1
  118. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -1
  119. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +3 -1
  120. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +3 -1
  121. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
  122. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +13 -0
  123. data/spec/dummy/db/schema.rb +38 -37
  124. data/spec/factories.rb +1 -1
  125. data/spec/generators/application_owner_generator_spec.rb +25 -6
  126. data/spec/generators/confidential_applications_generator_spec.rb +45 -0
  127. data/spec/generators/install_generator_spec.rb +1 -1
  128. data/spec/generators/migration_generator_spec.rb +25 -4
  129. data/spec/generators/pkce_generator_spec.rb +43 -0
  130. data/spec/generators/previous_refresh_token_generator_spec.rb +57 -0
  131. data/spec/generators/views_generator_spec.rb +1 -1
  132. data/spec/grape/grape_integration_spec.rb +135 -0
  133. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +2 -2
  134. data/spec/lib/config_spec.rb +170 -22
  135. data/spec/lib/doorkeeper_spec.rb +1 -126
  136. data/spec/lib/models/expirable_spec.rb +0 -4
  137. data/spec/lib/models/revocable_spec.rb +2 -4
  138. data/spec/lib/models/scopes_spec.rb +0 -4
  139. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
  140. data/spec/lib/oauth/authorization_code_request_spec.rb +63 -13
  141. data/spec/lib/oauth/base_request_spec.rb +19 -10
  142. data/spec/lib/oauth/base_response_spec.rb +1 -1
  143. data/spec/lib/oauth/client/credentials_spec.rb +5 -5
  144. data/spec/lib/oauth/client_credentials/creator_spec.rb +6 -2
  145. data/spec/lib/oauth/client_credentials/issuer_spec.rb +26 -7
  146. data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -3
  147. data/spec/lib/oauth/client_credentials_integration_spec.rb +2 -2
  148. data/spec/lib/oauth/client_credentials_request_spec.rb +4 -5
  149. data/spec/lib/oauth/client_spec.rb +0 -3
  150. data/spec/lib/oauth/code_request_spec.rb +5 -5
  151. data/spec/lib/oauth/error_response_spec.rb +0 -3
  152. data/spec/lib/oauth/error_spec.rb +1 -3
  153. data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
  154. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -3
  155. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
  156. data/spec/lib/oauth/helpers/uri_checker_spec.rb +115 -3
  157. data/spec/lib/oauth/invalid_token_response_spec.rb +2 -5
  158. data/spec/lib/oauth/password_access_token_request_spec.rb +46 -5
  159. data/spec/lib/oauth/pre_authorization_spec.rb +40 -6
  160. data/spec/lib/oauth/refresh_token_request_spec.rb +30 -14
  161. data/spec/lib/oauth/scopes_spec.rb +28 -4
  162. data/spec/lib/oauth/token_request_spec.rb +10 -13
  163. data/spec/lib/oauth/token_response_spec.rb +0 -1
  164. data/spec/lib/oauth/token_spec.rb +37 -14
  165. data/spec/lib/orm/active_record/stale_records_cleaner_spec.rb +79 -0
  166. data/spec/lib/request/strategy_spec.rb +0 -1
  167. data/spec/lib/server_spec.rb +10 -0
  168. data/spec/models/doorkeeper/access_grant_spec.rb +2 -2
  169. data/spec/models/doorkeeper/access_token_spec.rb +118 -60
  170. data/spec/models/doorkeeper/application_spec.rb +101 -23
  171. data/spec/requests/applications/applications_request_spec.rb +94 -6
  172. data/spec/requests/applications/authorized_applications_spec.rb +1 -1
  173. data/spec/requests/endpoints/authorization_spec.rb +1 -1
  174. data/spec/requests/endpoints/token_spec.rb +15 -6
  175. data/spec/requests/flows/authorization_code_errors_spec.rb +12 -2
  176. data/spec/requests/flows/authorization_code_spec.rb +198 -1
  177. data/spec/requests/flows/client_credentials_spec.rb +73 -5
  178. data/spec/requests/flows/implicit_grant_errors_spec.rb +3 -3
  179. data/spec/requests/flows/implicit_grant_spec.rb +38 -11
  180. data/spec/requests/flows/password_spec.rb +160 -24
  181. data/spec/requests/flows/refresh_token_spec.rb +6 -6
  182. data/spec/requests/flows/revoke_token_spec.rb +26 -26
  183. data/spec/requests/flows/skip_authorization_spec.rb +16 -11
  184. data/spec/requests/protected_resources/metal_spec.rb +2 -2
  185. data/spec/requests/protected_resources/private_api_spec.rb +2 -2
  186. data/spec/routing/custom_controller_routes_spec.rb +63 -7
  187. data/spec/routing/default_routes_spec.rb +6 -2
  188. data/spec/routing/scoped_routes_spec.rb +16 -2
  189. data/spec/spec_helper.rb +54 -3
  190. data/spec/spec_helper_integration.rb +2 -64
  191. data/spec/support/dependencies/factory_bot.rb +2 -0
  192. data/spec/support/doorkeeper_rspec.rb +19 -0
  193. data/spec/support/helpers/access_token_request_helper.rb +1 -1
  194. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  195. data/spec/support/helpers/model_helper.rb +9 -4
  196. data/spec/support/helpers/request_spec_helper.rb +10 -6
  197. data/spec/support/helpers/url_helper.rb +15 -10
  198. data/spec/support/http_method_shim.rb +12 -16
  199. data/spec/support/shared/controllers_shared_context.rb +2 -6
  200. data/spec/support/shared/models_shared_examples.rb +4 -4
  201. data/spec/validators/redirect_uri_validator_spec.rb +58 -7
  202. data/spec/version/version_spec.rb +15 -0
  203. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  204. metadata +74 -34
  205. data/spec/controllers/application_metal_controller.rb +0 -10
  206. data/spec/support/dependencies/factory_girl.rb +0 -2
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  feature 'Skip authorization form' do
4
4
  background do
@@ -15,13 +15,24 @@ feature 'Skip authorization form' do
15
15
  end
16
16
 
17
17
  scenario 'skips the authorization and return a new grant code' do
18
- client_is_authorized(@client, @resource_owner, scopes: 'public')
19
- visit authorization_endpoint_url(client: @client)
18
+ client_is_authorized(@client, @resource_owner, scopes: "public")
19
+ visit authorization_endpoint_url(client: @client, scope: "public")
20
+
21
+ i_should_not_see "Authorize"
22
+ client_should_be_authorized @client
23
+ i_should_be_on_client_callback @client
24
+ url_should_have_param "code", Doorkeeper::AccessGrant.first.token
25
+ end
26
+
27
+ scenario "skips the authorization if other scopes are not requested" do
28
+ client_exists scopes: "public read write"
29
+ client_is_authorized(@client, @resource_owner, scopes: "public")
30
+ visit authorization_endpoint_url(client: @client, scope: "public")
20
31
 
21
- i_should_not_see 'Authorize'
32
+ i_should_not_see "Authorize"
22
33
  client_should_be_authorized @client
23
34
  i_should_be_on_client_callback @client
24
- url_should_have_param 'code', Doorkeeper::AccessGrant.first.token
35
+ url_should_have_param "code", Doorkeeper::AccessGrant.first.token
25
36
  end
26
37
 
27
38
  scenario 'does not skip authorization when scopes differ (new request has fewer scopes)' do
@@ -43,12 +54,6 @@ feature 'Skip authorization form' do
43
54
  access_grant_should_have_scopes :public
44
55
  end
45
56
 
46
- scenario 'doesn not skip authorization when scopes are greater' do
47
- client_is_authorized(@client, @resource_owner, scopes: 'public')
48
- visit authorization_endpoint_url(client: @client, scope: 'public write')
49
- i_should_see 'Authorize'
50
- end
51
-
52
57
  scenario 'creates grant with new scope when scopes are greater' do
53
58
  client_is_authorized(@client, @resource_owner, scopes: 'public')
54
59
  visit authorization_endpoint_url(client: @client, scope: 'public write')
@@ -1,8 +1,8 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'ActionController::Metal API' do
4
4
  before do
5
- @client = FactoryGirl.create(:application)
5
+ @client = FactoryBot.create(:application)
6
6
  @resource = User.create!(name: 'Joe', password: 'sekret')
7
7
  @token = client_is_authorized(@client, @resource)
8
8
  end
@@ -1,8 +1,8 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  feature 'Private API' do
4
4
  background do
5
- @client = FactoryGirl.create(:application)
5
+ @client = FactoryBot.create(:application)
6
6
  @resource = User.create!(name: 'Joe', password: 'sekret')
7
7
  @token = client_is_authorized(@client, @resource)
8
8
  end
@@ -1,27 +1,79 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'Custom controller for routes' do
4
- it 'GET /space/scope/authorize routes to custom authorizations controller' do
4
+ before :all do
5
+ Rails.application.routes.disable_clear_and_finalize = true
6
+
7
+ Rails.application.routes.draw do
8
+ scope 'inner_space' do
9
+ use_doorkeeper scope: 'scope' do
10
+ controllers authorizations: 'custom_authorizations',
11
+ tokens: 'custom_authorizations',
12
+ applications: 'custom_authorizations',
13
+ token_info: 'custom_authorizations'
14
+
15
+ as authorizations: 'custom_auth',
16
+ tokens: 'custom_token',
17
+ token_info: 'custom_token_info'
18
+ end
19
+ end
20
+
21
+ scope 'space' do
22
+ use_doorkeeper do
23
+ controllers authorizations: 'custom_authorizations',
24
+ tokens: 'custom_authorizations',
25
+ applications: 'custom_authorizations',
26
+ token_info: 'custom_authorizations'
27
+
28
+ as authorizations: 'custom_auth',
29
+ tokens: 'custom_token',
30
+ token_info: 'custom_token_info'
31
+ end
32
+ end
33
+
34
+ scope 'outer_space' do
35
+ use_doorkeeper do
36
+ controllers authorizations: 'custom_authorizations',
37
+ tokens: 'custom_authorizations',
38
+ token_info: 'custom_authorizations'
39
+
40
+ as authorizations: 'custom_auth',
41
+ tokens: 'custom_token',
42
+ token_info: 'custom_token_info'
43
+
44
+ skip_controllers :tokens, :applications, :token_info
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ after :all do
51
+ Rails.application.routes.clear!
52
+
53
+ load File.expand_path('../dummy/config/routes.rb', __dir__)
54
+ end
55
+
56
+ it 'GET /inner_space/scope/authorize routes to custom authorizations controller' do
5
57
  expect(get('/inner_space/scope/authorize')).to route_to('custom_authorizations#new')
6
58
  end
7
59
 
8
- it 'POST /space/scope/authorize routes to custom authorizations controller' do
60
+ it 'POST /inner_space/scope/authorize routes to custom authorizations controller' do
9
61
  expect(post('/inner_space/scope/authorize')).to route_to('custom_authorizations#create')
10
62
  end
11
63
 
12
- it 'DELETE /space/scope/authorize routes to custom authorizations controller' do
64
+ it 'DELETE /inner_space/scope/authorize routes to custom authorizations controller' do
13
65
  expect(delete('/inner_space/scope/authorize')).to route_to('custom_authorizations#destroy')
14
66
  end
15
67
 
16
- it 'POST /space/scope/token routes to tokens controller' do
68
+ it 'POST /inner_space/scope/token routes to tokens controller' do
17
69
  expect(post('/inner_space/scope/token')).to route_to('custom_authorizations#create')
18
70
  end
19
71
 
20
- it 'GET /space/scope/applications routes to applications controller' do
72
+ it 'GET /inner_space/scope/applications routes to applications controller' do
21
73
  expect(get('/inner_space/scope/applications')).to route_to('custom_authorizations#index')
22
74
  end
23
75
 
24
- it 'GET /space/scope/token/info routes to the token_info controller' do
76
+ it 'GET /inner_space/scope/token/info routes to the token_info controller' do
25
77
  expect(get('/inner_space/scope/token/info')).to route_to('custom_authorizations#show')
26
78
  end
27
79
 
@@ -45,6 +97,10 @@ describe 'Custom controller for routes' do
45
97
  expect(post('/space/oauth/revoke')).to route_to('custom_authorizations#revoke')
46
98
  end
47
99
 
100
+ it 'POST /space/oauth/introspect routes to tokens controller' do
101
+ expect(post('/space/oauth/introspect')).to route_to('custom_authorizations#introspect')
102
+ end
103
+
48
104
  it 'GET /space/oauth/applications routes to applications controller' do
49
105
  expect(get('/space/oauth/applications')).to route_to('custom_authorizations#index')
50
106
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'Default routes' do
4
4
  it 'GET /oauth/authorize routes to authorizations controller' do
@@ -21,6 +21,10 @@ describe 'Default routes' do
21
21
  expect(post('/oauth/revoke')).to route_to('doorkeeper/tokens#revoke')
22
22
  end
23
23
 
24
+ it 'POST /oauth/introspect routes to tokens controller' do
25
+ expect(post('/oauth/introspect')).to route_to('doorkeeper/tokens#introspect')
26
+ end
27
+
24
28
  it 'GET /oauth/applications routes to applications controller' do
25
29
  expect(get('/oauth/applications')).to route_to('doorkeeper/applications#index')
26
30
  end
@@ -29,7 +33,7 @@ describe 'Default routes' do
29
33
  expect(get('/oauth/authorized_applications')).to route_to('doorkeeper/authorized_applications#index')
30
34
  end
31
35
 
32
- it 'GET /oauth/token/info route to authorzed tokeninfo controller' do
36
+ it 'GET /oauth/token/info route to authorized TokenInfo controller' do
33
37
  expect(get('/oauth/token/info')).to route_to('doorkeeper/token_info#show')
34
38
  end
35
39
  end
@@ -1,6 +1,20 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'Scoped routes' do
4
+ before :all do
5
+ Rails.application.routes.disable_clear_and_finalize = true
6
+
7
+ Rails.application.routes.draw do
8
+ use_doorkeeper scope: 'scope'
9
+ end
10
+ end
11
+
12
+ after :all do
13
+ Rails.application.routes.clear!
14
+
15
+ load File.expand_path('../dummy/config/routes.rb', __dir__)
16
+ end
17
+
4
18
  it 'GET /scope/authorize routes to authorizations controller' do
5
19
  expect(get('/scope/authorize')).to route_to('doorkeeper/authorizations#new')
6
20
  end
@@ -25,7 +39,7 @@ describe 'Scoped routes' do
25
39
  expect(get('/scope/authorized_applications')).to route_to('doorkeeper/authorized_applications#index')
26
40
  end
27
41
 
28
- it 'GET /scope/token/info route to authorzed tokeninfo controller' do
42
+ it 'GET /scope/token/info route to authorized TokenInfo controller' do
29
43
  expect(get('/scope/token/info')).to route_to('doorkeeper/token_info#show')
30
44
  end
31
45
  end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,55 @@
1
- $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '../lib'))
2
- $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '../app'))
1
+ require 'coveralls'
3
2
 
4
- require 'doorkeeper'
3
+ Coveralls.wear!('rails') do
4
+ add_filter('/spec/')
5
+ add_filter('/lib/generators/doorkeeper/templates/')
6
+ end
7
+
8
+ ENV['RAILS_ENV'] ||= 'test'
9
+
10
+ $LOAD_PATH.unshift File.dirname(__FILE__)
11
+
12
+ require "#{File.dirname(__FILE__)}/support/doorkeeper_rspec.rb"
13
+
14
+ DOORKEEPER_ORM = Doorkeeper::RSpec.detect_orm
15
+
16
+ require 'dummy/config/environment'
17
+ require 'rspec/rails'
18
+ require 'capybara/rspec'
19
+ require 'database_cleaner'
20
+ require 'generator_spec/test_case'
21
+
22
+ # Load JRuby SQLite3 if in that platform
23
+ if defined? JRUBY_VERSION
24
+ require 'jdbc/sqlite3'
25
+ Jdbc::SQLite3.load_driver
26
+ end
27
+
28
+ Doorkeeper::RSpec.print_configuration_info
29
+
30
+ # Remove after dropping support of Rails 4.2
31
+ require "#{File.dirname(__FILE__)}/support/http_method_shim.rb"
32
+
33
+ require "support/orm/#{DOORKEEPER_ORM}"
34
+
35
+ Dir["#{File.dirname(__FILE__)}/support/{dependencies,helpers,shared}/*.rb"].each { |file| require file }
36
+
37
+ RSpec.configure do |config|
38
+ config.infer_spec_type_from_file_location!
39
+ config.mock_with :rspec
40
+
41
+ config.infer_base_class_for_anonymous_controllers = false
42
+
43
+ config.include RSpec::Rails::RequestExampleGroup, type: :request
44
+
45
+ config.before do
46
+ DatabaseCleaner.start
47
+ Doorkeeper.configure { orm DOORKEEPER_ORM }
48
+ end
49
+
50
+ config.after do
51
+ DatabaseCleaner.clean
52
+ end
53
+
54
+ config.order = 'random'
55
+ end
@@ -1,64 +1,2 @@
1
- if ENV['TRAVIS']
2
- require 'coveralls'
3
- Coveralls.wear!('rails') { add_filter('/spec/') }
4
- end
5
-
6
- ENV['RAILS_ENV'] ||= 'test'
7
- TABLE_NAME_PREFIX = ENV['table_name_prefix'] || nil
8
- TABLE_NAME_SUFFIX = ENV['table_name_suffix'] || nil
9
-
10
- orm = (ENV['BUNDLE_GEMFILE'] || '').match(/Gemfile\.(.+)\.rb/)
11
- DOORKEEPER_ORM = (orm && orm[1] || :active_record).to_sym
12
-
13
- $LOAD_PATH.unshift File.dirname(__FILE__)
14
-
15
- require 'capybara/rspec'
16
- require 'dummy/config/environment'
17
- require 'rspec/rails'
18
- require 'generator_spec/test_case'
19
- require 'timecop'
20
- require 'database_cleaner'
21
-
22
- # Load JRuby SQLite3 if in that platform
23
- begin
24
- require 'jdbc/sqlite3'
25
- Jdbc::SQLite3.load_driver
26
- rescue LoadError
27
- end
28
-
29
- Rails.logger.info "====> Doorkeeper.orm = #{Doorkeeper.configuration.orm.inspect}"
30
- if Doorkeeper.configuration.orm == :active_record
31
- Rails.logger.info "======> active_record.table_name_prefix = #{Rails.configuration.active_record.table_name_prefix.inspect}"
32
- Rails.logger.info "======> active_record.table_name_suffix = #{Rails.configuration.active_record.table_name_suffix.inspect}"
33
- end
34
- Rails.logger.info "====> Rails version: #{Rails.version}"
35
- Rails.logger.info "====> Ruby version: #{RUBY_VERSION}"
36
-
37
- require "support/orm/#{DOORKEEPER_ORM}"
38
-
39
- ENGINE_RAILS_ROOT = File.join(File.dirname(__FILE__), '../')
40
-
41
- Dir["#{File.dirname(__FILE__)}/support/{dependencies,helpers,shared}/*.rb"].each { |f| require f }
42
-
43
- # Remove after dropping support of Rails 4.2
44
- require "#{File.dirname(__FILE__)}/support/http_method_shim.rb"
45
-
46
- RSpec.configure do |config|
47
- config.infer_spec_type_from_file_location!
48
- config.mock_with :rspec
49
-
50
- config.infer_base_class_for_anonymous_controllers = false
51
-
52
- config.include RSpec::Rails::RequestExampleGroup, type: :request
53
-
54
- config.before do
55
- DatabaseCleaner.start
56
- Doorkeeper.configure { orm DOORKEEPER_ORM }
57
- end
58
-
59
- config.after do
60
- DatabaseCleaner.clean
61
- end
62
-
63
- config.order = 'random'
64
- end
1
+ # For compatibility only
2
+ require 'spec_helper'
@@ -0,0 +1,2 @@
1
+ require 'factory_bot'
2
+ FactoryBot.find_definitions
@@ -0,0 +1,19 @@
1
+ module Doorkeeper
2
+ class RSpec
3
+ # Print's useful information about env: Ruby / Rails versions,
4
+ # Doorkeeper configuration, etc.
5
+ def self.print_configuration_info
6
+ puts <<-INFO.strip_heredoc
7
+ ====> Doorkeeper ORM = #{Doorkeeper.configuration.orm}
8
+ ====> Rails version: #{::Rails.version}
9
+ ====> Ruby version: #{RUBY_VERSION} on #{RUBY_PLATFORM}
10
+ INFO
11
+ end
12
+
13
+ # Tries to find ORM from the Gemfile used to run test suite
14
+ def self.detect_orm
15
+ orm = (ENV['BUNDLE_GEMFILE'] || '').match(/Gemfile\.(.+)\.rb/)
16
+ (orm && orm[1] || :active_record).to_sym
17
+ end
18
+ end
19
+ end
@@ -4,7 +4,7 @@ module AccessTokenRequestHelper
4
4
  application: client,
5
5
  resource_owner_id: resource_owner.id
6
6
  }.merge(access_token_attributes)
7
- FactoryGirl.create(:access_token, attributes)
7
+ FactoryBot.create(:access_token, attributes)
8
8
  end
9
9
  end
10
10
 
@@ -28,13 +28,13 @@ module AuthorizationRequestHelper
28
28
  expect(client.redirect_uri).to eq("#{current_uri.scheme}://#{current_uri.host}#{current_uri.path}")
29
29
  end
30
30
 
31
- def allowing_forgery_protection(&block)
32
- _original_value = ActionController::Base.allow_forgery_protection
31
+ def allowing_forgery_protection(&_block)
32
+ original_value = ActionController::Base.allow_forgery_protection
33
33
  ActionController::Base.allow_forgery_protection = true
34
34
 
35
- block.call
35
+ yield
36
36
  ensure
37
- ActionController::Base.allow_forgery_protection = _original_value
37
+ ActionController::Base.allow_forgery_protection = original_value
38
38
  end
39
39
  end
40
40
 
@@ -1,6 +1,6 @@
1
1
  module ModelHelper
2
2
  def client_exists(client_attributes = {})
3
- @client = FactoryGirl.create(:application, client_attributes)
3
+ @client = FactoryBot.create(:application, client_attributes)
4
4
  end
5
5
 
6
6
  def create_resource_owner
@@ -8,7 +8,7 @@ module ModelHelper
8
8
  end
9
9
 
10
10
  def authorization_code_exists(options = {})
11
- @authorization = FactoryGirl.create(:access_grant, options)
11
+ @authorization = FactoryBot.create(:access_grant, options)
12
12
  end
13
13
 
14
14
  def access_grant_should_exist_for(client, resource_owner)
@@ -55,9 +55,14 @@ module ModelHelper
55
55
  error_classes = [Sequel::UniqueConstraintViolation, Sequel::ValidationFailed]
56
56
  proc { |error| expect(error.class).to be_in(error_classes) }
57
57
  when :mongo_mapper
58
- MongoMapper::DocumentNotValid
58
+ error_classes = [MongoMapper::DocumentNotValid, Mongo::OperationFailure]
59
+ proc { |error| expect(error.class).to be_in(error_classes) }
59
60
  when /mongoid/
60
- Mongoid::Errors::Validations
61
+ error_classes = [Mongoid::Errors::Validations]
62
+ error_classes << Moped::Errors::OperationFailure if defined?(::Moped) # Mongoid 4
63
+ error_classes << Mongo::Error::OperationFailure if defined?(::Mongo) # Mongoid 5
64
+
65
+ proc { |error| expect(error.class).to be_in(error_classes) }
61
66
  else
62
67
  raise "'#{DOORKEEPER_ORM}' ORM is not supported!"
63
68
  end
@@ -31,6 +31,10 @@ module RequestSpecHelper
31
31
  respond_to?(:response) ? response : page.driver.response
32
32
  end
33
33
 
34
+ def json_response
35
+ JSON.parse(request_response.body)
36
+ end
37
+
34
38
  def should_have_header(header, value)
35
39
  expect(headers[header]).to eq(value)
36
40
  end
@@ -48,15 +52,15 @@ module RequestSpecHelper
48
52
  end
49
53
 
50
54
  def should_have_json(key, value)
51
- expect(JSON.parse(request_response.body).fetch(key)).to eq(value)
55
+ expect(json_response.fetch(key)).to eq(value)
52
56
  end
53
57
 
54
58
  def should_have_json_within(key, value, range)
55
- expect(JSON.parse(request_response.body).fetch(key)).to be_within(range).of(value)
59
+ expect(json_response.fetch(key)).to be_within(range).of(value)
56
60
  end
57
61
 
58
62
  def should_not_have_json(key)
59
- expect(JSON.parse(request_response.body)).not_to have_key(key)
63
+ expect(json_response).not_to have_key(key)
60
64
  end
61
65
 
62
66
  def sign_in
@@ -64,8 +68,8 @@ module RequestSpecHelper
64
68
  click_on 'Sign in'
65
69
  end
66
70
 
67
- def create_access_token(authorization_code, client)
68
- page.driver.post token_endpoint_url(code: authorization_code, client: client)
71
+ def create_access_token(authorization_code, client, code_verifier = nil)
72
+ page.driver.post token_endpoint_url(code: authorization_code, client: client, code_verifier: code_verifier)
69
73
  end
70
74
 
71
75
  def i_should_see_translated_error_message(key)
@@ -73,7 +77,7 @@ module RequestSpecHelper
73
77
  end
74
78
 
75
79
  def translated_error_message(key)
76
- I18n.translate key, scope: [:doorkeeper, :errors, :messages]
80
+ I18n.translate key, scope: %i[doorkeeper errors messages]
77
81
  end
78
82
 
79
83
  def response_status_should_be(status)
@@ -2,21 +2,24 @@ module UrlHelper
2
2
  def token_endpoint_url(options = {})
3
3
  parameters = {
4
4
  code: options[:code],
5
- client_id: options[:client_id] || (options[:client] ? options[:client].uid : nil),
5
+ client_id: options[:client_id] || (options[:client] ? options[:client].uid : nil),
6
6
  client_secret: options[:client_secret] || (options[:client] ? options[:client].secret : nil),
7
7
  redirect_uri: options[:redirect_uri] || (options[:client] ? options[:client].redirect_uri : nil),
8
- grant_type: options[:grant_type] || 'authorization_code'
9
- }
8
+ grant_type: options[:grant_type] || 'authorization_code',
9
+ code_verifier: options[:code_verifier],
10
+ code_challenge_method: options[:code_challenge_method]
11
+ }.reject { |_, v| v.blank? }
10
12
  "/oauth/token?#{build_query(parameters)}"
11
13
  end
12
14
 
13
15
  def password_token_endpoint_url(options = {})
14
16
  parameters = {
15
17
  code: options[:code],
16
- client_id: options[:client_id] || (options[:client] ? options[:client].uid : nil),
18
+ client_id: options[:client_id] || (options[:client] ? options[:client].uid : nil),
17
19
  client_secret: options[:client_secret] || (options[:client] ? options[:client].secret : nil),
18
20
  username: options[:resource_owner_username] || (options[:resource_owner] ? options[:resource_owner].name : nil),
19
21
  password: options[:resource_owner_password] || (options[:resource_owner] ? options[:resource_owner].password : nil),
22
+ scope: options[:scope],
20
23
  grant_type: 'password'
21
24
  }
22
25
  "/oauth/token?#{build_query(parameters)}"
@@ -24,21 +27,23 @@ module UrlHelper
24
27
 
25
28
  def authorization_endpoint_url(options = {})
26
29
  parameters = {
27
- client_id: options[:client_id] || options[:client].uid,
28
- redirect_uri: options[:redirect_uri] || options[:client].redirect_uri,
30
+ client_id: options[:client_id] || options[:client].uid,
31
+ redirect_uri: options[:redirect_uri] || options[:client].redirect_uri,
29
32
  response_type: options[:response_type] || 'code',
30
33
  scope: options[:scope],
31
- state: options[:state]
32
- }.reject { |k, v| v.blank? }
34
+ state: options[:state],
35
+ code_challenge: options[:code_challenge],
36
+ code_challenge_method: options[:code_challenge_method]
37
+ }.reject { |_, v| v.blank? }
33
38
  "/oauth/authorize?#{build_query(parameters)}"
34
39
  end
35
40
 
36
41
  def refresh_token_endpoint_url(options = {})
37
42
  parameters = {
38
43
  refresh_token: options[:refresh_token],
39
- client_id: options[:client_id] || options[:client].uid,
44
+ client_id: options[:client_id] || options[:client].uid,
40
45
  client_secret: options[:client_secret] || options[:client].secret,
41
- grant_type: options[:grant_type] || 'refresh_token'
46
+ grant_type: options[:grant_type] || 'refresh_token'
42
47
  }
43
48
  "/oauth/token?#{build_query(parameters)}"
44
49
  end
@@ -3,34 +3,30 @@
3
3
  # supported in Rails 5+. Since we support back to 4, we need some sort of shim
4
4
  # to avoid super noisy deprecations when running tests.
5
5
  module RoutingHTTPMethodShim
6
- def get(path, params = {}, headers = nil)
7
- super(path, params: params, headers: headers)
6
+ def get(path, **args)
7
+ super(path, args[:params], args[:headers])
8
8
  end
9
9
 
10
- def post(path, params = {}, headers = nil)
11
- super(path, params: params, headers: headers)
10
+ def post(path, **args)
11
+ super(path, args[:params], args[:headers])
12
12
  end
13
13
 
14
- def put(path, params = {}, headers = nil)
15
- super(path, params: params, headers: headers)
14
+ def put(path, **args)
15
+ super(path, args[:params], args[:headers])
16
16
  end
17
17
  end
18
18
 
19
19
  module ControllerHTTPMethodShim
20
- def get(path, params = {})
21
- super(path, params: params)
22
- end
23
-
24
- def post(path, params = {})
25
- super(path, params: params)
26
- end
20
+ def process(action, http_method = 'GET', **args)
21
+ if (as = args.delete(:as))
22
+ @request.headers['Content-Type'] = Mime[as].to_s
23
+ end
27
24
 
28
- def put(path, params = {})
29
- super(path, params: params)
25
+ super(action, http_method, args[:params], args[:session], args[:flash])
30
26
  end
31
27
  end
32
28
 
33
- if ::Rails::VERSION::MAJOR >= 5
29
+ if ::Rails::VERSION::MAJOR < 5
34
30
  RSpec.configure do |config|
35
31
  config.include ControllerHTTPMethodShim, type: :controller
36
32
  config.include RoutingHTTPMethodShim, type: :request
@@ -1,7 +1,5 @@
1
1
  shared_context 'valid token', token: :valid do
2
- let :token_string do
3
- '1A2B3C4D'
4
- end
2
+ let(:token_string) { '1A2B3C4D' }
5
3
 
6
4
  let :token do
7
5
  double(Doorkeeper::AccessToken,
@@ -17,9 +15,7 @@ shared_context 'valid token', token: :valid do
17
15
  end
18
16
 
19
17
  shared_context 'invalid token', token: :invalid do
20
- let :token_string do
21
- '1A2B3C4D'
22
- end
18
+ let(:token_string) { '1A2B3C4D' }
23
19
 
24
20
  let :token do
25
21
  double(Doorkeeper::AccessToken,
@@ -34,15 +34,15 @@ shared_examples 'a unique token' do
34
34
  end
35
35
 
36
36
  it 'is not valid if token exists' do
37
- token1 = FactoryGirl.create factory_name
38
- token2 = FactoryGirl.create factory_name
37
+ token1 = FactoryBot.create factory_name
38
+ token2 = FactoryBot.create factory_name
39
39
  token2.token = token1.token
40
40
  expect(token2).not_to be_valid
41
41
  end
42
42
 
43
43
  it 'expects database to throw an error when tokens are the same' do
44
- token1 = FactoryGirl.create factory_name
45
- token2 = FactoryGirl.create factory_name
44
+ token1 = FactoryBot.create factory_name
45
+ token2 = FactoryBot.create factory_name
46
46
  token2.token = token1.token
47
47
  expect do
48
48
  token2.save!(validate: false)