doorkeeper 4.4.3 → 5.0.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of doorkeeper might be problematic. Click here for more details.

Files changed (223) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.gitlab-ci.yml +16 -0
  4. data/.travis.yml +7 -0
  5. data/Appraisals +2 -2
  6. data/Dangerfile +64 -0
  7. data/Gemfile +1 -1
  8. data/NEWS.md +98 -8
  9. data/README.md +110 -12
  10. data/Rakefile +6 -0
  11. data/UPGRADE.md +2 -0
  12. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  13. data/app/controllers/doorkeeper/application_controller.rb +6 -3
  14. data/app/controllers/doorkeeper/application_metal_controller.rb +6 -0
  15. data/app/controllers/doorkeeper/applications_controller.rb +46 -24
  16. data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
  17. data/app/controllers/doorkeeper/authorized_applications_controller.rb +21 -2
  18. data/app/controllers/doorkeeper/token_info_controller.rb +2 -0
  19. data/app/controllers/doorkeeper/tokens_controller.rb +4 -6
  20. data/app/helpers/doorkeeper/dashboard_helper.rb +9 -7
  21. data/app/validators/redirect_uri_validator.rb +5 -2
  22. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  23. data/app/views/doorkeeper/applications/_form.html.erb +25 -24
  24. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  25. data/app/views/doorkeeper/applications/index.html.erb +17 -7
  26. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  27. data/app/views/doorkeeper/applications/show.html.erb +6 -6
  28. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  29. data/app/views/doorkeeper/authorizations/new.html.erb +4 -0
  30. data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
  31. data/config/locales/en.yml +10 -1
  32. data/doorkeeper.gemspec +25 -26
  33. data/gemfiles/rails_5_2.gemfile +1 -1
  34. data/gemfiles/rails_master.gemfile +4 -1
  35. data/lib/doorkeeper/config.rb +81 -40
  36. data/lib/doorkeeper/engine.rb +6 -0
  37. data/lib/doorkeeper/errors.rb +17 -3
  38. data/lib/doorkeeper/grape/authorization_decorator.rb +2 -0
  39. data/lib/doorkeeper/grape/helpers.rb +3 -1
  40. data/lib/doorkeeper/helpers/controller.rb +9 -2
  41. data/lib/doorkeeper/models/access_grant_mixin.rb +73 -0
  42. data/lib/doorkeeper/models/access_token_mixin.rb +44 -25
  43. data/lib/doorkeeper/models/application_mixin.rb +2 -0
  44. data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
  45. data/lib/doorkeeper/models/concerns/expirable.rb +2 -0
  46. data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
  47. data/lib/doorkeeper/models/concerns/ownership.rb +2 -0
  48. data/lib/doorkeeper/models/concerns/revocable.rb +2 -0
  49. data/lib/doorkeeper/models/concerns/scopes.rb +3 -1
  50. data/lib/doorkeeper/oauth/authorization/code.rb +33 -8
  51. data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
  52. data/lib/doorkeeper/oauth/authorization/token.rb +38 -14
  53. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +2 -0
  54. data/lib/doorkeeper/oauth/authorization_code_request.rb +29 -2
  55. data/lib/doorkeeper/oauth/base_request.rb +22 -9
  56. data/lib/doorkeeper/oauth/base_response.rb +2 -0
  57. data/lib/doorkeeper/oauth/client/credentials.rb +3 -1
  58. data/lib/doorkeeper/oauth/client.rb +1 -1
  59. data/lib/doorkeeper/oauth/client_credentials/creator.rb +4 -1
  60. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -2
  61. data/lib/doorkeeper/oauth/client_credentials/validation.rb +5 -5
  62. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -3
  63. data/lib/doorkeeper/oauth/code_request.rb +2 -0
  64. data/lib/doorkeeper/oauth/code_response.rb +2 -0
  65. data/lib/doorkeeper/oauth/error.rb +2 -0
  66. data/lib/doorkeeper/oauth/error_response.rb +21 -3
  67. data/lib/doorkeeper/oauth/forbidden_token_response.rb +9 -2
  68. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +2 -8
  69. data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -0
  70. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +5 -2
  71. data/lib/doorkeeper/oauth/invalid_token_response.rb +18 -0
  72. data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -4
  73. data/lib/doorkeeper/oauth/pre_authorization.rb +43 -11
  74. data/lib/doorkeeper/oauth/refresh_token_request.rb +16 -3
  75. data/lib/doorkeeper/oauth/scopes.rb +3 -1
  76. data/lib/doorkeeper/oauth/token.rb +7 -2
  77. data/lib/doorkeeper/oauth/token_introspection.rb +4 -2
  78. data/lib/doorkeeper/oauth/token_request.rb +2 -0
  79. data/lib/doorkeeper/oauth/token_response.rb +6 -2
  80. data/lib/doorkeeper/oauth.rb +13 -0
  81. data/lib/doorkeeper/orm/active_record/application.rb +75 -12
  82. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
  83. data/lib/doorkeeper/orm/active_record.rb +4 -0
  84. data/lib/doorkeeper/rails/helpers.rb +6 -4
  85. data/lib/doorkeeper/rails/routes/mapper.rb +2 -0
  86. data/lib/doorkeeper/rails/routes/mapping.rb +2 -0
  87. data/lib/doorkeeper/rails/routes.rb +23 -8
  88. data/lib/doorkeeper/rake/db.rake +40 -0
  89. data/lib/doorkeeper/rake/setup.rake +6 -0
  90. data/lib/doorkeeper/rake.rb +14 -0
  91. data/lib/doorkeeper/request/authorization_code.rb +1 -1
  92. data/lib/doorkeeper/request/client_credentials.rb +1 -1
  93. data/lib/doorkeeper/request/code.rb +1 -1
  94. data/lib/doorkeeper/request/password.rb +1 -1
  95. data/lib/doorkeeper/request/refresh_token.rb +1 -1
  96. data/lib/doorkeeper/request/strategy.rb +2 -0
  97. data/lib/doorkeeper/request/token.rb +1 -1
  98. data/lib/doorkeeper/request.rb +29 -34
  99. data/lib/doorkeeper/server.rb +2 -0
  100. data/lib/doorkeeper/stale_records_cleaner.rb +20 -0
  101. data/lib/doorkeeper/validations.rb +2 -0
  102. data/lib/doorkeeper/version.rb +6 -24
  103. data/lib/doorkeeper.rb +20 -17
  104. data/lib/generators/doorkeeper/application_owner_generator.rb +23 -18
  105. data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
  106. data/lib/generators/doorkeeper/install_generator.rb +17 -9
  107. data/lib/generators/doorkeeper/migration_generator.rb +23 -18
  108. data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
  109. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -24
  110. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  111. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
  112. data/lib/generators/doorkeeper/templates/initializer.rb +96 -13
  113. data/lib/generators/doorkeeper/templates/migration.rb.erb +2 -3
  114. data/lib/generators/doorkeeper/views_generator.rb +3 -1
  115. data/spec/controllers/application_metal_controller_spec.rb +50 -0
  116. data/spec/controllers/applications_controller_spec.rb +123 -14
  117. data/spec/controllers/authorizations_controller_spec.rb +334 -51
  118. data/spec/controllers/protected_resources_controller_spec.rb +60 -18
  119. data/spec/controllers/token_info_controller_spec.rb +4 -12
  120. data/spec/controllers/tokens_controller_spec.rb +17 -20
  121. data/spec/dummy/Rakefile +1 -1
  122. data/spec/dummy/app/assets/config/manifest.js +2 -0
  123. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +1 -1
  124. data/spec/dummy/app/controllers/home_controller.rb +1 -2
  125. data/spec/dummy/config/application.rb +1 -1
  126. data/spec/dummy/config/boot.rb +2 -4
  127. data/spec/dummy/config/environment.rb +1 -1
  128. data/spec/dummy/config/environments/test.rb +5 -6
  129. data/spec/dummy/config/initializers/doorkeeper.rb +12 -6
  130. data/spec/dummy/config/initializers/new_framework_defaults.rb +2 -0
  131. data/spec/dummy/config/initializers/secret_token.rb +1 -1
  132. data/spec/dummy/config/routes.rb +3 -42
  133. data/spec/dummy/config.ru +1 -1
  134. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +4 -4
  135. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +1 -1
  136. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
  137. data/spec/dummy/db/migrate/{20180210183654_add_confidential_to_application.rb → 20180210183654_add_confidential_to_applications.rb} +1 -1
  138. data/spec/dummy/db/schema.rb +36 -36
  139. data/spec/dummy/script/rails +4 -3
  140. data/spec/factories.rb +6 -6
  141. data/spec/generators/application_owner_generator_spec.rb +1 -1
  142. data/spec/generators/confidential_applications_generator_spec.rb +45 -0
  143. data/spec/generators/install_generator_spec.rb +5 -2
  144. data/spec/generators/migration_generator_spec.rb +1 -1
  145. data/spec/generators/pkce_generator_spec.rb +43 -0
  146. data/spec/generators/previous_refresh_token_generator_spec.rb +1 -1
  147. data/spec/generators/templates/routes.rb +0 -1
  148. data/spec/generators/views_generator_spec.rb +2 -2
  149. data/spec/grape/grape_integration_spec.rb +2 -2
  150. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  151. data/spec/lib/config_spec.rb +105 -39
  152. data/spec/lib/doorkeeper_spec.rb +6 -131
  153. data/spec/lib/models/expirable_spec.rb +0 -3
  154. data/spec/lib/models/revocable_spec.rb +0 -2
  155. data/spec/lib/models/scopes_spec.rb +0 -4
  156. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
  157. data/spec/lib/oauth/authorization_code_request_spec.rb +17 -7
  158. data/spec/lib/oauth/base_request_spec.rb +49 -11
  159. data/spec/lib/oauth/base_response_spec.rb +1 -1
  160. data/spec/lib/oauth/client/credentials_spec.rb +2 -4
  161. data/spec/lib/oauth/client_credentials/creator_spec.rb +5 -1
  162. data/spec/lib/oauth/client_credentials/issuer_spec.rb +24 -7
  163. data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
  164. data/spec/lib/oauth/client_credentials_integration_spec.rb +2 -2
  165. data/spec/lib/oauth/client_credentials_request_spec.rb +3 -5
  166. data/spec/lib/oauth/client_spec.rb +0 -3
  167. data/spec/lib/oauth/code_request_spec.rb +5 -3
  168. data/spec/lib/oauth/code_response_spec.rb +1 -1
  169. data/spec/lib/oauth/error_response_spec.rb +0 -3
  170. data/spec/lib/oauth/error_spec.rb +0 -2
  171. data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
  172. data/spec/lib/oauth/helpers/scope_checker_spec.rb +8 -11
  173. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
  174. data/spec/lib/oauth/helpers/uri_checker_spec.rb +22 -13
  175. data/spec/lib/oauth/invalid_token_response_spec.rb +1 -4
  176. data/spec/lib/oauth/password_access_token_request_spec.rb +53 -6
  177. data/spec/lib/oauth/pre_authorization_spec.rb +33 -4
  178. data/spec/lib/oauth/refresh_token_request_spec.rb +22 -14
  179. data/spec/lib/oauth/scopes_spec.rb +0 -3
  180. data/spec/lib/oauth/token_request_spec.rb +8 -9
  181. data/spec/lib/oauth/token_response_spec.rb +0 -1
  182. data/spec/lib/oauth/token_spec.rb +40 -14
  183. data/spec/lib/request/strategy_spec.rb +0 -1
  184. data/spec/lib/server_spec.rb +7 -7
  185. data/spec/lib/stale_records_cleaner_spec.rb +89 -0
  186. data/spec/models/doorkeeper/access_grant_spec.rb +44 -1
  187. data/spec/models/doorkeeper/access_token_spec.rb +80 -32
  188. data/spec/models/doorkeeper/application_spec.rb +293 -221
  189. data/spec/requests/applications/applications_request_spec.rb +134 -1
  190. data/spec/requests/applications/authorized_applications_spec.rb +1 -1
  191. data/spec/requests/endpoints/authorization_spec.rb +3 -3
  192. data/spec/requests/endpoints/token_spec.rb +7 -5
  193. data/spec/requests/flows/authorization_code_errors_spec.rb +2 -2
  194. data/spec/requests/flows/authorization_code_spec.rb +258 -2
  195. data/spec/requests/flows/client_credentials_spec.rb +46 -6
  196. data/spec/requests/flows/implicit_grant_errors_spec.rb +3 -3
  197. data/spec/requests/flows/implicit_grant_spec.rb +38 -11
  198. data/spec/requests/flows/password_spec.rb +61 -3
  199. data/spec/requests/flows/refresh_token_spec.rb +59 -2
  200. data/spec/requests/flows/revoke_token_spec.rb +20 -20
  201. data/spec/requests/flows/skip_authorization_spec.rb +16 -11
  202. data/spec/requests/protected_resources/metal_spec.rb +1 -1
  203. data/spec/requests/protected_resources/private_api_spec.rb +3 -3
  204. data/spec/routing/custom_controller_routes_spec.rb +59 -7
  205. data/spec/routing/default_routes_spec.rb +2 -2
  206. data/spec/routing/scoped_routes_spec.rb +16 -2
  207. data/spec/spec_helper.rb +54 -3
  208. data/spec/spec_helper_integration.rb +2 -74
  209. data/spec/support/dependencies/{factory_girl.rb → factory_bot.rb} +0 -0
  210. data/spec/support/doorkeeper_rspec.rb +20 -0
  211. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  212. data/spec/support/helpers/model_helper.rb +8 -4
  213. data/spec/support/helpers/request_spec_helper.rb +10 -2
  214. data/spec/support/helpers/url_helper.rb +18 -14
  215. data/spec/support/http_method_shim.rb +12 -16
  216. data/spec/support/shared/controllers_shared_context.rb +56 -0
  217. data/spec/validators/redirect_uri_validator_spec.rb +9 -3
  218. data/spec/version/version_spec.rb +3 -3
  219. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  220. metadata +54 -35
  221. data/lib/generators/doorkeeper/add_client_confidentiality_generator.rb +0 -31
  222. data/lib/generators/doorkeeper/templates/add_confidential_to_application_migration.rb.erb +0 -11
  223. data/spec/controllers/application_metal_controller.rb +0 -10
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  feature 'Implicit Grant Flow (feature spec)' do
4
4
  background do
@@ -17,6 +17,29 @@ feature 'Implicit Grant Flow (feature spec)' do
17
17
 
18
18
  i_should_be_on_client_callback @client
19
19
  end
20
+
21
+ context 'when application scopes are present and no scope is passed' do
22
+ background do
23
+ @client.update_attributes(scopes: 'public write read')
24
+ end
25
+
26
+ scenario 'access token has no scopes' do
27
+ default_scopes_exist :admin
28
+ visit authorization_endpoint_url(client: @client, response_type: 'token')
29
+ click_on 'Authorize'
30
+ access_token_should_exist_for @client, @resource_owner
31
+ token = Doorkeeper::AccessToken.first
32
+ expect(token.scopes).to be_empty
33
+ end
34
+
35
+ scenario 'access token has scopes which are common in application scopees and default scopes' do
36
+ default_scopes_exist :public, :write
37
+ visit authorization_endpoint_url(client: @client, response_type: 'token')
38
+ click_on 'Authorize'
39
+ access_token_should_exist_for @client, @resource_owner
40
+ access_token_should_have_scopes :public, :write
41
+ end
42
+ end
20
43
  end
21
44
 
22
45
  describe 'Implicit Grant Flow (request spec)' do
@@ -34,11 +57,13 @@ describe 'Implicit Grant Flow (request spec)' do
34
57
  token = client_is_authorized(@client, @resource_owner)
35
58
 
36
59
  post "/oauth/authorize",
37
- client_id: @client.uid,
38
- state: '',
39
- redirect_uri: @client.redirect_uri,
40
- response_type: 'token',
41
- commit: 'Authorize'
60
+ params: {
61
+ client_id: @client.uid,
62
+ state: '',
63
+ redirect_uri: @client.redirect_uri,
64
+ response_type: 'token',
65
+ commit: 'Authorize'
66
+ }
42
67
 
43
68
  expect(response.location).not_to include(token.token)
44
69
  end
@@ -49,11 +74,13 @@ describe 'Implicit Grant Flow (request spec)' do
49
74
  token = client_is_authorized(@client, @resource_owner)
50
75
 
51
76
  post "/oauth/authorize",
52
- client_id: @client.uid,
53
- state: '',
54
- redirect_uri: @client.redirect_uri,
55
- response_type: 'token',
56
- commit: 'Authorize'
77
+ params: {
78
+ client_id: @client.uid,
79
+ state: '',
80
+ redirect_uri: @client.redirect_uri,
81
+ response_type: 'token',
82
+ commit: 'Authorize'
83
+ }
57
84
 
58
85
  expect(response.location).to include(token.token)
59
86
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'Resource Owner Password Credentials Flow not set up' do
4
4
  before do
@@ -7,7 +7,7 @@ describe 'Resource Owner Password Credentials Flow not set up' do
7
7
  end
8
8
 
9
9
  context 'with valid user credentials' do
10
- it 'doesn\'t issue new token' do
10
+ it 'does not issue new token' do
11
11
  expect do
12
12
  post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
13
13
  end.to_not(change { Doorkeeper::AccessToken.count })
@@ -57,7 +57,11 @@ describe 'Resource Owner Password Credentials Flow' do
57
57
  context "when client_secret incorrect" do
58
58
  it "should not issue new token" do
59
59
  expect do
60
- post password_token_endpoint_url(client_id: @client.uid, client_secret: 'foobar', resource_owner: @resource_owner)
60
+ post password_token_endpoint_url(
61
+ client_id: @client.uid,
62
+ client_secret: 'foobar',
63
+ resource_owner: @resource_owner
64
+ )
61
65
  end.not_to(change { Doorkeeper::AccessToken.count })
62
66
 
63
67
  expect(response).not_to be_ok
@@ -140,6 +144,60 @@ describe 'Resource Owner Password Credentials Flow' do
140
144
  end
141
145
  end
142
146
 
147
+ context 'when application scopes are present and differs from configured default scopes and no scope is passed' do
148
+ before do
149
+ default_scopes_exist :public
150
+ @client.update_attributes(scopes: 'abc')
151
+ end
152
+
153
+ it 'issues new token without any scope' do
154
+ expect do
155
+ post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
156
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
157
+
158
+ token = Doorkeeper::AccessToken.first
159
+
160
+ expect(token.application_id).to eq @client.id
161
+ expect(token.scopes).to be_empty
162
+ should_have_json 'access_token', token.token
163
+ should_not_have_json 'scope'
164
+ end
165
+ end
166
+
167
+ context 'when application scopes contain some of the default scopes and no scope is passed' do
168
+ before do
169
+ @client.update_attributes(scopes: 'read write public')
170
+ end
171
+
172
+ it 'issues new token with one default scope that are present in application scopes' do
173
+ default_scopes_exist :public, :admin
174
+
175
+ expect do
176
+ post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
177
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
178
+
179
+ token = Doorkeeper::AccessToken.first
180
+
181
+ expect(token.application_id).to eq @client.id
182
+ should_have_json 'access_token', token.token
183
+ should_have_json 'scope', 'public'
184
+ end
185
+
186
+ it 'issues new token with multiple default scopes that are present in application scopes' do
187
+ default_scopes_exist :public, :read, :update
188
+
189
+ expect do
190
+ post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
191
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
192
+
193
+ token = Doorkeeper::AccessToken.first
194
+
195
+ expect(token.application_id).to eq @client.id
196
+ should_have_json 'access_token', token.token
197
+ should_have_json 'scope', 'public read'
198
+ end
199
+ end
200
+
143
201
  context 'with invalid scopes' do
144
202
  subject do
145
203
  post password_token_endpoint_url(client: @client,
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'Refresh Token Flow' do
4
4
  before do
@@ -6,6 +6,7 @@ describe 'Refresh Token Flow' do
6
6
  orm DOORKEEPER_ORM
7
7
  use_refresh_token
8
8
  end
9
+
9
10
  client_exists
10
11
  end
11
12
 
@@ -14,7 +15,7 @@ describe 'Refresh Token Flow' do
14
15
  authorization_code_exists application: @client
15
16
  end
16
17
 
17
- it 'client gets the refresh token and refreshses it' do
18
+ it 'client gets the refresh token and refreshes it' do
18
19
  post token_endpoint_url(code: @authorization.token, client: @client)
19
20
 
20
21
  token = Doorkeeper::AccessToken.first
@@ -95,6 +96,62 @@ describe 'Refresh Token Flow' do
95
96
  end
96
97
  end
97
98
 
99
+ context "public & private clients" do
100
+ let(:public_client) do
101
+ FactoryBot.create(
102
+ :application,
103
+ confidential: false
104
+ )
105
+ end
106
+
107
+ let(:token_for_private_client) do
108
+ FactoryBot.create(
109
+ :access_token,
110
+ application: @client,
111
+ resource_owner_id: 1,
112
+ use_refresh_token: true
113
+ )
114
+ end
115
+
116
+ let(:token_for_public_client) do
117
+ FactoryBot.create(
118
+ :access_token,
119
+ application: public_client,
120
+ resource_owner_id: 1,
121
+ use_refresh_token: true
122
+ )
123
+ end
124
+
125
+ it 'issues a new token without client_secret when refresh token was issued to a public client' do
126
+ post refresh_token_endpoint_url(
127
+ client_id: public_client.uid,
128
+ refresh_token: token_for_public_client.refresh_token
129
+ )
130
+
131
+ new_token = Doorkeeper::AccessToken.last
132
+ should_have_json 'access_token', new_token.token
133
+ should_have_json 'refresh_token', new_token.refresh_token
134
+ end
135
+
136
+ it 'returns an error without credentials' do
137
+ post refresh_token_endpoint_url(refresh_token: token_for_private_client.refresh_token)
138
+
139
+ should_not_have_json 'refresh_token'
140
+ should_have_json 'error', 'invalid_grant'
141
+ end
142
+
143
+ it 'returns an error with wrong credentials' do
144
+ post refresh_token_endpoint_url(
145
+ client_id: '1',
146
+ client_secret: '1',
147
+ refresh_token: token_for_private_client.refresh_token
148
+ )
149
+
150
+ should_not_have_json 'refresh_token'
151
+ should_have_json 'error', 'invalid_client'
152
+ end
153
+ end
154
+
98
155
  it 'client gets an error for invalid refresh token' do
99
156
  post refresh_token_endpoint_url(client: @client, refresh_token: 'invalid')
100
157
  should_not_have_json 'refresh_token'
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'Revoke Token Flow' do
4
4
  before do
@@ -10,9 +10,9 @@ describe 'Revoke Token Flow' do
10
10
  let(:resource_owner) { User.create!(name: 'John', password: 'sekret') }
11
11
  let(:access_token) do
12
12
  FactoryBot.create(:access_token,
13
- application: client_application,
14
- resource_owner_id: resource_owner.id,
15
- use_refresh_token: true)
13
+ application: client_application,
14
+ resource_owner_id: resource_owner.id,
15
+ use_refresh_token: true)
16
16
  end
17
17
 
18
18
  context 'with authenticated, confidential OAuth 2.0 client/application' do
@@ -24,7 +24,7 @@ describe 'Revoke Token Flow' do
24
24
  end
25
25
 
26
26
  it 'should revoke the access token provided' do
27
- post revocation_token_endpoint_url, { token: access_token.token }, headers
27
+ post revocation_token_endpoint_url, params: { token: access_token.token }, headers: headers
28
28
 
29
29
  access_token.reload
30
30
 
@@ -33,7 +33,7 @@ describe 'Revoke Token Flow' do
33
33
  end
34
34
 
35
35
  it 'should revoke the refresh token provided' do
36
- post revocation_token_endpoint_url, { token: access_token.refresh_token }, headers
36
+ post revocation_token_endpoint_url, params: { token: access_token.refresh_token }, headers: headers
37
37
 
38
38
  access_token.reload
39
39
 
@@ -44,7 +44,7 @@ describe 'Revoke Token Flow' do
44
44
  context 'with invalid token to revoke' do
45
45
  it 'should not revoke any tokens and respond successfully' do
46
46
  num_prev_revoked_tokens = Doorkeeper::AccessToken.where(revoked_at: nil).count
47
- post revocation_token_endpoint_url, { token: 'I_AM_AN_INVALID_TOKEN' }, headers
47
+ post revocation_token_endpoint_url, params: { token: 'I_AM_AN_INVALID_TOKEN' }, headers: headers
48
48
 
49
49
  # The authorization server responds with HTTP status code 200 even if
50
50
  # token is invalid
@@ -60,7 +60,7 @@ describe 'Revoke Token Flow' do
60
60
  { 'HTTP_AUTHORIZATION' => "Basic #{credentials}" }
61
61
  end
62
62
  it 'should not revoke any tokens and respond successfully' do
63
- post revocation_token_endpoint_url, { token: access_token.token }, headers
63
+ post revocation_token_endpoint_url, params: { token: access_token.token }, headers: headers
64
64
 
65
65
  access_token.reload
66
66
 
@@ -71,7 +71,7 @@ describe 'Revoke Token Flow' do
71
71
 
72
72
  context 'with no credentials and a valid token' do
73
73
  it 'should not revoke any tokens and respond successfully' do
74
- post revocation_token_endpoint_url, { token: access_token.token }
74
+ post revocation_token_endpoint_url, params: { token: access_token.token }
75
75
 
76
76
  access_token.reload
77
77
 
@@ -90,7 +90,7 @@ describe 'Revoke Token Flow' do
90
90
  end
91
91
 
92
92
  it 'should not revoke the token as its unauthorized' do
93
- post revocation_token_endpoint_url, { token: access_token.token }, headers
93
+ post revocation_token_endpoint_url, params: { token: access_token.token }, headers: headers
94
94
 
95
95
  access_token.reload
96
96
 
@@ -103,13 +103,13 @@ describe 'Revoke Token Flow' do
103
103
  context 'with public OAuth 2.0 client/application' do
104
104
  let(:access_token) do
105
105
  FactoryBot.create(:access_token,
106
- application: nil,
107
- resource_owner_id: resource_owner.id,
108
- use_refresh_token: true)
106
+ application: nil,
107
+ resource_owner_id: resource_owner.id,
108
+ use_refresh_token: true)
109
109
  end
110
110
 
111
111
  it 'should revoke the access token provided' do
112
- post revocation_token_endpoint_url, { token: access_token.token }
112
+ post revocation_token_endpoint_url, params: { token: access_token.token }
113
113
 
114
114
  access_token.reload
115
115
 
@@ -118,7 +118,7 @@ describe 'Revoke Token Flow' do
118
118
  end
119
119
 
120
120
  it 'should revoke the refresh token provided' do
121
- post revocation_token_endpoint_url, { token: access_token.refresh_token }
121
+ post revocation_token_endpoint_url, params: { token: access_token.refresh_token }
122
122
 
123
123
  access_token.reload
124
124
 
@@ -129,13 +129,13 @@ describe 'Revoke Token Flow' do
129
129
  context 'with a valid token issued for a confidential client' do
130
130
  let(:access_token) do
131
131
  FactoryBot.create(:access_token,
132
- application: client_application,
133
- resource_owner_id: resource_owner.id,
134
- use_refresh_token: true)
132
+ application: client_application,
133
+ resource_owner_id: resource_owner.id,
134
+ use_refresh_token: true)
135
135
  end
136
136
 
137
137
  it 'should not revoke the access token provided' do
138
- post revocation_token_endpoint_url, { token: access_token.token }
138
+ post revocation_token_endpoint_url, params: { token: access_token.token }
139
139
 
140
140
  access_token.reload
141
141
 
@@ -144,7 +144,7 @@ describe 'Revoke Token Flow' do
144
144
  end
145
145
 
146
146
  it 'should not revoke the refresh token provided' do
147
- post revocation_token_endpoint_url, { token: access_token.token }
147
+ post revocation_token_endpoint_url, params: { token: access_token.token }
148
148
 
149
149
  access_token.reload
150
150
 
@@ -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,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'ActionController::Metal API' do
4
4
  before do
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  feature 'Private API' do
4
4
  background do
@@ -41,10 +41,10 @@ feature 'Private API' do
41
41
  end
42
42
 
43
43
  scenario 'access token with no default scopes' do
44
- Doorkeeper.configuration.instance_eval {
44
+ Doorkeeper.configuration.instance_eval do
45
45
  @default_scopes = Doorkeeper::OAuth::Scopes.from_array([:public])
46
46
  @scopes = default_scopes + optional_scopes
47
- }
47
+ end
48
48
  @token.update_attribute :scopes, 'dummy'
49
49
  with_access_token_header @token.token
50
50
  visit '/full_protected_resources'
@@ -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
 
@@ -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
@@ -33,7 +33,7 @@ describe 'Default routes' do
33
33
  expect(get('/oauth/authorized_applications')).to route_to('doorkeeper/authorized_applications#index')
34
34
  end
35
35
 
36
- it 'GET /oauth/token/info route to authorized tokeninfo controller' do
36
+ it 'GET /oauth/token/info route to authorized TokenInfo controller' do
37
37
  expect(get('/oauth/token/info')).to route_to('doorkeeper/token_info#show')
38
38
  end
39
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