doorkeeper 5.3.3 → 5.4.0

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 (224) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -4
  3. data/README.md +6 -4
  4. data/app/controllers/doorkeeper/applications_controller.rb +4 -4
  5. data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
  6. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  7. data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
  8. data/app/views/doorkeeper/applications/_form.html.erb +1 -1
  9. data/app/views/doorkeeper/applications/show.html.erb +19 -2
  10. data/config/locales/en.yml +3 -1
  11. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  12. data/lib/doorkeeper/config/option.rb +28 -14
  13. data/lib/doorkeeper/config.rb +64 -35
  14. data/lib/doorkeeper/engine.rb +1 -1
  15. data/lib/doorkeeper/grape/helpers.rb +1 -1
  16. data/lib/doorkeeper/helpers/controller.rb +4 -4
  17. data/lib/doorkeeper/models/access_grant_mixin.rb +20 -16
  18. data/lib/doorkeeper/models/access_token_mixin.rb +108 -45
  19. data/lib/doorkeeper/models/application_mixin.rb +5 -4
  20. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  21. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  22. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  23. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  24. data/lib/doorkeeper/oauth/authorization/code.rb +15 -6
  25. data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
  26. data/lib/doorkeeper/oauth/authorization/token.rb +8 -12
  27. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  28. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
  29. data/lib/doorkeeper/oauth/base_request.rb +11 -19
  30. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  31. data/lib/doorkeeper/oauth/client.rb +1 -1
  32. data/lib/doorkeeper/oauth/client_credentials/creator.rb +26 -8
  33. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  34. data/lib/doorkeeper/oauth/client_credentials/validator.rb +4 -2
  35. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  36. data/lib/doorkeeper/oauth/code_request.rb +3 -3
  37. data/lib/doorkeeper/oauth/code_response.rb +6 -2
  38. data/lib/doorkeeper/oauth/error_response.rb +2 -4
  39. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
  40. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  41. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  42. data/lib/doorkeeper/oauth/password_access_token_request.rb +4 -6
  43. data/lib/doorkeeper/oauth/pre_authorization.rb +36 -30
  44. data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
  45. data/lib/doorkeeper/oauth/token.rb +5 -6
  46. data/lib/doorkeeper/oauth/token_introspection.rb +4 -8
  47. data/lib/doorkeeper/oauth/token_request.rb +3 -3
  48. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  49. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +8 -3
  50. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +7 -3
  51. data/lib/doorkeeper/orm/active_record.rb +10 -2
  52. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  53. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  54. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  55. data/lib/doorkeeper/rails/routes.rb +13 -17
  56. data/lib/doorkeeper/request/refresh_token.rb +2 -1
  57. data/lib/doorkeeper/request/strategy.rb +2 -2
  58. data/lib/doorkeeper/server.rb +4 -4
  59. data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
  60. data/lib/doorkeeper/version.rb +2 -2
  61. data/lib/doorkeeper.rb +106 -79
  62. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  63. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  64. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
  65. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  66. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  67. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  68. data/lib/generators/doorkeeper/templates/initializer.rb +39 -3
  69. data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
  70. metadata +13 -296
  71. data/Appraisals +0 -40
  72. data/CODE_OF_CONDUCT.md +0 -46
  73. data/CONTRIBUTING.md +0 -49
  74. data/Dangerfile +0 -67
  75. data/Dockerfile +0 -29
  76. data/Gemfile +0 -25
  77. data/NEWS.md +0 -1
  78. data/RELEASING.md +0 -11
  79. data/Rakefile +0 -28
  80. data/SECURITY.md +0 -15
  81. data/UPGRADE.md +0 -2
  82. data/bin/console +0 -16
  83. data/doorkeeper.gemspec +0 -42
  84. data/gemfiles/rails_5_0.gemfile +0 -18
  85. data/gemfiles/rails_5_1.gemfile +0 -18
  86. data/gemfiles/rails_5_2.gemfile +0 -18
  87. data/gemfiles/rails_6_0.gemfile +0 -18
  88. data/gemfiles/rails_master.gemfile +0 -18
  89. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  90. data/spec/controllers/applications_controller_spec.rb +0 -274
  91. data/spec/controllers/authorizations_controller_spec.rb +0 -608
  92. data/spec/controllers/protected_resources_controller_spec.rb +0 -361
  93. data/spec/controllers/token_info_controller_spec.rb +0 -50
  94. data/spec/controllers/tokens_controller_spec.rb +0 -498
  95. data/spec/dummy/Rakefile +0 -9
  96. data/spec/dummy/app/assets/config/manifest.js +0 -2
  97. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  98. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  99. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  100. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  101. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  102. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  103. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  104. data/spec/dummy/app/models/user.rb +0 -7
  105. data/spec/dummy/app/views/home/index.html.erb +0 -0
  106. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  107. data/spec/dummy/config/application.rb +0 -49
  108. data/spec/dummy/config/boot.rb +0 -7
  109. data/spec/dummy/config/database.yml +0 -15
  110. data/spec/dummy/config/environment.rb +0 -5
  111. data/spec/dummy/config/environments/development.rb +0 -31
  112. data/spec/dummy/config/environments/production.rb +0 -64
  113. data/spec/dummy/config/environments/test.rb +0 -45
  114. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  115. data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
  116. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  117. data/spec/dummy/config/initializers/session_store.rb +0 -10
  118. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  119. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  120. data/spec/dummy/config/routes.rb +0 -13
  121. data/spec/dummy/config.ru +0 -6
  122. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  123. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  124. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  125. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  126. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  127. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  128. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  129. data/spec/dummy/db/schema.rb +0 -68
  130. data/spec/dummy/public/404.html +0 -26
  131. data/spec/dummy/public/422.html +0 -26
  132. data/spec/dummy/public/500.html +0 -26
  133. data/spec/dummy/public/favicon.ico +0 -0
  134. data/spec/dummy/script/rails +0 -9
  135. data/spec/factories.rb +0 -30
  136. data/spec/generators/application_owner_generator_spec.rb +0 -28
  137. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  138. data/spec/generators/install_generator_spec.rb +0 -36
  139. data/spec/generators/migration_generator_spec.rb +0 -28
  140. data/spec/generators/pkce_generator_spec.rb +0 -28
  141. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  142. data/spec/generators/templates/routes.rb +0 -4
  143. data/spec/generators/views_generator_spec.rb +0 -29
  144. data/spec/grape/grape_integration_spec.rb +0 -137
  145. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  146. data/spec/lib/config_spec.rb +0 -809
  147. data/spec/lib/doorkeeper_spec.rb +0 -27
  148. data/spec/lib/models/expirable_spec.rb +0 -61
  149. data/spec/lib/models/reusable_spec.rb +0 -40
  150. data/spec/lib/models/revocable_spec.rb +0 -59
  151. data/spec/lib/models/scopes_spec.rb +0 -53
  152. data/spec/lib/models/secret_storable_spec.rb +0 -135
  153. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  154. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -170
  155. data/spec/lib/oauth/base_request_spec.rb +0 -224
  156. data/spec/lib/oauth/base_response_spec.rb +0 -45
  157. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  158. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -134
  159. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  160. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  161. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  162. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -107
  163. data/spec/lib/oauth/client_spec.rb +0 -38
  164. data/spec/lib/oauth/code_request_spec.rb +0 -46
  165. data/spec/lib/oauth/code_response_spec.rb +0 -32
  166. data/spec/lib/oauth/error_response_spec.rb +0 -64
  167. data/spec/lib/oauth/error_spec.rb +0 -21
  168. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
  169. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
  170. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  171. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  172. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
  173. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
  174. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -190
  175. data/spec/lib/oauth/pre_authorization_spec.rb +0 -223
  176. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
  177. data/spec/lib/oauth/scopes_spec.rb +0 -146
  178. data/spec/lib/oauth/token_request_spec.rb +0 -157
  179. data/spec/lib/oauth/token_response_spec.rb +0 -84
  180. data/spec/lib/oauth/token_spec.rb +0 -156
  181. data/spec/lib/request/strategy_spec.rb +0 -54
  182. data/spec/lib/secret_storing/base_spec.rb +0 -60
  183. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  184. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  185. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  186. data/spec/lib/server_spec.rb +0 -49
  187. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  188. data/spec/models/doorkeeper/access_grant_spec.rb +0 -161
  189. data/spec/models/doorkeeper/access_token_spec.rb +0 -622
  190. data/spec/models/doorkeeper/application_spec.rb +0 -482
  191. data/spec/requests/applications/applications_request_spec.rb +0 -259
  192. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  193. data/spec/requests/endpoints/authorization_spec.rb +0 -91
  194. data/spec/requests/endpoints/token_spec.rb +0 -75
  195. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
  196. data/spec/requests/flows/authorization_code_spec.rb +0 -525
  197. data/spec/requests/flows/client_credentials_spec.rb +0 -166
  198. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  199. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  200. data/spec/requests/flows/password_spec.rb +0 -316
  201. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  202. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  203. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  204. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  205. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  206. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  207. data/spec/routing/default_routes_spec.rb +0 -41
  208. data/spec/routing/scoped_routes_spec.rb +0 -47
  209. data/spec/spec_helper.rb +0 -54
  210. data/spec/spec_helper_integration.rb +0 -4
  211. data/spec/support/dependencies/factory_bot.rb +0 -4
  212. data/spec/support/doorkeeper_rspec.rb +0 -22
  213. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  214. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  215. data/spec/support/helpers/config_helper.rb +0 -11
  216. data/spec/support/helpers/model_helper.rb +0 -78
  217. data/spec/support/helpers/request_spec_helper.rb +0 -110
  218. data/spec/support/helpers/url_helper.rb +0 -62
  219. data/spec/support/orm/active_record.rb +0 -5
  220. data/spec/support/shared/controllers_shared_context.rb +0 -133
  221. data/spec/support/shared/hashing_shared_context.rb +0 -36
  222. data/spec/support/shared/models_shared_examples.rb +0 -54
  223. data/spec/validators/redirect_uri_validator_spec.rb +0 -183
  224. data/spec/version/version_spec.rb +0 -17
@@ -1,498 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- describe Doorkeeper::TokensController do
6
- let(:client) { FactoryBot.create :application }
7
- let!(:user) { User.create!(name: "Joe", password: "sekret") }
8
-
9
- before do
10
- Doorkeeper.configure do
11
- resource_owner_from_credentials do
12
- User.first
13
- end
14
- end
15
-
16
- allow(Doorkeeper.configuration).to receive(:grant_flows).and_return(["password"])
17
- end
18
-
19
- subject { JSON.parse(response.body) }
20
-
21
- describe "POST #create" do
22
- before do
23
- post :create, params: {
24
- client_id: client.uid,
25
- client_secret: client.secret,
26
- grant_type: "password",
27
- }
28
- end
29
-
30
- it "responds after authorization" do
31
- expect(response).to be_successful
32
- end
33
-
34
- it "includes access token in response" do
35
- expect(subject["access_token"]).to eq(Doorkeeper::AccessToken.first.token)
36
- end
37
-
38
- it "includes token type in response" do
39
- expect(subject["token_type"]).to eq("Bearer")
40
- end
41
-
42
- it "includes token expiration in response" do
43
- expect(subject["expires_in"].to_i).to eq(Doorkeeper.configuration.access_token_expires_in)
44
- end
45
-
46
- it "issues the token for the current client" do
47
- expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
48
- end
49
-
50
- it "issues the token for the current resource owner" do
51
- expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
52
- end
53
- end
54
-
55
- describe "POST #create with errors" do
56
- before do
57
- post :create, params: {
58
- client_id: client.uid,
59
- client_secret: "invalid",
60
- grant_type: "password",
61
- }
62
- end
63
-
64
- it "responds after authorization" do
65
- expect(response).to be_unauthorized
66
- end
67
-
68
- it "include error in response" do
69
- expect(subject["error"]).to eq("invalid_client")
70
- end
71
-
72
- it "include error_description in response" do
73
- expect(subject["error_description"]).to be
74
- end
75
-
76
- it "does not include access token in response" do
77
- expect(subject["access_token"]).to be_nil
78
- end
79
-
80
- it "does not include token type in response" do
81
- expect(subject["token_type"]).to be_nil
82
- end
83
-
84
- it "does not include token expiration in response" do
85
- expect(subject["expires_in"]).to be_nil
86
- end
87
-
88
- it "does not issue any access token" do
89
- expect(Doorkeeper::AccessToken.all).to be_empty
90
- end
91
- end
92
-
93
- describe "POST #create with callbacks" do
94
- after do
95
- client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
96
- end
97
-
98
- describe "when successful" do
99
- after do
100
- post :create, params: {
101
- client_id: client.uid,
102
- client_secret: client.secret,
103
- grant_type: "password",
104
- }
105
- end
106
-
107
- it "should call :before_successful_authorization callback" do
108
- expect(Doorkeeper.configuration)
109
- .to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
110
- end
111
-
112
- it "should call :after_successful_authorization callback" do
113
- expect(Doorkeeper.configuration)
114
- .to receive_message_chain(:after_successful_authorization, :call).with(instance_of(described_class))
115
- end
116
- end
117
-
118
- describe "with errors" do
119
- after do
120
- post :create, params: {
121
- client_id: client.uid,
122
- client_secret: "invalid",
123
- grant_type: "password",
124
- }
125
- end
126
-
127
- it "should call :before_successful_authorization callback" do
128
- expect(Doorkeeper.configuration)
129
- .to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
130
- end
131
-
132
- it "should not call :after_successful_authorization callback" do
133
- expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
134
- end
135
- end
136
- end
137
-
138
- describe "POST #create with custom error" do
139
- it "returns the error response with a custom message" do
140
- # I18n looks for `doorkeeper.errors.messages.custom_message` in locale files
141
- custom_message = "my_message"
142
- allow(I18n).to receive(:translate)
143
- .with(
144
- custom_message,
145
- hash_including(scope: %i[doorkeeper errors messages]),
146
- )
147
- .and_return("Authorization custom message")
148
-
149
- doorkeeper_error = Doorkeeper::Errors::DoorkeeperError.new(custom_message)
150
-
151
- strategy = double(:strategy)
152
- request = double(token_request: strategy)
153
- allow(strategy).to receive(:authorize).and_raise(doorkeeper_error)
154
- allow(controller).to receive(:server).and_return(request)
155
-
156
- post :create
157
-
158
- expected_response_body = {
159
- "error" => custom_message,
160
- "error_description" => "Authorization custom message",
161
- }
162
- expect(response.status).to eq 400
163
- expect(response.headers["WWW-Authenticate"]).to match(/Bearer/)
164
- expect(JSON.parse(response.body)).to eq expected_response_body
165
- end
166
- end
167
-
168
- # http://tools.ietf.org/html/rfc7009#section-2.2
169
- describe "POST #revoke" do
170
- let(:client) { FactoryBot.create(:application) }
171
- let(:access_token) { FactoryBot.create(:access_token, application: client) }
172
-
173
- context "when associated app is public" do
174
- let(:client) { FactoryBot.create(:application, confidential: false) }
175
-
176
- it "returns 200" do
177
- post :revoke, params: { token: access_token.token }
178
-
179
- expect(response.status).to eq 200
180
- end
181
-
182
- it "revokes the access token" do
183
- post :revoke, params: { token: access_token.token }
184
-
185
- expect(access_token.reload).to have_attributes(revoked?: true)
186
- end
187
- end
188
-
189
- context "when associated app is confidential" do
190
- let(:client) { FactoryBot.create(:application, confidential: true) }
191
- let(:oauth_client) { Doorkeeper::OAuth::Client.new(client) }
192
-
193
- before(:each) do
194
- allow_any_instance_of(Doorkeeper::Server).to receive(:client) { oauth_client }
195
- end
196
-
197
- it "returns 200" do
198
- post :revoke, params: { token: access_token.token }
199
-
200
- expect(response.status).to eq 200
201
- end
202
-
203
- it "revokes the access token" do
204
- post :revoke, params: { token: access_token.token }
205
-
206
- expect(access_token.reload).to have_attributes(revoked?: true)
207
- end
208
-
209
- context "when authorization fails" do
210
- let(:some_other_client) { FactoryBot.create(:application, confidential: true) }
211
- let(:oauth_client) { Doorkeeper::OAuth::Client.new(some_other_client) }
212
-
213
- it "returns 403" do
214
- post :revoke, params: { token: access_token.token }
215
-
216
- expect(response.status).to eq 403
217
- end
218
-
219
- it "does not revoke the access token" do
220
- post :revoke, params: { token: access_token.token }
221
-
222
- expect(access_token.reload).to have_attributes(revoked?: false)
223
- end
224
- end
225
- end
226
- end
227
-
228
- describe "POST #introspect" do
229
- let(:client) { FactoryBot.create(:application) }
230
- let(:access_token) { FactoryBot.create(:access_token, application: client) }
231
- let(:token_for_introspection) { FactoryBot.create(:access_token, application: client) }
232
-
233
- context "authorized using valid Bearer token" do
234
- it "responds with full token introspection" do
235
- request.headers["Authorization"] = "Bearer #{access_token.token}"
236
-
237
- post :introspect, params: { token: token_for_introspection.token }
238
-
239
- should_have_json "active", true
240
- expect(json_response).to include("client_id", "token_type", "exp", "iat")
241
- end
242
- end
243
-
244
- context "authorized using Client Credentials of the client that token is issued to" do
245
- it "responds with full token introspection" do
246
- request.headers["Authorization"] = basic_auth_header_for_client(client)
247
-
248
- post :introspect, params: { token: token_for_introspection.token }
249
-
250
- should_have_json "active", true
251
- expect(json_response).to include("client_id", "token_type", "exp", "iat")
252
- should_have_json "client_id", client.uid
253
- end
254
- end
255
-
256
- context "configured token introspection disabled" do
257
- before do
258
- Doorkeeper.configure do
259
- orm DOORKEEPER_ORM
260
- allow_token_introspection false
261
- end
262
- end
263
-
264
- it "responds with invalid_token error" do
265
- request.headers["Authorization"] = "Bearer #{access_token.token}"
266
-
267
- post :introspect, params: { token: token_for_introspection.token }
268
-
269
- response_status_should_be 401
270
-
271
- should_not_have_json "active"
272
- should_have_json "error", "invalid_token"
273
- end
274
- end
275
-
276
- context "using custom introspection response" do
277
- before do
278
- Doorkeeper.configure do
279
- orm DOORKEEPER_ORM
280
- custom_introspection_response do |_token, _context|
281
- {
282
- sub: "Z5O3upPC88QrAjx00dis",
283
- aud: "https://protected.example.net/resource",
284
- }
285
- end
286
- end
287
- end
288
-
289
- it "responds with full token introspection" do
290
- request.headers["Authorization"] = "Bearer #{access_token.token}"
291
-
292
- post :introspect, params: { token: token_for_introspection.token }
293
-
294
- expect(json_response).to include("client_id", "token_type", "exp", "iat", "sub", "aud")
295
- should_have_json "sub", "Z5O3upPC88QrAjx00dis"
296
- should_have_json "aud", "https://protected.example.net/resource"
297
- end
298
- end
299
-
300
- context "public access token" do
301
- let(:token_for_introspection) { FactoryBot.create(:access_token, application: nil) }
302
-
303
- it "responds with full token introspection" do
304
- request.headers["Authorization"] = basic_auth_header_for_client(client)
305
-
306
- post :introspect, params: { token: token_for_introspection.token }
307
-
308
- should_have_json "active", true
309
- expect(json_response).to include("client_id", "token_type", "exp", "iat")
310
- should_have_json "client_id", nil
311
- end
312
- end
313
-
314
- context "token was issued to a different client than is making this request" do
315
- let(:different_client) { FactoryBot.create(:application) }
316
-
317
- it "responds with only active state" do
318
- request.headers["Authorization"] = basic_auth_header_for_client(different_client)
319
-
320
- post :introspect, params: { token: token_for_introspection.token }
321
-
322
- expect(response).to be_successful
323
-
324
- should_have_json "active", false
325
- expect(json_response).not_to include("client_id", "token_type", "exp", "iat")
326
- end
327
- end
328
-
329
- context "introspection request authorized by a client and allow_token_introspection is true" do
330
- let(:different_client) { FactoryBot.create(:application) }
331
-
332
- before do
333
- allow(Doorkeeper.configuration).to receive(:allow_token_introspection).and_return(proc do
334
- true
335
- end)
336
- end
337
-
338
- it "responds with full token introspection" do
339
- request.headers["Authorization"] = basic_auth_header_for_client(different_client)
340
-
341
- post :introspect, params: { token: token_for_introspection.token }
342
-
343
- should_have_json "active", true
344
- expect(json_response).to include("client_id", "token_type", "exp", "iat")
345
- should_have_json "client_id", client.uid
346
- end
347
- end
348
-
349
- context "allow_token_introspection requires authorized token with special scope" do
350
- let(:access_token) { FactoryBot.create(:access_token, scopes: "introspection") }
351
-
352
- before do
353
- allow(Doorkeeper.configuration).to receive(:allow_token_introspection).and_return(proc do |_token, _client, authorized_token|
354
- authorized_token.scopes.include?("introspection")
355
- end)
356
- end
357
-
358
- it "responds with full token introspection if authorized token has introspection scope" do
359
- request.headers["Authorization"] = "Bearer #{access_token.token}"
360
-
361
- post :introspect, params: { token: token_for_introspection.token }
362
-
363
- should_have_json "active", true
364
- expect(json_response).to include("client_id", "token_type", "exp", "iat")
365
- end
366
-
367
- it "responds with invalid_token error if authorized token doesn't have introspection scope" do
368
- access_token.update(scopes: "read write")
369
-
370
- request.headers["Authorization"] = "Bearer #{access_token.token}"
371
-
372
- post :introspect, params: { token: token_for_introspection.token }
373
-
374
- response_status_should_be 401
375
-
376
- should_not_have_json "active"
377
- should_have_json "error", "invalid_token"
378
- end
379
- end
380
-
381
- context "authorized using invalid Bearer token" do
382
- let(:access_token) do
383
- FactoryBot.create(:access_token, application: client, revoked_at: 1.day.ago)
384
- end
385
-
386
- it "responds with invalid_token error" do
387
- request.headers["Authorization"] = "Bearer #{access_token.token}"
388
-
389
- post :introspect, params: { token: token_for_introspection.token }
390
-
391
- response_status_should_be 401
392
-
393
- should_not_have_json "active"
394
- should_have_json "error", "invalid_token"
395
- end
396
- end
397
-
398
- context "authorized using the Bearer token that need to be introspected" do
399
- it "responds with invalid token error" do
400
- request.headers["Authorization"] = "Bearer #{access_token.token}"
401
-
402
- post :introspect, params: { token: access_token.token }
403
-
404
- response_status_should_be 401
405
-
406
- should_not_have_json "active"
407
- should_have_json "error", "invalid_token"
408
- end
409
- end
410
-
411
- context "using invalid credentials to authorize" do
412
- let(:client) { double(uid: "123123", secret: "666999") }
413
- let(:access_token) { FactoryBot.create(:access_token) }
414
-
415
- it "responds with invalid_client error" do
416
- request.headers["Authorization"] = basic_auth_header_for_client(client)
417
-
418
- post :introspect, params: { token: access_token.token }
419
-
420
- expect(response).not_to be_successful
421
- response_status_should_be 401
422
-
423
- should_not_have_json "active"
424
- should_have_json "error", "invalid_client"
425
- end
426
- end
427
-
428
- context "using wrong token value" do
429
- context "authorized using client credentials" do
430
- it "responds with only active state" do
431
- request.headers["Authorization"] = basic_auth_header_for_client(client)
432
-
433
- post :introspect, params: { token: SecureRandom.hex(16) }
434
-
435
- should_have_json "active", false
436
- expect(json_response).not_to include("client_id", "token_type", "exp", "iat")
437
- end
438
- end
439
-
440
- context "authorized using valid Bearer token" do
441
- it "responds with invalid_token error" do
442
- request.headers["Authorization"] = "Bearer #{access_token.token}"
443
-
444
- post :introspect, params: { token: SecureRandom.hex(16) }
445
-
446
- response_status_should_be 401
447
-
448
- should_not_have_json "active"
449
- should_have_json "error", "invalid_token"
450
- end
451
- end
452
- end
453
-
454
- context "when requested access token expired" do
455
- let(:token_for_introspection) do
456
- FactoryBot.create(:access_token, application: client, created_at: 1.year.ago)
457
- end
458
-
459
- it "responds with only active state" do
460
- request.headers["Authorization"] = basic_auth_header_for_client(client)
461
-
462
- post :introspect, params: { token: token_for_introspection.token }
463
-
464
- should_have_json "active", false
465
- expect(json_response).not_to include("client_id", "token_type", "exp", "iat")
466
- end
467
- end
468
-
469
- context "when requested Access Token revoked" do
470
- let(:token_for_introspection) do
471
- FactoryBot.create(:access_token, application: client, revoked_at: 1.year.ago)
472
- end
473
-
474
- it "responds with only active state" do
475
- request.headers["Authorization"] = basic_auth_header_for_client(client)
476
-
477
- post :introspect, params: { token: token_for_introspection.token }
478
-
479
- should_have_json "active", false
480
- expect(json_response).not_to include("client_id", "token_type", "exp", "iat")
481
- end
482
- end
483
-
484
- context "unauthorized (no bearer token or client credentials)" do
485
- let(:token_for_introspection) { FactoryBot.create(:access_token) }
486
-
487
- it "responds with invalid_request error" do
488
- post :introspect, params: { token: token_for_introspection.token }
489
-
490
- expect(response).not_to be_successful
491
- response_status_should_be 400
492
-
493
- should_not_have_json "active"
494
- should_have_json "error", "invalid_request"
495
- end
496
- end
497
- end
498
- end
data/spec/dummy/Rakefile DELETED
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env rake
2
- # frozen_string_literal: true
3
-
4
- # Add your own tasks in files placed in lib/tasks ending in .rake,
5
- # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
6
-
7
- require File.expand_path("config/application", __dir__)
8
-
9
- Dummy::Application.load_tasks
@@ -1,2 +0,0 @@
1
- // JS and CSS bundles
2
- //
@@ -1,5 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class ApplicationController < ActionController::Base
4
- protect_from_forgery with: :exception
5
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class CustomAuthorizationsController < ::ApplicationController
4
- %w[index show new create edit update destroy].each do |action|
5
- define_method action do
6
- render nothing: true
7
- end
8
- end
9
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FullProtectedResourcesController < ApplicationController
4
- before_action -> { doorkeeper_authorize! :write, :admin }, only: :show
5
- before_action :doorkeeper_authorize!, only: :index
6
-
7
- def index
8
- render plain: "index"
9
- end
10
-
11
- def show
12
- render plain: "show"
13
- end
14
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class HomeController < ApplicationController
4
- def index; end
5
-
6
- def sign_in
7
- session[:user_id] = if Rails.env.development?
8
- User.first || User.create!(name: "Joe", password: "sekret")
9
- else
10
- User.first
11
- end
12
- redirect_to "/"
13
- end
14
-
15
- def callback
16
- render plain: "ok"
17
- end
18
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class MetalController < ActionController::Metal
4
- include AbstractController::Callbacks
5
- include ActionController::Head
6
- include Doorkeeper::Rails::Helpers
7
-
8
- before_action :doorkeeper_authorize!
9
-
10
- def index
11
- self.response_body = { ok: true }.to_json
12
- end
13
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class SemiProtectedResourcesController < ApplicationController
4
- before_action :doorkeeper_authorize!, only: :index
5
-
6
- def index
7
- render plain: "protected index"
8
- end
9
-
10
- def show
11
- render plain: "non protected show"
12
- end
13
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ApplicationHelper
4
- def current_user
5
- @current_user ||= User.find_by_id(session[:user_id])
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class User < ActiveRecord::Base
4
- def self.authenticate!(name, password)
5
- User.where(name: name, password: password).first
6
- end
7
- end
File without changes
@@ -1,14 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>Dummy</title>
5
- <%= csrf_meta_tags %>
6
- </head>
7
- <body>
8
-
9
- <%= link_to "Sign in", '/sign_in' %>
10
-
11
- <%= yield %>
12
-
13
- </body>
14
- </html>
@@ -1,49 +0,0 @@
1
- require File.expand_path('boot', __dir__)
2
-
3
- require "rails"
4
-
5
- %w[
6
- action_controller/railtie
7
- action_view/railtie
8
- action_cable/engine
9
- sprockets/railtie
10
- ].each do |railtie|
11
- begin
12
- require railtie
13
- rescue LoadError => e
14
- puts "Error loading '#{railtie}' (#{e.message})"
15
- end
16
- end
17
-
18
- Bundler.require(*Rails.groups)
19
-
20
- require 'yaml'
21
-
22
- orm = if DOORKEEPER_ORM =~ /mongoid/
23
- Mongoid.load!(File.join(File.dirname(File.expand_path(__FILE__)), "#{DOORKEEPER_ORM}.yml"))
24
- :mongoid
25
- else
26
- DOORKEEPER_ORM
27
- end
28
- require "#{orm}/railtie"
29
-
30
- module Dummy
31
- class Application < Rails::Application
32
- if Rails.gem_version < Gem::Version.new('5.1')
33
- config.action_controller.per_form_csrf_tokens = true
34
- config.action_controller.forgery_protection_origin_check = true
35
-
36
- ActiveSupport.to_time_preserves_timezone = true
37
-
38
- config.active_record.belongs_to_required_by_default = true
39
-
40
- config.ssl_options = { hsts: { subdomains: true } }
41
- else
42
- config.load_defaults "#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}"
43
- end
44
-
45
- # Settings in config/environments/* take precedence over those specified here.
46
- # Application configuration should go into files in config/initializers
47
- # -- all .rb files in that directory are automatically loaded.
48
- end
49
- end
@@ -1,7 +0,0 @@
1
- require 'rubygems'
2
- require 'bundler/setup'
3
-
4
- orm = ENV['BUNDLE_GEMFILE'].match(/Gemfile\.(.+)\.rb/)
5
- DOORKEEPER_ORM = (orm && orm[1]) || :active_record unless defined?(DOORKEEPER_ORM)
6
-
7
- $LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)