doorkeeper 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. checksums.yaml +5 -5
  2. data/.hound.yml +2 -1
  3. data/.rubocop.yml +37 -4
  4. data/.travis.yml +16 -21
  5. data/Appraisals +29 -7
  6. data/Dangerfile +67 -0
  7. data/Gemfile +19 -5
  8. data/NEWS.md +107 -10
  9. data/README.md +75 -470
  10. data/Rakefile +10 -8
  11. data/app/controllers/doorkeeper/application_controller.rb +3 -2
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -13
  13. data/app/controllers/doorkeeper/applications_controller.rb +21 -7
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +3 -3
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -0
  16. data/app/controllers/doorkeeper/token_info_controller.rb +4 -2
  17. data/app/controllers/doorkeeper/tokens_controller.rb +13 -11
  18. data/app/helpers/doorkeeper/dashboard_helper.rb +3 -1
  19. data/app/validators/redirect_uri_validator.rb +7 -2
  20. data/app/views/doorkeeper/applications/_form.html.erb +6 -0
  21. data/app/views/doorkeeper/applications/show.html.erb +1 -1
  22. data/app/views/layouts/doorkeeper/admin.html.erb +5 -3
  23. data/bin/console +16 -0
  24. data/config/locales/en.yml +1 -0
  25. data/doorkeeper.gemspec +28 -24
  26. data/gemfiles/rails_5_0.gemfile +9 -4
  27. data/gemfiles/rails_5_1.gemfile +9 -4
  28. data/gemfiles/rails_5_2.gemfile +10 -5
  29. data/gemfiles/rails_6_0.gemfile +17 -0
  30. data/gemfiles/rails_master.gemfile +9 -9
  31. data/lib/doorkeeper/config/option.rb +64 -0
  32. data/lib/doorkeeper/config.rb +197 -76
  33. data/lib/doorkeeper/engine.rb +3 -1
  34. data/lib/doorkeeper/errors.rb +17 -0
  35. data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
  36. data/lib/doorkeeper/grape/helpers.rb +5 -3
  37. data/lib/doorkeeper/helpers/controller.rb +5 -2
  38. data/lib/doorkeeper/models/access_grant_mixin.rb +25 -6
  39. data/lib/doorkeeper/models/access_token_mixin.rb +68 -22
  40. data/lib/doorkeeper/models/application_mixin.rb +45 -1
  41. data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
  42. data/lib/doorkeeper/models/concerns/expirable.rb +6 -2
  43. data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
  44. data/lib/doorkeeper/models/concerns/ownership.rb +3 -6
  45. data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
  46. data/lib/doorkeeper/models/concerns/revocable.rb +4 -1
  47. data/lib/doorkeeper/models/concerns/scopes.rb +7 -1
  48. data/lib/doorkeeper/models/concerns/secret_storable.rb +108 -0
  49. data/lib/doorkeeper/oauth/authorization/code.rb +4 -2
  50. data/lib/doorkeeper/oauth/authorization/context.rb +2 -0
  51. data/lib/doorkeeper/oauth/authorization/token.rb +14 -7
  52. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +3 -1
  53. data/lib/doorkeeper/oauth/authorization_code_request.rb +8 -4
  54. data/lib/doorkeeper/oauth/base_request.rb +2 -0
  55. data/lib/doorkeeper/oauth/base_response.rb +2 -0
  56. data/lib/doorkeeper/oauth/client/credentials.rb +2 -0
  57. data/lib/doorkeeper/oauth/client.rb +3 -1
  58. data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -0
  59. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +2 -0
  60. data/lib/doorkeeper/oauth/client_credentials/validation.rb +7 -4
  61. data/lib/doorkeeper/oauth/client_credentials_request.rb +3 -1
  62. data/lib/doorkeeper/oauth/code_request.rb +2 -0
  63. data/lib/doorkeeper/oauth/code_response.rb +4 -2
  64. data/lib/doorkeeper/oauth/error.rb +2 -0
  65. data/lib/doorkeeper/oauth/error_response.rb +20 -6
  66. data/lib/doorkeeper/oauth/forbidden_token_response.rb +10 -3
  67. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +25 -8
  68. data/lib/doorkeeper/oauth/helpers/unique_token.rb +15 -1
  69. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +42 -3
  70. data/lib/doorkeeper/oauth/invalid_token_response.rb +22 -0
  71. data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -2
  72. data/lib/doorkeeper/oauth/pre_authorization.rb +13 -5
  73. data/lib/doorkeeper/oauth/refresh_token_request.rb +15 -4
  74. data/lib/doorkeeper/oauth/scopes.rb +7 -3
  75. data/lib/doorkeeper/oauth/token.rb +4 -2
  76. data/lib/doorkeeper/oauth/token_introspection.rb +76 -8
  77. data/lib/doorkeeper/oauth/token_request.rb +2 -0
  78. data/lib/doorkeeper/oauth/token_response.rb +11 -9
  79. data/lib/doorkeeper/oauth.rb +5 -5
  80. data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -13
  81. data/lib/doorkeeper/orm/active_record/access_token.rb +6 -13
  82. data/lib/doorkeeper/orm/active_record/application.rb +26 -7
  83. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
  84. data/lib/doorkeeper/orm/active_record.rb +8 -6
  85. data/lib/doorkeeper/rails/helpers.rb +5 -1
  86. data/lib/doorkeeper/rails/routes/mapper.rb +2 -0
  87. data/lib/doorkeeper/rails/routes/mapping.rb +9 -7
  88. data/lib/doorkeeper/rails/routes.rb +19 -12
  89. data/lib/doorkeeper/rake/db.rake +17 -17
  90. data/lib/doorkeeper/rake.rb +1 -1
  91. data/lib/doorkeeper/request/authorization_code.rb +2 -0
  92. data/lib/doorkeeper/request/client_credentials.rb +2 -0
  93. data/lib/doorkeeper/request/code.rb +2 -0
  94. data/lib/doorkeeper/request/password.rb +2 -0
  95. data/lib/doorkeeper/request/refresh_token.rb +2 -0
  96. data/lib/doorkeeper/request/strategy.rb +2 -0
  97. data/lib/doorkeeper/request/token.rb +2 -0
  98. data/lib/doorkeeper/request.rb +3 -1
  99. data/lib/doorkeeper/secret_storing/base.rb +64 -0
  100. data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
  101. data/lib/doorkeeper/secret_storing/plain.rb +33 -0
  102. data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
  103. data/lib/doorkeeper/server.rb +2 -0
  104. data/lib/doorkeeper/stale_records_cleaner.rb +20 -0
  105. data/lib/doorkeeper/validations.rb +2 -0
  106. data/lib/doorkeeper/version.rb +4 -2
  107. data/lib/doorkeeper.rb +69 -59
  108. data/lib/generators/doorkeeper/application_owner_generator.rb +10 -9
  109. data/lib/generators/doorkeeper/confidential_applications_generator.rb +10 -9
  110. data/lib/generators/doorkeeper/install_generator.rb +11 -9
  111. data/lib/generators/doorkeeper/migration_generator.rb +9 -9
  112. data/lib/generators/doorkeeper/pkce_generator.rb +10 -9
  113. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +10 -9
  114. data/lib/generators/doorkeeper/templates/initializer.rb +138 -13
  115. data/lib/generators/doorkeeper/templates/migration.rb.erb +17 -10
  116. data/lib/generators/doorkeeper/views_generator.rb +6 -4
  117. data/spec/controllers/application_metal_controller_spec.rb +24 -10
  118. data/spec/controllers/applications_controller_spec.rb +76 -78
  119. data/spec/controllers/authorizations_controller_spec.rb +189 -142
  120. data/spec/controllers/protected_resources_controller_spec.rb +111 -67
  121. data/spec/controllers/token_info_controller_spec.rb +14 -12
  122. data/spec/controllers/tokens_controller_spec.rb +170 -112
  123. data/spec/dummy/Rakefile +3 -1
  124. data/spec/dummy/app/controllers/application_controller.rb +3 -1
  125. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +3 -1
  126. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -2
  127. data/spec/dummy/app/controllers/home_controller.rb +6 -5
  128. data/spec/dummy/app/controllers/metal_controller.rb +2 -0
  129. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +4 -2
  130. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  131. data/spec/dummy/app/models/user.rb +2 -0
  132. data/spec/dummy/config/application.rb +26 -2
  133. data/spec/dummy/config/boot.rb +2 -4
  134. data/spec/dummy/config/environment.rb +1 -1
  135. data/spec/dummy/config/environments/development.rb +2 -0
  136. data/spec/dummy/config/environments/production.rb +2 -0
  137. data/spec/dummy/config/environments/test.rb +4 -2
  138. data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
  139. data/spec/dummy/config/initializers/doorkeeper.rb +7 -3
  140. data/spec/dummy/config/initializers/secret_token.rb +3 -1
  141. data/spec/dummy/config/initializers/session_store.rb +3 -1
  142. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
  143. data/spec/dummy/config.ru +3 -1
  144. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +20 -13
  145. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +1 -1
  146. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +2 -0
  147. data/spec/dummy/db/schema.rb +1 -1
  148. data/spec/dummy/script/rails +7 -4
  149. data/spec/factories.rb +11 -9
  150. data/spec/generators/application_owner_generator_spec.rb +13 -26
  151. data/spec/generators/confidential_applications_generator_spec.rb +12 -28
  152. data/spec/generators/install_generator_spec.rb +19 -14
  153. data/spec/generators/migration_generator_spec.rb +13 -26
  154. data/spec/generators/pkce_generator_spec.rb +11 -26
  155. data/spec/generators/previous_refresh_token_generator_spec.rb +16 -29
  156. data/spec/generators/templates/routes.rb +2 -1
  157. data/spec/generators/views_generator_spec.rb +14 -12
  158. data/spec/grape/grape_integration_spec.rb +35 -33
  159. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +9 -7
  160. data/spec/lib/config_spec.rb +290 -104
  161. data/spec/lib/doorkeeper_spec.rb +8 -6
  162. data/spec/lib/models/expirable_spec.rb +22 -8
  163. data/spec/lib/models/reusable_spec.rb +40 -0
  164. data/spec/lib/models/revocable_spec.rb +8 -6
  165. data/spec/lib/models/scopes_spec.rb +27 -13
  166. data/spec/lib/models/secret_storable_spec.rb +135 -0
  167. data/spec/lib/oauth/authorization/uri_builder_spec.rb +17 -15
  168. data/spec/lib/oauth/authorization_code_request_spec.rb +43 -17
  169. data/spec/lib/oauth/base_request_spec.rb +24 -12
  170. data/spec/lib/oauth/base_response_spec.rb +3 -1
  171. data/spec/lib/oauth/client/credentials_spec.rb +26 -24
  172. data/spec/lib/oauth/client_credentials/creator_spec.rb +56 -10
  173. data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -20
  174. data/spec/lib/oauth/client_credentials/validation_spec.rb +21 -15
  175. data/spec/lib/oauth/client_credentials_integration_spec.rb +8 -6
  176. data/spec/lib/oauth/client_credentials_request_spec.rb +27 -21
  177. data/spec/lib/oauth/client_spec.rb +15 -13
  178. data/spec/lib/oauth/code_request_spec.rb +10 -8
  179. data/spec/lib/oauth/code_response_spec.rb +9 -7
  180. data/spec/lib/oauth/error_response_spec.rb +19 -11
  181. data/spec/lib/oauth/error_spec.rb +4 -2
  182. data/spec/lib/oauth/forbidden_token_response_spec.rb +7 -5
  183. data/spec/lib/oauth/helpers/scope_checker_spec.rb +68 -31
  184. data/spec/lib/oauth/helpers/unique_token_spec.rb +8 -6
  185. data/spec/lib/oauth/helpers/uri_checker_spec.rb +124 -93
  186. data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
  187. data/spec/lib/oauth/password_access_token_request_spec.rb +95 -34
  188. data/spec/lib/oauth/pre_authorization_spec.rb +80 -54
  189. data/spec/lib/oauth/refresh_token_request_spec.rb +46 -39
  190. data/spec/lib/oauth/scopes_spec.rb +63 -61
  191. data/spec/lib/oauth/token_request_spec.rb +80 -25
  192. data/spec/lib/oauth/token_response_spec.rb +40 -38
  193. data/spec/lib/oauth/token_spec.rb +64 -45
  194. data/spec/lib/request/strategy_spec.rb +3 -1
  195. data/spec/lib/secret_storing/base_spec.rb +60 -0
  196. data/spec/lib/secret_storing/bcrypt_spec.rb +49 -0
  197. data/spec/lib/secret_storing/plain_spec.rb +44 -0
  198. data/spec/lib/secret_storing/sha256_hash_spec.rb +48 -0
  199. data/spec/lib/server_spec.rb +20 -18
  200. data/spec/lib/{orm/active_record/stale_records_cleaner_spec.rb → stale_records_cleaner_spec.rb} +28 -18
  201. data/spec/models/doorkeeper/access_grant_spec.rb +80 -15
  202. data/spec/models/doorkeeper/access_token_spec.rb +212 -83
  203. data/spec/models/doorkeeper/application_spec.rb +146 -49
  204. data/spec/requests/applications/applications_request_spec.rb +100 -68
  205. data/spec/requests/applications/authorized_applications_spec.rb +20 -18
  206. data/spec/requests/endpoints/authorization_spec.rb +27 -25
  207. data/spec/requests/endpoints/token_spec.rb +38 -36
  208. data/spec/requests/flows/authorization_code_errors_spec.rb +27 -25
  209. data/spec/requests/flows/authorization_code_spec.rb +260 -158
  210. data/spec/requests/flows/client_credentials_spec.rb +54 -52
  211. data/spec/requests/flows/implicit_grant_errors_spec.rb +11 -9
  212. data/spec/requests/flows/implicit_grant_spec.rb +27 -25
  213. data/spec/requests/flows/password_spec.rb +64 -56
  214. data/spec/requests/flows/refresh_token_spec.rb +91 -32
  215. data/spec/requests/flows/revoke_token_spec.rb +49 -63
  216. data/spec/requests/flows/skip_authorization_spec.rb +23 -21
  217. data/spec/requests/protected_resources/metal_spec.rb +7 -5
  218. data/spec/requests/protected_resources/private_api_spec.rb +37 -35
  219. data/spec/routing/custom_controller_routes_spec.rb +71 -65
  220. data/spec/routing/default_routes_spec.rb +22 -20
  221. data/spec/routing/scoped_routes_spec.rb +20 -18
  222. data/spec/spec_helper.rb +15 -13
  223. data/spec/spec_helper_integration.rb +3 -1
  224. data/spec/support/dependencies/factory_bot.rb +3 -1
  225. data/spec/support/doorkeeper_rspec.rb +5 -2
  226. data/spec/support/helpers/access_token_request_helper.rb +3 -1
  227. data/spec/support/helpers/authorization_request_helper.rb +4 -2
  228. data/spec/support/helpers/config_helper.rb +2 -0
  229. data/spec/support/helpers/model_helper.rb +11 -5
  230. data/spec/support/helpers/request_spec_helper.rb +5 -3
  231. data/spec/support/helpers/url_helper.rb +20 -18
  232. data/spec/support/http_method_shim.rb +4 -9
  233. data/spec/support/orm/active_record.rb +3 -1
  234. data/spec/support/shared/controllers_shared_context.rb +68 -10
  235. data/spec/support/shared/hashing_shared_context.rb +36 -0
  236. data/spec/support/shared/models_shared_examples.rb +12 -10
  237. data/spec/validators/redirect_uri_validator_spec.rb +76 -47
  238. data/spec/version/version_spec.rb +7 -5
  239. metadata +70 -21
  240. data/gemfiles/rails_4_2.gemfile +0 -13
  241. data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -10
@@ -1,41 +1,44 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- describe 'Refresh Token Flow' do
3
+ require "spec_helper"
4
+
5
+ describe "Refresh Token Flow" do
4
6
  before do
5
7
  Doorkeeper.configure do
6
8
  orm DOORKEEPER_ORM
7
9
  use_refresh_token
8
10
  end
11
+
9
12
  client_exists
10
13
  end
11
14
 
12
- context 'issuing a refresh token' do
15
+ context "issuing a refresh token" do
13
16
  before do
14
17
  authorization_code_exists application: @client
15
18
  end
16
19
 
17
- it 'client gets the refresh token and refreshes it' do
20
+ it "client gets the refresh token and refreshes it" do
18
21
  post token_endpoint_url(code: @authorization.token, client: @client)
19
22
 
20
23
  token = Doorkeeper::AccessToken.first
21
24
 
22
- should_have_json 'access_token', token.token
23
- should_have_json 'refresh_token', token.refresh_token
25
+ should_have_json "access_token", token.token
26
+ should_have_json "refresh_token", token.refresh_token
24
27
 
25
28
  expect(@authorization.reload).to be_revoked
26
29
 
27
30
  post refresh_token_endpoint_url(client: @client, refresh_token: token.refresh_token)
28
31
 
29
32
  new_token = Doorkeeper::AccessToken.last
30
- should_have_json 'access_token', new_token.token
31
- should_have_json 'refresh_token', new_token.refresh_token
33
+ should_have_json "access_token", new_token.token
34
+ should_have_json "refresh_token", new_token.refresh_token
32
35
 
33
36
  expect(token.token).not_to eq(new_token.token)
34
37
  expect(token.refresh_token).not_to eq(new_token.refresh_token)
35
38
  end
36
39
  end
37
40
 
38
- context 'refreshing the token' do
41
+ context "refreshing the token" do
39
42
  before do
40
43
  @token = FactoryBot.create(
41
44
  :access_token,
@@ -46,23 +49,23 @@ describe 'Refresh Token Flow' do
46
49
  end
47
50
 
48
51
  context "refresh_token revoked on use" do
49
- it 'client request a token with refresh token' do
52
+ it "client request a token with refresh token" do
50
53
  post refresh_token_endpoint_url(
51
54
  client: @client, refresh_token: @token.refresh_token
52
55
  )
53
56
  should_have_json(
54
- 'refresh_token', Doorkeeper::AccessToken.last.refresh_token
57
+ "refresh_token", Doorkeeper::AccessToken.last.refresh_token
55
58
  )
56
59
  expect(@token.reload).not_to be_revoked
57
60
  end
58
61
 
59
- it 'client request a token with expired access token' do
62
+ it "client request a token with expired access token" do
60
63
  @token.update_attribute :expires_in, -100
61
64
  post refresh_token_endpoint_url(
62
65
  client: @client, refresh_token: @token.refresh_token
63
66
  )
64
67
  should_have_json(
65
- 'refresh_token', Doorkeeper::AccessToken.last.refresh_token
68
+ "refresh_token", Doorkeeper::AccessToken.last.refresh_token
66
69
  )
67
70
  expect(@token.reload).not_to be_revoked
68
71
  end
@@ -73,51 +76,107 @@ describe 'Refresh Token Flow' do
73
76
  allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(false)
74
77
  end
75
78
 
76
- it 'client request a token with refresh token' do
79
+ it "client request a token with refresh token" do
77
80
  post refresh_token_endpoint_url(
78
81
  client: @client, refresh_token: @token.refresh_token
79
82
  )
80
83
  should_have_json(
81
- 'refresh_token', Doorkeeper::AccessToken.last.refresh_token
84
+ "refresh_token", Doorkeeper::AccessToken.last.refresh_token
82
85
  )
83
86
  expect(@token.reload).to be_revoked
84
87
  end
85
88
 
86
- it 'client request a token with expired access token' do
89
+ it "client request a token with expired access token" do
87
90
  @token.update_attribute :expires_in, -100
88
91
  post refresh_token_endpoint_url(
89
92
  client: @client, refresh_token: @token.refresh_token
90
93
  )
91
94
  should_have_json(
92
- 'refresh_token', Doorkeeper::AccessToken.last.refresh_token
95
+ "refresh_token", Doorkeeper::AccessToken.last.refresh_token
93
96
  )
94
97
  expect(@token.reload).to be_revoked
95
98
  end
96
99
  end
97
100
 
98
- it 'client gets an error for invalid refresh token' do
99
- post refresh_token_endpoint_url(client: @client, refresh_token: 'invalid')
100
- should_not_have_json 'refresh_token'
101
- should_have_json 'error', 'invalid_grant'
101
+ context "public & private clients" do
102
+ let(:public_client) do
103
+ FactoryBot.create(
104
+ :application,
105
+ confidential: false
106
+ )
107
+ end
108
+
109
+ let(:token_for_private_client) do
110
+ FactoryBot.create(
111
+ :access_token,
112
+ application: @client,
113
+ resource_owner_id: 1,
114
+ use_refresh_token: true
115
+ )
116
+ end
117
+
118
+ let(:token_for_public_client) do
119
+ FactoryBot.create(
120
+ :access_token,
121
+ application: public_client,
122
+ resource_owner_id: 1,
123
+ use_refresh_token: true
124
+ )
125
+ end
126
+
127
+ it "issues a new token without client_secret when refresh token was issued to a public client" do
128
+ post refresh_token_endpoint_url(
129
+ client_id: public_client.uid,
130
+ refresh_token: token_for_public_client.refresh_token
131
+ )
132
+
133
+ new_token = Doorkeeper::AccessToken.last
134
+ should_have_json "access_token", new_token.token
135
+ should_have_json "refresh_token", new_token.refresh_token
136
+ end
137
+
138
+ it "returns an error without credentials" do
139
+ post refresh_token_endpoint_url(refresh_token: token_for_private_client.refresh_token)
140
+
141
+ should_not_have_json "refresh_token"
142
+ should_have_json "error", "invalid_grant"
143
+ end
144
+
145
+ it "returns an error with wrong credentials" do
146
+ post refresh_token_endpoint_url(
147
+ client_id: "1",
148
+ client_secret: "1",
149
+ refresh_token: token_for_private_client.refresh_token
150
+ )
151
+
152
+ should_not_have_json "refresh_token"
153
+ should_have_json "error", "invalid_client"
154
+ end
155
+ end
156
+
157
+ it "client gets an error for invalid refresh token" do
158
+ post refresh_token_endpoint_url(client: @client, refresh_token: "invalid")
159
+ should_not_have_json "refresh_token"
160
+ should_have_json "error", "invalid_grant"
102
161
  end
103
162
 
104
- it 'client gets an error for revoked access token' do
163
+ it "client gets an error for revoked access token" do
105
164
  @token.revoke
106
165
  post refresh_token_endpoint_url(client: @client, refresh_token: @token.refresh_token)
107
- should_not_have_json 'refresh_token'
108
- should_have_json 'error', 'invalid_grant'
166
+ should_not_have_json "refresh_token"
167
+ should_have_json "error", "invalid_grant"
109
168
  end
110
169
 
111
- it 'second of simultaneous client requests get an error for revoked access token' do
170
+ it "second of simultaneous client requests get an error for revoked access token" do
112
171
  allow_any_instance_of(Doorkeeper::AccessToken).to receive(:revoked?).and_return(false, true)
113
172
  post refresh_token_endpoint_url(client: @client, refresh_token: @token.refresh_token)
114
173
 
115
- should_not_have_json 'refresh_token'
116
- should_have_json 'error', 'invalid_request'
174
+ should_not_have_json "refresh_token"
175
+ should_have_json "error", "invalid_request"
117
176
  end
118
177
  end
119
178
 
120
- context 'refreshing the token with multiple sessions (devices)' do
179
+ context "refreshing the token with multiple sessions (devices)" do
121
180
  before do
122
181
  # enable password auth to simulate other devices
123
182
  config_is_set(:grant_flows, ["password"])
@@ -140,12 +199,12 @@ describe 'Refresh Token Flow' do
140
199
  end
141
200
 
142
201
  context "refresh_token revoked on use" do
143
- it 'client request a token after creating another token with the same user' do
202
+ it "client request a token after creating another token with the same user" do
144
203
  post refresh_token_endpoint_url(
145
204
  client: @client, refresh_token: @token.refresh_token
146
205
  )
147
206
 
148
- should_have_json 'refresh_token', last_token.refresh_token
207
+ should_have_json "refresh_token", last_token.refresh_token
149
208
  expect(@token.reload).not_to be_revoked
150
209
  end
151
210
  end
@@ -155,12 +214,12 @@ describe 'Refresh Token Flow' do
155
214
  allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(false)
156
215
  end
157
216
 
158
- it 'client request a token after creating another token with the same user' do
217
+ it "client request a token after creating another token with the same user" do
159
218
  post refresh_token_endpoint_url(
160
219
  client: @client, refresh_token: @token.refresh_token
161
220
  )
162
221
 
163
- should_have_json 'refresh_token', last_token.refresh_token
222
+ should_have_json "refresh_token", last_token.refresh_token
164
223
  expect(@token.reload).to be_revoked
165
224
  end
166
225
  end
@@ -1,155 +1,141 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- describe 'Revoke Token Flow' do
3
+ require "spec_helper"
4
+
5
+ describe "Revoke Token Flow" do
4
6
  before do
5
7
  Doorkeeper.configure { orm DOORKEEPER_ORM }
6
8
  end
7
9
 
8
- context 'with default parameters' do
10
+ context "with default parameters" do
9
11
  let(:client_application) { FactoryBot.create :application }
10
- let(:resource_owner) { User.create!(name: 'John', password: 'sekret') }
12
+ let(:resource_owner) { User.create!(name: "John", password: "sekret") }
11
13
  let(:access_token) do
12
14
  FactoryBot.create(:access_token,
13
- application: client_application,
14
- resource_owner_id: resource_owner.id,
15
- use_refresh_token: true)
15
+ application: client_application,
16
+ resource_owner_id: resource_owner.id,
17
+ use_refresh_token: true)
16
18
  end
17
19
 
18
- context 'with authenticated, confidential OAuth 2.0 client/application' do
20
+ context "with authenticated, confidential OAuth 2.0 client/application" do
19
21
  let(:headers) do
20
22
  client_id = client_application.uid
21
23
  client_secret = client_application.secret
22
24
  credentials = Base64.encode64("#{client_id}:#{client_secret}")
23
- { 'HTTP_AUTHORIZATION' => "Basic #{credentials}" }
25
+ { "HTTP_AUTHORIZATION" => "Basic #{credentials}" }
24
26
  end
25
27
 
26
- it 'should revoke the access token provided' do
28
+ it "should revoke the access token provided" do
27
29
  post revocation_token_endpoint_url, params: { token: access_token.token }, headers: headers
28
30
 
29
- access_token.reload
30
-
31
31
  expect(response).to be_successful
32
- expect(access_token.revoked?).to be_truthy
32
+ expect(access_token.reload.revoked?).to be_truthy
33
33
  end
34
34
 
35
- it 'should revoke the refresh token provided' do
35
+ it "should revoke the refresh token provided" do
36
36
  post revocation_token_endpoint_url, params: { token: access_token.refresh_token }, headers: headers
37
37
 
38
- access_token.reload
39
-
40
38
  expect(response).to be_successful
41
- expect(access_token.revoked?).to be_truthy
39
+ expect(access_token.reload.revoked?).to be_truthy
42
40
  end
43
41
 
44
- context 'with invalid token to revoke' do
45
- it 'should not revoke any tokens and respond successfully' do
46
- num_prev_revoked_tokens = Doorkeeper::AccessToken.where(revoked_at: nil).count
47
- post revocation_token_endpoint_url, params: { token: 'I_AM_AN_INVALID_TOKEN' }, headers: headers
42
+ context "with invalid token to revoke" do
43
+ it "should not revoke any tokens and respond successfully" do
44
+ expect do
45
+ post revocation_token_endpoint_url,
46
+ params: { token: "I_AM_AN_INVALID_TOKEN" },
47
+ headers: headers
48
+ end.not_to(change { Doorkeeper::AccessToken.where(revoked_at: nil).count })
48
49
 
49
50
  # The authorization server responds with HTTP status code 200 even if
50
51
  # token is invalid
51
52
  expect(response).to be_successful
52
- expect(Doorkeeper::AccessToken.where(revoked_at: nil).count).to eq(num_prev_revoked_tokens)
53
53
  end
54
54
  end
55
55
 
56
- context 'with bad credentials and a valid token' do
56
+ context "with bad credentials and a valid token" do
57
57
  let(:headers) do
58
58
  client_id = client_application.uid
59
59
  credentials = Base64.encode64("#{client_id}:poop")
60
- { 'HTTP_AUTHORIZATION' => "Basic #{credentials}" }
60
+ { "HTTP_AUTHORIZATION" => "Basic #{credentials}" }
61
61
  end
62
- it 'should not revoke any tokens and respond successfully' do
62
+ it "should not revoke any tokens and respond successfully" do
63
63
  post revocation_token_endpoint_url, params: { token: access_token.token }, headers: headers
64
64
 
65
- access_token.reload
66
-
67
65
  expect(response).to be_successful
68
- expect(access_token.revoked?).to be_falsey
66
+ expect(access_token.reload.revoked?).to be_falsey
69
67
  end
70
68
  end
71
69
 
72
- context 'with no credentials and a valid token' do
73
- it 'should not revoke any tokens and respond successfully' do
70
+ context "with no credentials and a valid token" do
71
+ it "should not revoke any tokens and respond successfully" do
74
72
  post revocation_token_endpoint_url, params: { token: access_token.token }
75
73
 
76
- access_token.reload
77
-
78
74
  expect(response).to be_successful
79
- expect(access_token.revoked?).to be_falsey
75
+ expect(access_token.reload.revoked?).to be_falsey
80
76
  end
81
77
  end
82
78
 
83
- context 'with valid token for another client application' do
79
+ context "with valid token for another client application" do
84
80
  let(:other_client_application) { FactoryBot.create :application }
85
81
  let(:headers) do
86
82
  client_id = other_client_application.uid
87
83
  client_secret = other_client_application.secret
88
84
  credentials = Base64.encode64("#{client_id}:#{client_secret}")
89
- { 'HTTP_AUTHORIZATION' => "Basic #{credentials}" }
85
+ { "HTTP_AUTHORIZATION" => "Basic #{credentials}" }
90
86
  end
91
87
 
92
- it 'should not revoke the token as its unauthorized' do
88
+ it "should not revoke the token as its unauthorized" do
93
89
  post revocation_token_endpoint_url, params: { token: access_token.token }, headers: headers
94
90
 
95
- access_token.reload
96
-
97
91
  expect(response).to be_successful
98
- expect(access_token.revoked?).to be_falsey
92
+ expect(access_token.reload.revoked?).to be_falsey
99
93
  end
100
94
  end
101
95
  end
102
96
 
103
- context 'with public OAuth 2.0 client/application' do
97
+ context "with public OAuth 2.0 client/application" do
104
98
  let(:access_token) do
105
99
  FactoryBot.create(:access_token,
106
- application: nil,
107
- resource_owner_id: resource_owner.id,
108
- use_refresh_token: true)
100
+ application: nil,
101
+ resource_owner_id: resource_owner.id,
102
+ use_refresh_token: true)
109
103
  end
110
104
 
111
- it 'should revoke the access token provided' do
105
+ it "should revoke the access token provided" do
112
106
  post revocation_token_endpoint_url, params: { token: access_token.token }
113
107
 
114
- access_token.reload
115
-
116
108
  expect(response).to be_successful
117
- expect(access_token.revoked?).to be_truthy
109
+ expect(access_token.reload.revoked?).to be_truthy
118
110
  end
119
111
 
120
- it 'should revoke the refresh token provided' do
112
+ it "should revoke the refresh token provided" do
121
113
  post revocation_token_endpoint_url, params: { token: access_token.refresh_token }
122
114
 
123
- access_token.reload
124
-
125
115
  expect(response).to be_successful
126
- expect(access_token.revoked?).to be_truthy
116
+ expect(access_token.reload.revoked?).to be_truthy
127
117
  end
128
118
 
129
- context 'with a valid token issued for a confidential client' do
119
+ context "with a valid token issued for a confidential client" do
130
120
  let(:access_token) do
131
121
  FactoryBot.create(:access_token,
132
- application: client_application,
133
- resource_owner_id: resource_owner.id,
134
- use_refresh_token: true)
122
+ application: client_application,
123
+ resource_owner_id: resource_owner.id,
124
+ use_refresh_token: true)
135
125
  end
136
126
 
137
- it 'should not revoke the access token provided' do
127
+ it "should not revoke the access token provided" do
138
128
  post revocation_token_endpoint_url, params: { token: access_token.token }
139
129
 
140
- access_token.reload
141
-
142
130
  expect(response).to be_successful
143
- expect(access_token.revoked?).to be_falsey
131
+ expect(access_token.reload.revoked?).to be_falsey
144
132
  end
145
133
 
146
- it 'should not revoke the refresh token provided' do
134
+ it "should not revoke the refresh token provided" do
147
135
  post revocation_token_endpoint_url, params: { token: access_token.token }
148
136
 
149
- access_token.reload
150
-
151
137
  expect(response).to be_successful
152
- expect(access_token.revoked?).to be_falsey
138
+ expect(access_token.reload.revoked?).to be_falsey
153
139
  end
154
140
  end
155
141
  end
@@ -1,20 +1,22 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- feature 'Skip authorization form' do
3
+ require "spec_helper"
4
+
5
+ feature "Skip authorization form" do
4
6
  background do
5
- config_is_set(:authenticate_resource_owner) { User.first || redirect_to('/sign_in') }
7
+ config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
6
8
  client_exists
7
9
  default_scopes_exist :public
8
10
  optional_scopes_exist :write
9
11
  end
10
12
 
11
- context 'for previously authorized clients' do
13
+ context "for previously authorized clients" do
12
14
  background do
13
15
  create_resource_owner
14
16
  sign_in
15
17
  end
16
18
 
17
- scenario 'skips the authorization and return a new grant code' do
19
+ scenario "skips the authorization and return a new grant code" do
18
20
  client_is_authorized(@client, @resource_owner, scopes: "public")
19
21
  visit authorization_endpoint_url(client: @client, scope: "public")
20
22
 
@@ -35,29 +37,29 @@ feature 'Skip authorization form' do
35
37
  url_should_have_param "code", Doorkeeper::AccessGrant.first.token
36
38
  end
37
39
 
38
- scenario 'does not skip authorization when scopes differ (new request has fewer scopes)' do
39
- client_is_authorized(@client, @resource_owner, scopes: 'public write')
40
- visit authorization_endpoint_url(client: @client, scope: 'public')
41
- i_should_see 'Authorize'
40
+ scenario "does not skip authorization when scopes differ (new request has fewer scopes)" do
41
+ client_is_authorized(@client, @resource_owner, scopes: "public write")
42
+ visit authorization_endpoint_url(client: @client, scope: "public")
43
+ i_should_see "Authorize"
42
44
  end
43
45
 
44
- scenario 'does not skip authorization when scopes differ (new request has more scopes)' do
45
- client_is_authorized(@client, @resource_owner, scopes: 'public write')
46
- visit authorization_endpoint_url(client: @client, scopes: 'public write email')
47
- i_should_see 'Authorize'
46
+ scenario "does not skip authorization when scopes differ (new request has more scopes)" do
47
+ client_is_authorized(@client, @resource_owner, scopes: "public write")
48
+ visit authorization_endpoint_url(client: @client, scopes: "public write email")
49
+ i_should_see "Authorize"
48
50
  end
49
51
 
50
- scenario 'creates grant with new scope when scopes differ' do
51
- client_is_authorized(@client, @resource_owner, scopes: 'public write')
52
- visit authorization_endpoint_url(client: @client, scope: 'public')
53
- click_on 'Authorize'
52
+ scenario "creates grant with new scope when scopes differ" do
53
+ client_is_authorized(@client, @resource_owner, scopes: "public write")
54
+ visit authorization_endpoint_url(client: @client, scope: "public")
55
+ click_on "Authorize"
54
56
  access_grant_should_have_scopes :public
55
57
  end
56
58
 
57
- scenario 'creates grant with new scope when scopes are greater' do
58
- client_is_authorized(@client, @resource_owner, scopes: 'public')
59
- visit authorization_endpoint_url(client: @client, scope: 'public write')
60
- click_on 'Authorize'
59
+ scenario "creates grant with new scope when scopes are greater" do
60
+ client_is_authorized(@client, @resource_owner, scopes: "public")
61
+ visit authorization_endpoint_url(client: @client, scope: "public write")
62
+ click_on "Authorize"
61
63
  access_grant_should_have_scopes :public, :write
62
64
  end
63
65
  end
@@ -1,14 +1,16 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- describe 'ActionController::Metal API' do
3
+ require "spec_helper"
4
+
5
+ describe "ActionController::Metal API" do
4
6
  before do
5
7
  @client = FactoryBot.create(:application)
6
- @resource = User.create!(name: 'Joe', password: 'sekret')
8
+ @resource = User.create!(name: "Joe", password: "sekret")
7
9
  @token = client_is_authorized(@client, @resource)
8
10
  end
9
11
 
10
- it 'client requests protected resource with valid token' do
12
+ it "client requests protected resource with valid token" do
11
13
  get "/metal.json?access_token=#{@token.token}"
12
- should_have_json 'ok', true
14
+ should_have_json "ok", true
13
15
  end
14
16
  end
@@ -1,81 +1,83 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- feature 'Private API' do
3
+ require "spec_helper"
4
+
5
+ feature "Private API" do
4
6
  background do
5
7
  @client = FactoryBot.create(:application)
6
- @resource = User.create!(name: 'Joe', password: 'sekret')
8
+ @resource = User.create!(name: "Joe", password: "sekret")
7
9
  @token = client_is_authorized(@client, @resource)
8
10
  end
9
11
 
10
- scenario 'client requests protected resource with valid token' do
12
+ scenario "client requests protected resource with valid token" do
11
13
  with_access_token_header @token.token
12
- visit '/full_protected_resources'
13
- expect(page.body).to have_content('index')
14
+ visit "/full_protected_resources"
15
+ expect(page.body).to have_content("index")
14
16
  end
15
17
 
16
- scenario 'client requests protected resource with disabled header authentication' do
18
+ scenario "client requests protected resource with disabled header authentication" do
17
19
  config_is_set :access_token_methods, [:from_access_token_param]
18
20
  with_access_token_header @token.token
19
- visit '/full_protected_resources'
21
+ visit "/full_protected_resources"
20
22
  response_status_should_be 401
21
23
  end
22
24
 
23
- scenario 'client attempts to request protected resource with invalid token' do
24
- with_access_token_header 'invalid'
25
- visit '/full_protected_resources'
25
+ scenario "client attempts to request protected resource with invalid token" do
26
+ with_access_token_header "invalid"
27
+ visit "/full_protected_resources"
26
28
  response_status_should_be 401
27
29
  end
28
30
 
29
- scenario 'client attempts to request protected resource with expired token' do
31
+ scenario "client attempts to request protected resource with expired token" do
30
32
  @token.update_attribute :expires_in, -100 # expires token
31
33
  with_access_token_header @token.token
32
- visit '/full_protected_resources'
34
+ visit "/full_protected_resources"
33
35
  response_status_should_be 401
34
36
  end
35
37
 
36
- scenario 'client requests protected resource with permanent token' do
38
+ scenario "client requests protected resource with permanent token" do
37
39
  @token.update_attribute :expires_in, nil # never expires
38
40
  with_access_token_header @token.token
39
- visit '/full_protected_resources'
40
- expect(page.body).to have_content('index')
41
+ visit "/full_protected_resources"
42
+ expect(page.body).to have_content("index")
41
43
  end
42
44
 
43
- scenario 'access token with no default scopes' do
44
- Doorkeeper.configuration.instance_eval {
45
+ scenario "access token with no default scopes" do
46
+ Doorkeeper.configuration.instance_eval do
45
47
  @default_scopes = Doorkeeper::OAuth::Scopes.from_array([:public])
46
48
  @scopes = default_scopes + optional_scopes
47
- }
48
- @token.update_attribute :scopes, 'dummy'
49
+ end
50
+ @token.update_attribute :scopes, "dummy"
49
51
  with_access_token_header @token.token
50
- visit '/full_protected_resources'
52
+ visit "/full_protected_resources"
51
53
  response_status_should_be 403
52
54
  end
53
55
 
54
- scenario 'access token with no allowed scopes' do
56
+ scenario "access token with no allowed scopes" do
55
57
  @token.update_attribute :scopes, nil
56
58
  with_access_token_header @token.token
57
- visit '/full_protected_resources/1.json'
59
+ visit "/full_protected_resources/1.json"
58
60
  response_status_should_be 403
59
61
  end
60
62
 
61
- scenario 'access token with one of allowed scopes' do
62
- @token.update_attribute :scopes, 'admin'
63
+ scenario "access token with one of allowed scopes" do
64
+ @token.update_attribute :scopes, "admin"
63
65
  with_access_token_header @token.token
64
- visit '/full_protected_resources/1.json'
65
- expect(page.body).to have_content('show')
66
+ visit "/full_protected_resources/1.json"
67
+ expect(page.body).to have_content("show")
66
68
  end
67
69
 
68
- scenario 'access token with another of allowed scopes' do
69
- @token.update_attribute :scopes, 'write'
70
+ scenario "access token with another of allowed scopes" do
71
+ @token.update_attribute :scopes, "write"
70
72
  with_access_token_header @token.token
71
- visit '/full_protected_resources/1.json'
72
- expect(page.body).to have_content('show')
73
+ visit "/full_protected_resources/1.json"
74
+ expect(page.body).to have_content("show")
73
75
  end
74
76
 
75
- scenario 'access token with both allowed scopes' do
76
- @token.update_attribute :scopes, 'write admin'
77
+ scenario "access token with both allowed scopes" do
78
+ @token.update_attribute :scopes, "write admin"
77
79
  with_access_token_header @token.token
78
- visit '/full_protected_resources/1.json'
79
- expect(page.body).to have_content('show')
80
+ visit "/full_protected_resources/1.json"
81
+ expect(page.body).to have_content("show")
80
82
  end
81
83
  end