doorkeeper 5.0.3 → 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 (215) hide show
  1. checksums.yaml +4 -4
  2. data/.hound.yml +2 -1
  3. data/.rubocop.yml +37 -4
  4. data/.travis.yml +11 -21
  5. data/Appraisals +29 -7
  6. data/Dangerfile +5 -2
  7. data/Gemfile +19 -5
  8. data/NEWS.md +81 -21
  9. data/README.md +75 -485
  10. data/Rakefile +10 -8
  11. data/app/controllers/doorkeeper/application_controller.rb +1 -2
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +2 -13
  13. data/app/controllers/doorkeeper/applications_controller.rb +20 -8
  14. data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
  15. data/app/controllers/doorkeeper/token_info_controller.rb +2 -2
  16. data/app/controllers/doorkeeper/tokens_controller.rb +11 -11
  17. data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
  18. data/app/validators/redirect_uri_validator.rb +5 -2
  19. data/app/views/doorkeeper/applications/_form.html.erb +6 -0
  20. data/app/views/doorkeeper/applications/show.html.erb +1 -1
  21. data/app/views/layouts/doorkeeper/admin.html.erb +5 -3
  22. data/bin/console +16 -0
  23. data/config/locales/en.yml +1 -0
  24. data/doorkeeper.gemspec +24 -21
  25. data/gemfiles/rails_5_0.gemfile +9 -4
  26. data/gemfiles/rails_5_1.gemfile +9 -4
  27. data/gemfiles/rails_5_2.gemfile +10 -5
  28. data/gemfiles/rails_6_0.gemfile +17 -0
  29. data/gemfiles/rails_master.gemfile +9 -9
  30. data/lib/doorkeeper/config/option.rb +64 -0
  31. data/lib/doorkeeper/config.rb +191 -75
  32. data/lib/doorkeeper/engine.rb +1 -1
  33. data/lib/doorkeeper/grape/authorization_decorator.rb +4 -4
  34. data/lib/doorkeeper/grape/helpers.rb +3 -3
  35. data/lib/doorkeeper/helpers/controller.rb +3 -2
  36. data/lib/doorkeeper/models/access_grant_mixin.rb +20 -3
  37. data/lib/doorkeeper/models/access_token_mixin.rb +63 -19
  38. data/lib/doorkeeper/models/application_mixin.rb +43 -1
  39. data/lib/doorkeeper/models/concerns/expirable.rb +4 -2
  40. data/lib/doorkeeper/models/concerns/ownership.rb +1 -6
  41. data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
  42. data/lib/doorkeeper/models/concerns/revocable.rb +2 -1
  43. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  44. data/lib/doorkeeper/models/concerns/secret_storable.rb +108 -0
  45. data/lib/doorkeeper/oauth/authorization/code.rb +2 -2
  46. data/lib/doorkeeper/oauth/authorization/token.rb +12 -7
  47. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +1 -1
  48. data/lib/doorkeeper/oauth/authorization_code_request.rb +6 -4
  49. data/lib/doorkeeper/oauth/client.rb +1 -1
  50. data/lib/doorkeeper/oauth/client_credentials/validation.rb +5 -4
  51. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
  52. data/lib/doorkeeper/oauth/code_response.rb +2 -2
  53. data/lib/doorkeeper/oauth/error_response.rb +10 -6
  54. data/lib/doorkeeper/oauth/forbidden_token_response.rb +1 -1
  55. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +23 -8
  56. data/lib/doorkeeper/oauth/helpers/unique_token.rb +13 -1
  57. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +37 -1
  58. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -1
  59. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -2
  60. data/lib/doorkeeper/oauth/pre_authorization.rb +11 -5
  61. data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -2
  62. data/lib/doorkeeper/oauth/scopes.rb +5 -3
  63. data/lib/doorkeeper/oauth/token.rb +2 -2
  64. data/lib/doorkeeper/oauth/token_introspection.rb +74 -8
  65. data/lib/doorkeeper/oauth/token_response.rb +9 -9
  66. data/lib/doorkeeper/oauth.rb +5 -5
  67. data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -13
  68. data/lib/doorkeeper/orm/active_record/access_token.rb +6 -13
  69. data/lib/doorkeeper/orm/active_record/application.rb +21 -57
  70. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
  71. data/lib/doorkeeper/orm/active_record.rb +6 -6
  72. data/lib/doorkeeper/rails/helpers.rb +1 -1
  73. data/lib/doorkeeper/rails/routes/mapping.rb +7 -7
  74. data/lib/doorkeeper/rails/routes.rb +11 -11
  75. data/lib/doorkeeper/rake/db.rake +13 -13
  76. data/lib/doorkeeper/rake.rb +1 -1
  77. data/lib/doorkeeper/request.rb +1 -1
  78. data/lib/doorkeeper/secret_storing/base.rb +64 -0
  79. data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
  80. data/lib/doorkeeper/secret_storing/plain.rb +33 -0
  81. data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
  82. data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
  83. data/lib/doorkeeper/version.rb +3 -3
  84. data/lib/doorkeeper.rb +69 -60
  85. data/lib/generators/doorkeeper/application_owner_generator.rb +10 -9
  86. data/lib/generators/doorkeeper/confidential_applications_generator.rb +10 -9
  87. data/lib/generators/doorkeeper/install_generator.rb +11 -9
  88. data/lib/generators/doorkeeper/migration_generator.rb +9 -9
  89. data/lib/generators/doorkeeper/pkce_generator.rb +10 -9
  90. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +10 -9
  91. data/lib/generators/doorkeeper/templates/initializer.rb +120 -13
  92. data/lib/generators/doorkeeper/templates/migration.rb.erb +15 -7
  93. data/lib/generators/doorkeeper/views_generator.rb +6 -4
  94. data/spec/controllers/application_metal_controller_spec.rb +24 -10
  95. data/spec/controllers/applications_controller_spec.rb +54 -52
  96. data/spec/controllers/authorizations_controller_spec.rb +139 -145
  97. data/spec/controllers/protected_resources_controller_spec.rb +78 -76
  98. data/spec/controllers/token_info_controller_spec.rb +14 -12
  99. data/spec/controllers/tokens_controller_spec.rb +167 -108
  100. data/spec/dummy/Rakefile +3 -1
  101. data/spec/dummy/app/controllers/application_controller.rb +3 -1
  102. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +2 -0
  103. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -2
  104. data/spec/dummy/app/controllers/home_controller.rb +5 -3
  105. data/spec/dummy/app/controllers/metal_controller.rb +2 -0
  106. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +4 -2
  107. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  108. data/spec/dummy/app/models/user.rb +2 -0
  109. data/spec/dummy/config/application.rb +25 -1
  110. data/spec/dummy/config/environments/development.rb +2 -0
  111. data/spec/dummy/config/environments/production.rb +2 -0
  112. data/spec/dummy/config/environments/test.rb +3 -1
  113. data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
  114. data/spec/dummy/config/initializers/doorkeeper.rb +5 -2
  115. data/spec/dummy/config/initializers/secret_token.rb +3 -1
  116. data/spec/dummy/config/initializers/session_store.rb +3 -1
  117. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
  118. data/spec/dummy/config.ru +3 -1
  119. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +17 -10
  120. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +2 -0
  121. data/spec/dummy/db/schema.rb +1 -1
  122. data/spec/dummy/script/rails +5 -3
  123. data/spec/factories.rb +8 -6
  124. data/spec/generators/application_owner_generator_spec.rb +13 -26
  125. data/spec/generators/confidential_applications_generator_spec.rb +12 -28
  126. data/spec/generators/install_generator_spec.rb +17 -15
  127. data/spec/generators/migration_generator_spec.rb +13 -26
  128. data/spec/generators/pkce_generator_spec.rb +11 -26
  129. data/spec/generators/previous_refresh_token_generator_spec.rb +16 -29
  130. data/spec/generators/templates/routes.rb +2 -0
  131. data/spec/generators/views_generator_spec.rb +14 -12
  132. data/spec/grape/grape_integration_spec.rb +34 -32
  133. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +9 -7
  134. data/spec/lib/config_spec.rb +268 -99
  135. data/spec/lib/doorkeeper_spec.rb +3 -1
  136. data/spec/lib/models/expirable_spec.rb +22 -8
  137. data/spec/lib/models/reusable_spec.rb +40 -0
  138. data/spec/lib/models/revocable_spec.rb +8 -6
  139. data/spec/lib/models/scopes_spec.rb +27 -13
  140. data/spec/lib/models/secret_storable_spec.rb +135 -0
  141. data/spec/lib/oauth/authorization/uri_builder_spec.rb +17 -15
  142. data/spec/lib/oauth/authorization_code_request_spec.rb +34 -11
  143. data/spec/lib/oauth/base_request_spec.rb +20 -8
  144. data/spec/lib/oauth/base_response_spec.rb +3 -1
  145. data/spec/lib/oauth/client/credentials_spec.rb +24 -22
  146. data/spec/lib/oauth/client_credentials/creator_spec.rb +56 -10
  147. data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -18
  148. data/spec/lib/oauth/client_credentials/validation_spec.rb +20 -15
  149. data/spec/lib/oauth/client_credentials_integration_spec.rb +7 -5
  150. data/spec/lib/oauth/client_credentials_request_spec.rb +27 -21
  151. data/spec/lib/oauth/client_spec.rb +15 -13
  152. data/spec/lib/oauth/code_request_spec.rb +8 -6
  153. data/spec/lib/oauth/code_response_spec.rb +9 -7
  154. data/spec/lib/oauth/error_response_spec.rb +19 -11
  155. data/spec/lib/oauth/error_spec.rb +4 -2
  156. data/spec/lib/oauth/forbidden_token_response_spec.rb +7 -5
  157. data/spec/lib/oauth/helpers/scope_checker_spec.rb +68 -31
  158. data/spec/lib/oauth/helpers/unique_token_spec.rb +8 -6
  159. data/spec/lib/oauth/helpers/uri_checker_spec.rb +115 -95
  160. data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
  161. data/spec/lib/oauth/password_access_token_request_spec.rb +79 -30
  162. data/spec/lib/oauth/pre_authorization_spec.rb +80 -54
  163. data/spec/lib/oauth/refresh_token_request_spec.rb +36 -33
  164. data/spec/lib/oauth/scopes_spec.rb +63 -61
  165. data/spec/lib/oauth/token_request_spec.rb +79 -24
  166. data/spec/lib/oauth/token_response_spec.rb +40 -38
  167. data/spec/lib/oauth/token_spec.rb +60 -44
  168. data/spec/lib/request/strategy_spec.rb +3 -1
  169. data/spec/lib/secret_storing/base_spec.rb +60 -0
  170. data/spec/lib/secret_storing/bcrypt_spec.rb +49 -0
  171. data/spec/lib/secret_storing/plain_spec.rb +44 -0
  172. data/spec/lib/secret_storing/sha256_hash_spec.rb +48 -0
  173. data/spec/lib/server_spec.rb +16 -14
  174. data/spec/lib/stale_records_cleaner_spec.rb +17 -17
  175. data/spec/models/doorkeeper/access_grant_spec.rb +80 -15
  176. data/spec/models/doorkeeper/access_token_spec.rb +198 -73
  177. data/spec/models/doorkeeper/application_spec.rb +280 -288
  178. data/spec/requests/applications/applications_request_spec.rb +98 -66
  179. data/spec/requests/applications/authorized_applications_spec.rb +20 -18
  180. data/spec/requests/endpoints/authorization_spec.rb +25 -23
  181. data/spec/requests/endpoints/token_spec.rb +38 -36
  182. data/spec/requests/flows/authorization_code_errors_spec.rb +26 -24
  183. data/spec/requests/flows/authorization_code_spec.rb +193 -151
  184. data/spec/requests/flows/client_credentials_spec.rb +54 -52
  185. data/spec/requests/flows/implicit_grant_errors_spec.rb +10 -8
  186. data/spec/requests/flows/implicit_grant_spec.rb +27 -25
  187. data/spec/requests/flows/password_spec.rb +59 -55
  188. data/spec/requests/flows/refresh_token_spec.rb +45 -43
  189. data/spec/requests/flows/revoke_token_spec.rb +40 -54
  190. data/spec/requests/flows/skip_authorization_spec.rb +23 -21
  191. data/spec/requests/protected_resources/metal_spec.rb +7 -5
  192. data/spec/requests/protected_resources/private_api_spec.rb +35 -33
  193. data/spec/routing/custom_controller_routes_spec.rb +71 -65
  194. data/spec/routing/default_routes_spec.rb +22 -20
  195. data/spec/routing/scoped_routes_spec.rb +20 -18
  196. data/spec/spec_helper.rb +15 -13
  197. data/spec/spec_helper_integration.rb +3 -1
  198. data/spec/support/dependencies/factory_bot.rb +3 -1
  199. data/spec/support/doorkeeper_rspec.rb +3 -1
  200. data/spec/support/helpers/access_token_request_helper.rb +3 -1
  201. data/spec/support/helpers/authorization_request_helper.rb +4 -2
  202. data/spec/support/helpers/config_helper.rb +2 -0
  203. data/spec/support/helpers/model_helper.rb +3 -1
  204. data/spec/support/helpers/request_spec_helper.rb +5 -3
  205. data/spec/support/helpers/url_helper.rb +9 -7
  206. data/spec/support/http_method_shim.rb +4 -9
  207. data/spec/support/orm/active_record.rb +3 -1
  208. data/spec/support/shared/controllers_shared_context.rb +18 -16
  209. data/spec/support/shared/hashing_shared_context.rb +36 -0
  210. data/spec/support/shared/models_shared_examples.rb +12 -10
  211. data/spec/validators/redirect_uri_validator_spec.rb +74 -45
  212. data/spec/version/version_spec.rb +7 -5
  213. metadata +60 -26
  214. data/gemfiles/rails_4_2.gemfile +0 -13
  215. data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -8
@@ -1,4 +1,6 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper
4
6
  unless defined?(AccessToken)
@@ -12,108 +14,122 @@ module Doorkeeper
12
14
  let(:request) { double.as_null_object }
13
15
 
14
16
  let(:method) do
15
- ->(*) { 'token-value' }
17
+ ->(*) { "token-value" }
16
18
  end
17
19
 
18
- it 'accepts anything that responds to #call' do
20
+ it "accepts anything that responds to #call" do
19
21
  expect(method).to receive(:call).with(request)
20
22
  Token.from_request request, method
21
23
  end
22
24
 
23
- it 'delegates methods received as symbols to Token class' do
25
+ it "delegates methods received as symbols to Token class" do
24
26
  expect(Token).to receive(:from_params).with(request)
25
27
  Token.from_request request, :from_params
26
28
  end
27
29
 
28
- it 'stops at the first credentials found' do
30
+ it "stops at the first credentials found" do
29
31
  not_called_method = double
30
32
  expect(not_called_method).not_to receive(:call)
31
33
  Token.from_request request, ->(_r) {}, method, not_called_method
32
34
  end
33
35
 
34
- it 'returns the credential from extractor method' do
36
+ it "returns the credential from extractor method" do
35
37
  credentials = Token.from_request request, method
36
- expect(credentials).to eq('token-value')
38
+ expect(credentials).to eq("token-value")
37
39
  end
38
40
  end
39
41
 
40
42
  describe :from_access_token_param do
41
- it 'returns token from access_token parameter' do
42
- request = double parameters: { access_token: 'some-token' }
43
+ it "returns token from access_token parameter" do
44
+ request = double parameters: { access_token: "some-token" }
43
45
  token = Token.from_access_token_param(request)
44
- expect(token).to eq('some-token')
46
+ expect(token).to eq("some-token")
45
47
  end
46
48
  end
47
49
 
48
50
  describe :from_bearer_param do
49
- it 'returns token from bearer_token parameter' do
50
- request = double parameters: { bearer_token: 'some-token' }
51
+ it "returns token from bearer_token parameter" do
52
+ request = double parameters: { bearer_token: "some-token" }
51
53
  token = Token.from_bearer_param(request)
52
- expect(token).to eq('some-token')
54
+ expect(token).to eq("some-token")
53
55
  end
54
56
  end
55
57
 
56
58
  describe :from_bearer_authorization do
57
- it 'returns token from capitalized authorization bearer' do
58
- request = double authorization: 'Bearer SomeToken'
59
+ it "returns token from capitalized authorization bearer" do
60
+ request = double authorization: "Bearer SomeToken"
59
61
  token = Token.from_bearer_authorization(request)
60
- expect(token).to eq('SomeToken')
62
+ expect(token).to eq("SomeToken")
61
63
  end
62
64
 
63
- it 'returns token from lowercased authorization bearer' do
64
- request = double authorization: 'bearer SomeToken'
65
+ it "returns token from lowercased authorization bearer" do
66
+ request = double authorization: "bearer SomeToken"
65
67
  token = Token.from_bearer_authorization(request)
66
- expect(token).to eq('SomeToken')
68
+ expect(token).to eq("SomeToken")
67
69
  end
68
70
 
69
- it 'does not return token if authorization is not bearer' do
70
- request = double authorization: 'MAC SomeToken'
71
+ it "does not return token if authorization is not bearer" do
72
+ request = double authorization: "MAC SomeToken"
71
73
  token = Token.from_bearer_authorization(request)
72
74
  expect(token).to be_blank
73
75
  end
74
76
  end
75
77
 
76
78
  describe :from_basic_authorization do
77
- it 'returns token from capitalized authorization basic' do
78
- request = double authorization: "Basic #{Base64.encode64 'SomeToken:'}"
79
+ it "returns token from capitalized authorization basic" do
80
+ request = double authorization: "Basic #{Base64.encode64 "SomeToken:"}"
79
81
  token = Token.from_basic_authorization(request)
80
- expect(token).to eq('SomeToken')
82
+ expect(token).to eq("SomeToken")
81
83
  end
82
84
 
83
- it 'returns token from lowercased authorization basic' do
84
- request = double authorization: "basic #{Base64.encode64 'SomeToken:'}"
85
+ it "returns token from lowercased authorization basic" do
86
+ request = double authorization: "basic #{Base64.encode64 "SomeToken:"}"
85
87
  token = Token.from_basic_authorization(request)
86
- expect(token).to eq('SomeToken')
88
+ expect(token).to eq("SomeToken")
87
89
  end
88
90
 
89
- it 'does not return token if authorization is not basic' do
90
- request = double authorization: "MAC #{Base64.encode64 'SomeToken:'}"
91
+ it "does not return token if authorization is not basic" do
92
+ request = double authorization: "MAC #{Base64.encode64 "SomeToken:"}"
91
93
  token = Token.from_basic_authorization(request)
92
94
  expect(token).to be_blank
93
95
  end
94
96
  end
95
97
 
96
98
  describe :authenticate do
97
- context 'refresh tokens are disabled (default)' do
98
- context 'refresh tokens are enabled' do
99
- it 'does not revoke previous refresh_token if token was found' do
100
- token = ->(_r) { 'token' }
99
+ context "refresh tokens are disabled (default)" do
100
+ context "refresh tokens are enabled" do
101
+ it "does not revoke previous refresh_token if token was found" do
102
+ token = ->(_r) { "token" }
101
103
  expect(
102
104
  AccessToken
103
- ).to receive(:by_token).with('token').and_return(token)
105
+ ).to receive(:by_token).with("token").and_return(token)
104
106
  expect(token).not_to receive(:revoke_previous_refresh_token!)
105
107
  Token.authenticate double, token
106
108
  end
107
109
  end
108
110
 
109
- it 'calls the finder if token was returned' do
110
- token = ->(_r) { 'token' }
111
- expect(AccessToken).to receive(:by_token).with('token')
111
+ it "calls the finder if token was returned" do
112
+ token = ->(_r) { "token" }
113
+ expect(AccessToken).to receive(:by_token).with("token")
114
+ Token.authenticate double, token
115
+ end
116
+ end
117
+
118
+ context "token hashing is enabled" do
119
+ include_context "with token hashing enabled"
120
+
121
+ let(:hashed_token) { hashed_or_plain_token_func.call("token") }
122
+ let(:token) { ->(_r) { "token" } }
123
+
124
+ it "searches with the hashed token" do
125
+ expect(
126
+ AccessToken
127
+ ).to receive(:find_by).with(token: hashed_token).and_return(token)
112
128
  Token.authenticate double, token
113
129
  end
114
130
  end
115
131
 
116
- context 'refresh tokens are enabled' do
132
+ context "refresh tokens are enabled" do
117
133
  before do
118
134
  Doorkeeper.configure do
119
135
  orm DOORKEEPER_ORM
@@ -121,18 +137,18 @@ module Doorkeeper
121
137
  end
122
138
  end
123
139
 
124
- it 'revokes previous refresh_token if token was found' do
125
- token = ->(_r) { 'token' }
140
+ it "revokes previous refresh_token if token was found" do
141
+ token = ->(_r) { "token" }
126
142
  expect(
127
143
  AccessToken
128
- ).to receive(:by_token).with('token').and_return(token)
144
+ ).to receive(:by_token).with("token").and_return(token)
129
145
  expect(token).to receive(:revoke_previous_refresh_token!)
130
146
  Token.authenticate double, token
131
147
  end
132
148
 
133
- it 'calls the finder if token was returned' do
134
- token = ->(_r) { 'token' }
135
- expect(AccessToken).to receive(:by_token).with('token')
149
+ it "calls the finder if token was returned" do
150
+ token = ->(_r) { "token" }
151
+ expect(AccessToken).to receive(:by_token).with("token")
136
152
  Token.authenticate double, token
137
153
  end
138
154
  end
@@ -1,4 +1,6 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper
4
6
  module Request
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe ::Doorkeeper::SecretStoring::Base do
6
+ let(:instance) { double("instance", token: "foo") }
7
+ subject { described_class }
8
+
9
+ describe "#transform_secret" do
10
+ it "raises" do
11
+ expect { subject.transform_secret("foo") }.to raise_error(NotImplementedError)
12
+ end
13
+ end
14
+
15
+ describe "#store_secret" do
16
+ it "sends to response of #transform_secret to the instance" do
17
+ expect(described_class)
18
+ .to receive(:transform_secret).with("bar")
19
+ .and_return "bar+transform"
20
+
21
+ expect(instance).to receive(:token=).with "bar+transform"
22
+ result = subject.store_secret instance, :token, "bar"
23
+ expect(result).to eq "bar+transform"
24
+ end
25
+ end
26
+
27
+ describe "#restore_secret" do
28
+ it "raises" do
29
+ expect { subject.restore_secret(subject, :token) }.to raise_error(NotImplementedError)
30
+ end
31
+ end
32
+
33
+ describe "#allows_restoring_secrets?" do
34
+ it "does not allow it" do
35
+ expect(subject.allows_restoring_secrets?).to eq false
36
+ end
37
+ end
38
+
39
+ describe "validate_for" do
40
+ it "allows for valid model" do
41
+ expect(subject.validate_for(:application)).to eq true
42
+ expect(subject.validate_for(:token)).to eq true
43
+ end
44
+
45
+ it "raises for invalid model" do
46
+ expect { subject.validate_for(:wat) }.to raise_error(ArgumentError, /can not be used for wat/)
47
+ end
48
+ end
49
+
50
+ describe "secret_matches?" do
51
+ before do
52
+ allow(subject).to receive(:transform_secret) { |input| "transformed: #{input}" }
53
+ end
54
+
55
+ it "compares input with #transform_secret" do
56
+ expect(subject.secret_matches?("input", "input")).to eq false
57
+ expect(subject.secret_matches?("a", "transformed: a")).to eq true
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+ require "bcrypt"
5
+
6
+ describe ::Doorkeeper::SecretStoring::BCrypt do
7
+ subject { described_class }
8
+ let(:instance) { double("instance", token: "foo") }
9
+
10
+ describe "#transform_secret" do
11
+ it "creates a bcrypt password" do
12
+ expect(subject.transform_secret("foo")).to be_a BCrypt::Password
13
+ end
14
+ end
15
+
16
+ describe "#restore_secret" do
17
+ it "raises" do
18
+ expect { subject.restore_secret(instance, :token) }.to raise_error(NotImplementedError)
19
+ end
20
+ end
21
+
22
+ describe "#allows_restoring_secrets?" do
23
+ it "does not allow it" do
24
+ expect(subject.allows_restoring_secrets?).to eq false
25
+ end
26
+ end
27
+
28
+ describe "validate_for" do
29
+ it "allows for valid model" do
30
+ expect(subject.validate_for(:application)).to eq true
31
+ end
32
+
33
+ it "raises for invalid model" do
34
+ expect { subject.validate_for(:wat) }
35
+ .to raise_error(ArgumentError, /can only be used for storing application secrets/)
36
+ expect { subject.validate_for(:token) }
37
+ .to raise_error(ArgumentError, /can only be used for storing application secrets/)
38
+ end
39
+ end
40
+
41
+ describe "secret_matches?" do
42
+ it "compares input with #transform_secret" do
43
+ expect(subject.secret_matches?("input", "input")).to eq false
44
+
45
+ password = BCrypt::Password.create "foobar"
46
+ expect(subject.secret_matches?("foobar", password.to_s)).to eq true
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe ::Doorkeeper::SecretStoring::Plain do
6
+ subject { described_class }
7
+ let(:instance) { double("instance", token: "foo") }
8
+
9
+ describe "#transform_secret" do
10
+ it "raises" do
11
+ expect(subject.transform_secret("foo")).to eq "foo"
12
+ end
13
+ end
14
+
15
+ describe "#restore_secret" do
16
+ it "raises" do
17
+ expect(subject.restore_secret(instance, :token)).to eq "foo"
18
+ end
19
+ end
20
+
21
+ describe "#allows_restoring_secrets?" do
22
+ it "does allow it" do
23
+ expect(subject.allows_restoring_secrets?).to eq true
24
+ end
25
+ end
26
+
27
+ describe "validate_for" do
28
+ it "allows for valid model" do
29
+ expect(subject.validate_for(:application)).to eq true
30
+ expect(subject.validate_for(:token)).to eq true
31
+ end
32
+
33
+ it "raises for invalid model" do
34
+ expect { subject.validate_for(:wat) }.to raise_error(ArgumentError, /can not be used for wat/)
35
+ end
36
+ end
37
+
38
+ describe "secret_matches?" do
39
+ it "compares input with #transform_secret" do
40
+ expect(subject.secret_matches?("input", "input")).to eq true
41
+ expect(subject.secret_matches?("a", "b")).to eq false
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe ::Doorkeeper::SecretStoring::Sha256Hash do
6
+ subject { described_class }
7
+ let(:instance) { double("instance") }
8
+
9
+ let(:hash_function) do
10
+ ->(input) { ::Digest::SHA256.hexdigest(input) }
11
+ end
12
+
13
+ describe "#transform_secret" do
14
+ it "raises" do
15
+ expect(subject.transform_secret("foo")).to eq hash_function.call("foo")
16
+ end
17
+ end
18
+
19
+ describe "#restore_secret" do
20
+ it "raises" do
21
+ expect { subject.restore_secret(instance, :token) }.to raise_error(NotImplementedError)
22
+ end
23
+ end
24
+
25
+ describe "#allows_restoring_secrets?" do
26
+ it "does not allow it" do
27
+ expect(subject.allows_restoring_secrets?).to eq false
28
+ end
29
+ end
30
+
31
+ describe "validate_for" do
32
+ it "allows for valid model" do
33
+ expect(subject.validate_for(:application)).to eq true
34
+ expect(subject.validate_for(:token)).to eq true
35
+ end
36
+
37
+ it "raises for invalid model" do
38
+ expect { subject.validate_for(:wat) }.to raise_error(ArgumentError, /can not be used for wat/)
39
+ end
40
+ end
41
+
42
+ describe "secret_matches?" do
43
+ it "compares input with #transform_secret" do
44
+ expect(subject.secret_matches?("input", "input")).to eq false
45
+ expect(subject.secret_matches?("a", hash_function.call("a"))).to eq true
46
+ end
47
+ end
48
+ end
@@ -1,4 +1,6 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  describe Doorkeeper::Server do
4
6
  let(:fake_class) { double :fake_class }
@@ -7,53 +9,53 @@ describe Doorkeeper::Server do
7
9
  described_class.new
8
10
  end
9
11
 
10
- describe '.authorization_request' do
11
- it 'raises error when strategy does not exist' do
12
+ describe ".authorization_request" do
13
+ it "raises error when strategy does not exist" do
12
14
  expect do
13
15
  subject.authorization_request(:duh)
14
16
  end.to raise_error(Doorkeeper::Errors::InvalidAuthorizationStrategy)
15
17
  end
16
18
 
17
- it 'raises error when strategy does not match phase' do
19
+ it "raises error when strategy does not match phase" do
18
20
  expect do
19
21
  subject.token_request(:code)
20
22
  end.to raise_error(Doorkeeper::Errors::InvalidTokenStrategy)
21
23
  end
22
24
 
23
- context 'when only Authorization Code strategy is enabled' do
25
+ context "when only Authorization Code strategy is enabled" do
24
26
  before do
25
27
  allow(Doorkeeper.configuration)
26
28
  .to receive(:grant_flows)
27
- .and_return(['authorization_code'])
29
+ .and_return(["authorization_code"])
28
30
  end
29
31
 
30
- it 'raises error when using the disabled Implicit strategy' do
32
+ it "raises error when using the disabled Implicit strategy" do
31
33
  expect do
32
34
  subject.authorization_request(:token)
33
35
  end.to raise_error(Doorkeeper::Errors::InvalidAuthorizationStrategy)
34
36
  end
35
37
 
36
- it 'raises error when using the disabled Client Credentials strategy' do
38
+ it "raises error when using the disabled Client Credentials strategy" do
37
39
  expect do
38
40
  subject.token_request(:client_credentials)
39
41
  end.to raise_error(Doorkeeper::Errors::InvalidTokenStrategy)
40
42
  end
41
43
  end
42
44
 
43
- it 'builds the request with selected strategy' do
44
- stub_const 'Doorkeeper::Request::Code', fake_class
45
+ it "builds the request with selected strategy" do
46
+ stub_const "Doorkeeper::Request::Code", fake_class
45
47
  expect(fake_class).to receive(:new).with(subject)
46
48
  subject.authorization_request :code
47
49
  end
48
50
 
49
- it 'builds the request with composite strategy name' do
51
+ it "builds the request with composite strategy name" do
50
52
  allow(Doorkeeper.configuration)
51
53
  .to receive(:authorization_response_types)
52
- .and_return(['id_token token'])
54
+ .and_return(["id_token token"])
53
55
 
54
- stub_const 'Doorkeeper::Request::IdTokenToken', fake_class
56
+ stub_const "Doorkeeper::Request::IdTokenToken", fake_class
55
57
  expect(fake_class).to receive(:new).with(subject)
56
- subject.authorization_request 'id_token token'
58
+ subject.authorization_request "id_token token"
57
59
  end
58
60
  end
59
61
  end
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
5
  describe Doorkeeper::StaleRecordsCleaner do
6
6
  let(:cleaner) { described_class.new(model) }
7
7
  let(:models_by_name) do
8
8
  {
9
9
  access_token: Doorkeeper::AccessToken,
10
- access_grant: Doorkeeper::AccessGrant
10
+ access_grant: Doorkeeper::AccessGrant,
11
11
  }
12
12
  end
13
13
 
14
- context 'when ORM has no cleaner class' do
15
- it 'raises an error' do
16
- allow_any_instance_of(Doorkeeper::Config).to receive(:orm).and_return('hibernate')
14
+ context "when ORM has no cleaner class" do
15
+ it "raises an error" do
16
+ allow_any_instance_of(Doorkeeper::Config).to receive(:orm).and_return("hibernate")
17
17
 
18
18
  expect do
19
19
  described_class.for(Doorkeeper::AccessToken)
@@ -25,61 +25,61 @@ describe Doorkeeper::StaleRecordsCleaner do
25
25
  context "(#{model_name})" do
26
26
  let(:model) { models_by_name.fetch(model_name) }
27
27
 
28
- describe '#clean_revoked' do
28
+ describe "#clean_revoked" do
29
29
  subject { cleaner.clean_revoked }
30
30
 
31
- context 'with revoked record' do
31
+ context "with revoked record" do
32
32
  before do
33
33
  FactoryBot.create model_name, revoked_at: Time.current - 1.minute
34
34
  end
35
35
 
36
- it 'removes the record' do
36
+ it "removes the record" do
37
37
  expect { subject }.to change { model.count }.to(0)
38
38
  end
39
39
  end
40
40
 
41
- context 'with record revoked in the future' do
41
+ context "with record revoked in the future" do
42
42
  before do
43
43
  FactoryBot.create model_name, revoked_at: Time.current + 1.minute
44
44
  end
45
45
 
46
- it 'keeps the record' do
46
+ it "keeps the record" do
47
47
  expect { subject }.not_to(change { model.count })
48
48
  end
49
49
  end
50
50
 
51
- context 'with unrevoked record' do
51
+ context "with unrevoked record" do
52
52
  before do
53
53
  FactoryBot.create model_name, revoked_at: nil
54
54
  end
55
55
 
56
- it 'keeps the record' do
56
+ it "keeps the record" do
57
57
  expect { subject }.not_to(change { model.count })
58
58
  end
59
59
  end
60
60
  end
61
61
 
62
- describe '#clean_expired' do
62
+ describe "#clean_expired" do
63
63
  subject { cleaner.clean_expired(ttl) }
64
64
  let(:ttl) { 500 }
65
65
  let(:expiry_border) { ttl.seconds.ago }
66
66
 
67
- context 'with record that is expired' do
67
+ context "with record that is expired" do
68
68
  before do
69
69
  FactoryBot.create model_name, created_at: expiry_border - 1.minute
70
70
  end
71
71
 
72
- it 'removes the record' do
72
+ it "removes the record" do
73
73
  expect { subject }.to change { model.count }.to(0)
74
74
  end
75
75
  end
76
76
 
77
- context 'with record that is not expired' do
77
+ context "with record that is not expired" do
78
78
  before do
79
79
  FactoryBot.create model_name, created_at: expiry_border + 1.minute
80
80
  end
81
81
 
82
- it 'keeps the record' do
82
+ it "keeps the record" do
83
83
  expect { subject }.not_to(change { model.count })
84
84
  end
85
85
  end