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,15 +1,17 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  class Doorkeeper::OAuth::Client
4
6
  describe Credentials do
5
- let(:client_id) { 'some-uid' }
6
- let(:client_secret) { 'some-secret' }
7
+ let(:client_id) { "some-uid" }
8
+ let(:client_secret) { "some-secret" }
7
9
 
8
- it 'is blank when the uid in credentials is blank' do
10
+ it "is blank when the uid in credentials is blank" do
9
11
  expect(Credentials.new(nil, nil)).to be_blank
10
- expect(Credentials.new(nil, 'something')).to be_blank
11
- expect(Credentials.new('something', nil)).to be_present
12
- expect(Credentials.new('something', 'something')).to be_present
12
+ expect(Credentials.new(nil, "something")).to be_blank
13
+ expect(Credentials.new("something", nil)).to be_present
14
+ expect(Credentials.new("something", "something")).to be_present
13
15
  end
14
16
 
15
17
  describe :from_request do
@@ -19,44 +21,44 @@ class Doorkeeper::OAuth::Client
19
21
  ->(_request) { %w[uid secret] }
20
22
  end
21
23
 
22
- it 'accepts anything that responds to #call' do
24
+ it "accepts anything that responds to #call" do
23
25
  expect(method).to receive(:call).with(request)
24
26
  Credentials.from_request request, method
25
27
  end
26
28
 
27
- it 'delegates methods received as symbols to Credentials class' do
29
+ it "delegates methods received as symbols to Credentials class" do
28
30
  expect(Credentials).to receive(:from_params).with(request)
29
31
  Credentials.from_request request, :from_params
30
32
  end
31
33
 
32
- it 'stops at the first credentials found' do
34
+ it "stops at the first credentials found" do
33
35
  not_called_method = double
34
36
  expect(not_called_method).not_to receive(:call)
35
37
  Credentials.from_request request, ->(_) {}, method, not_called_method
36
38
  end
37
39
 
38
- it 'returns new Credentials' do
40
+ it "returns new Credentials" do
39
41
  credentials = Credentials.from_request request, method
40
42
  expect(credentials).to be_a(Credentials)
41
43
  end
42
44
 
43
- it 'returns uid and secret from extractor method' do
45
+ it "returns uid and secret from extractor method" do
44
46
  credentials = Credentials.from_request request, method
45
- expect(credentials.uid).to eq('uid')
46
- expect(credentials.secret).to eq('secret')
47
+ expect(credentials.uid).to eq("uid")
48
+ expect(credentials.secret).to eq("secret")
47
49
  end
48
50
  end
49
51
 
50
52
  describe :from_params do
51
- it 'returns credentials from parameters when Authorization header is not available' do
53
+ it "returns credentials from parameters when Authorization header is not available" do
52
54
  request = double parameters: { client_id: client_id, client_secret: client_secret }
53
55
  uid, secret = Credentials.from_params(request)
54
56
 
55
- expect(uid).to eq('some-uid')
56
- expect(secret).to eq('some-secret')
57
+ expect(uid).to eq("some-uid")
58
+ expect(secret).to eq("some-secret")
57
59
  end
58
60
 
59
- it 'is blank when there are no credentials' do
61
+ it "is blank when there are no credentials" do
60
62
  request = double parameters: {}
61
63
  uid, secret = Credentials.from_params(request)
62
64
 
@@ -68,15 +70,15 @@ class Doorkeeper::OAuth::Client
68
70
  describe :from_basic do
69
71
  let(:credentials) { Base64.encode64("#{client_id}:#{client_secret}") }
70
72
 
71
- it 'decodes the credentials' do
73
+ it "decodes the credentials" do
72
74
  request = double authorization: "Basic #{credentials}"
73
75
  uid, secret = Credentials.from_basic(request)
74
76
 
75
- expect(uid).to eq('some-uid')
76
- expect(secret).to eq('some-secret')
77
+ expect(uid).to eq("some-uid")
78
+ expect(secret).to eq("some-secret")
77
79
  end
78
80
 
79
- it 'is blank if Authorization is not Basic' do
81
+ it "is blank if Authorization is not Basic" do
80
82
  request = double authorization: credentials.to_s
81
83
  uid, secret = Credentials.from_basic(request)
82
84
 
@@ -1,29 +1,75 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  class Doorkeeper::OAuth::ClientCredentialsRequest
4
6
  describe Creator do
5
7
  let(:client) { FactoryBot.create :application }
6
- let(:scopes) { Doorkeeper::OAuth::Scopes.from_string('public') }
8
+ let(:scopes) { Doorkeeper::OAuth::Scopes.from_string("public") }
7
9
 
8
10
  before do
9
11
  default_scopes_exist :public
10
12
  end
11
13
 
12
- it 'creates a new token' do
14
+ it "creates a new token" do
13
15
  expect do
14
16
  subject.call(client, scopes)
15
17
  end.to change { Doorkeeper::AccessToken.count }.by(1)
16
18
  end
17
19
 
18
20
  context "when reuse_access_token is true" do
19
- it "returns the existing valid token" do
20
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
21
- existing_token = subject.call(client, scopes)
21
+ context "when expiration is disabled" do
22
+ it "returns the existing valid token" do
23
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
24
+ existing_token = subject.call(client, scopes)
22
25
 
23
- result = subject.call(client, scopes)
26
+ result = subject.call(client, scopes)
27
+
28
+ expect(Doorkeeper::AccessToken.count).to eq(1)
29
+ expect(result).to eq(existing_token)
30
+ end
31
+ end
32
+
33
+ context "when existing token has not crossed token_reuse_limit" do
34
+ it "returns the existing valid token" do
35
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
36
+ allow(Doorkeeper.configuration).to receive(:token_reuse_limit).and_return(50)
37
+ existing_token = subject.call(client, scopes, expires_in: 1000)
38
+
39
+ allow_any_instance_of(Doorkeeper::AccessToken).to receive(:expires_in_seconds).and_return(600)
40
+ result = subject.call(client, scopes, expires_in: 1000)
41
+
42
+ expect(Doorkeeper::AccessToken.count).to eq(1)
43
+ expect(result).to eq(existing_token)
44
+ end
45
+ end
46
+
47
+ context "when existing token has crossed token_reuse_limit" do
48
+ it "returns a new token" do
49
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
50
+ allow(Doorkeeper.configuration).to receive(:token_reuse_limit).and_return(50)
51
+ existing_token = subject.call(client, scopes, expires_in: 1000)
52
+
53
+ allow_any_instance_of(Doorkeeper::AccessToken).to receive(:expires_in_seconds).and_return(400)
54
+ result = subject.call(client, scopes, expires_in: 1000)
55
+
56
+ expect(Doorkeeper::AccessToken.count).to eq(2)
57
+ expect(result).not_to eq(existing_token)
58
+ end
59
+ end
60
+
61
+ context "when existing token has been expired" do
62
+ it "returns a new token" do
63
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
64
+ allow(Doorkeeper.configuration).to receive(:token_reuse_limit).and_return(50)
65
+ existing_token = subject.call(client, scopes, expires_in: 1000)
66
+
67
+ allow_any_instance_of(Doorkeeper::AccessToken).to receive(:expired?).and_return(true)
68
+ result = subject.call(client, scopes, expires_in: 1000)
24
69
 
25
- expect(Doorkeeper::AccessToken.count).to eq(1)
26
- expect(result).to eq(existing_token)
70
+ expect(Doorkeeper::AccessToken.count).to eq(2)
71
+ expect(result).not_to eq(existing_token)
72
+ end
27
73
  end
28
74
  end
29
75
 
@@ -39,7 +85,7 @@ class Doorkeeper::OAuth::ClientCredentialsRequest
39
85
  end
40
86
  end
41
87
 
42
- it 'returns false if creation fails' do
88
+ it "returns false if creation fails" do
43
89
  expect(Doorkeeper::AccessToken).to receive(:find_or_create_for).and_return(false)
44
90
  created = subject.call(client, scopes)
45
91
  expect(created).to be_falsey
@@ -1,31 +1,36 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  class Doorkeeper::OAuth::ClientCredentialsRequest
4
6
  describe Issuer do
5
- let(:creator) { double :acces_token_creator }
7
+ let(:creator) { double :access_token_creator }
6
8
  let(:server) do
7
9
  double(
8
10
  :server,
9
- access_token_expires_in: 100,
10
- custom_access_token_expires_in: ->(_context) { nil }
11
+ access_token_expires_in: 100
11
12
  )
12
13
  end
13
14
  let(:validation) { double :validation, valid?: true }
14
15
 
16
+ before do
17
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(false)
18
+ end
19
+
15
20
  subject { Issuer.new(server, validation) }
16
21
 
17
22
  describe :create do
18
- let(:client) { double :client, id: 'some-id' }
19
- let(:scopes) { 'some scope' }
23
+ let(:client) { double :client, id: "some-id" }
24
+ let(:scopes) { "some scope" }
20
25
 
21
- it 'creates and sets the token' do
22
- expect(creator).to receive(:call).and_return('token')
26
+ it "creates and sets the token" do
27
+ expect(creator).to receive(:call).and_return("token")
23
28
  subject.create client, scopes, creator
24
29
 
25
- expect(subject.token).to eq('token')
30
+ expect(subject.token).to eq("token")
26
31
  end
27
32
 
28
- it 'creates with correct token parameters' do
33
+ it "creates with correct token parameters" do
29
34
  expect(creator).to receive(:call).with(
30
35
  client,
31
36
  scopes,
@@ -36,34 +41,34 @@ class Doorkeeper::OAuth::ClientCredentialsRequest
36
41
  subject.create client, scopes, creator
37
42
  end
38
43
 
39
- it 'has error set to :server_error if creator fails' do
44
+ it "has error set to :server_error if creator fails" do
40
45
  expect(creator).to receive(:call).and_return(false)
41
46
  subject.create client, scopes, creator
42
47
 
43
48
  expect(subject.error).to eq(:server_error)
44
49
  end
45
50
 
46
- context 'when validation fails' do
51
+ context "when validation fails" do
47
52
  before do
48
53
  allow(validation).to receive(:valid?).and_return(false)
49
54
  allow(validation).to receive(:error).and_return(:validation_error)
50
55
  expect(creator).not_to receive(:create)
51
56
  end
52
57
 
53
- it 'has error set from validation' do
58
+ it "has error set from validation" do
54
59
  subject.create client, scopes, creator
55
60
  expect(subject.error).to eq(:validation_error)
56
61
  end
57
62
 
58
- it 'returns false' do
63
+ it "returns false" do
59
64
  expect(subject.create(client, scopes, creator)).to be_falsey
60
65
  end
61
66
  end
62
67
 
63
- context 'with custom expirations' do
68
+ context "with custom expirations" do
64
69
  let(:custom_ttl_grant) { 1234 }
65
70
  let(:custom_ttl_scope) { 1235 }
66
- let(:custom_scope) { 'special' }
71
+ let(:custom_scope) { "special" }
67
72
  let(:server) do
68
73
  double(
69
74
  :server,
@@ -78,7 +83,11 @@ class Doorkeeper::OAuth::ClientCredentialsRequest
78
83
  )
79
84
  end
80
85
 
81
- it 'respects grant based rules' do
86
+ before do
87
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
88
+ end
89
+
90
+ it "respects grant based rules" do
82
91
  expect(creator).to receive(:call).with(
83
92
  client,
84
93
  scopes,
@@ -88,7 +97,7 @@ class Doorkeeper::OAuth::ClientCredentialsRequest
88
97
  subject.create client, scopes, creator
89
98
  end
90
99
 
91
- it 'respects scope based rules' do
100
+ it "respects scope based rules" do
92
101
  expect(creator).to receive(:call).with(
93
102
  client,
94
103
  custom_scope,
@@ -1,4 +1,6 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  class Doorkeeper::OAuth::ClientCredentialsRequest
4
6
  describe Validation do
@@ -9,42 +11,45 @@ class Doorkeeper::OAuth::ClientCredentialsRequest
9
11
 
10
12
  subject { Validation.new(server, request) }
11
13
 
12
- it 'is valid with valid request' do
14
+ it "is valid with valid request" do
13
15
  expect(subject).to be_valid
14
16
  end
15
17
 
16
- it 'is invalid when client is not present' do
18
+ it "is invalid when client is not present" do
17
19
  allow(request).to receive(:client).and_return(nil)
18
20
  expect(subject).not_to be_valid
19
21
  end
20
22
 
21
- context 'with scopes' do
22
- it 'is invalid when scopes are not included in the server' do
23
- server_scopes = Doorkeeper::OAuth::Scopes.from_string 'email'
23
+ context "with scopes" do
24
+ it "is invalid when scopes are not included in the server" do
25
+ server_scopes = Doorkeeper::OAuth::Scopes.from_string "email"
26
+ allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
24
27
  allow(server).to receive(:scopes).and_return(server_scopes)
25
28
  allow(request).to receive(:scopes).and_return(
26
- Doorkeeper::OAuth::Scopes.from_string('invalid')
29
+ Doorkeeper::OAuth::Scopes.from_string("invalid")
27
30
  )
28
31
  expect(subject).not_to be_valid
29
32
  end
30
33
 
31
- context 'with application scopes' do
32
- it 'is valid when scopes are included in the application' do
33
- application_scopes = Doorkeeper::OAuth::Scopes.from_string 'app'
34
- server_scopes = Doorkeeper::OAuth::Scopes.from_string 'email app'
34
+ context "with application scopes" do
35
+ it "is valid when scopes are included in the application" do
36
+ application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
37
+ server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
35
38
  allow(application).to receive(:scopes).and_return(application_scopes)
36
39
  allow(server).to receive(:scopes).and_return(server_scopes)
40
+ allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
37
41
  allow(request).to receive(:scopes).and_return(application_scopes)
38
42
  expect(subject).to be_valid
39
43
  end
40
44
 
41
- it 'is invalid when scopes are not included in the application' do
42
- application_scopes = Doorkeeper::OAuth::Scopes.from_string 'app'
43
- server_scopes = Doorkeeper::OAuth::Scopes.from_string 'email app'
45
+ it "is invalid when scopes are not included in the application" do
46
+ application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
47
+ server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
44
48
  allow(application).to receive(:scopes).and_return(application_scopes)
49
+ allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
45
50
  allow(server).to receive(:scopes).and_return(server_scopes)
46
51
  allow(request).to receive(:scopes).and_return(
47
- Doorkeeper::OAuth::Scopes.from_string('email')
52
+ Doorkeeper::OAuth::Scopes.from_string("email")
48
53
  )
49
54
  expect(subject).not_to be_valid
50
55
  end
@@ -1,13 +1,15 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth
4
6
  describe ClientCredentialsRequest do
5
7
  let(:server) { Doorkeeper.configuration }
6
8
 
7
- context 'with a valid request' do
9
+ context "with a valid request" do
8
10
  let(:client) { FactoryBot.create :application }
9
11
 
10
- it 'issues an access token' do
12
+ it "issues an access token" do
11
13
  request = ClientCredentialsRequest.new(server, client, {})
12
14
  expect do
13
15
  request.authorize
@@ -15,8 +17,8 @@ module Doorkeeper::OAuth
15
17
  end
16
18
  end
17
19
 
18
- describe 'with an invalid request' do
19
- it 'does not issue an access token' do
20
+ describe "with an invalid request" do
21
+ it "does not issue an access token" do
20
22
  request = ClientCredentialsRequest.new(server, nil, {})
21
23
  expect do
22
24
  request.authorize
@@ -1,4 +1,6 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth
4
6
  describe ClientCredentialsRequest do
@@ -10,71 +12,75 @@ module Doorkeeper::OAuth
10
12
  )
11
13
  end
12
14
 
13
- let(:application) { FactoryBot.create(:application, scopes: '') }
15
+ let(:application) { FactoryBot.create(:application, scopes: "") }
14
16
  let(:client) { double :client, application: application }
15
17
  let(:token_creator) { double :issuer, create: true, token: double }
16
18
 
19
+ before do
20
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
21
+ end
22
+
17
23
  subject { ClientCredentialsRequest.new(server, client) }
18
24
 
19
25
  before do
20
26
  subject.issuer = token_creator
21
27
  end
22
28
 
23
- it 'issues an access token for the current client' do
29
+ it "issues an access token for the current client" do
24
30
  expect(token_creator).to receive(:create).with(client, nil)
25
31
  subject.authorize
26
32
  end
27
33
 
28
- it 'has successful response when issue was created' do
34
+ it "has successful response when issue was created" do
29
35
  subject.authorize
30
36
  expect(subject.response).to be_a(TokenResponse)
31
37
  end
32
38
 
33
- context 'if issue was not created' do
39
+ context "if issue was not created" do
34
40
  before do
35
41
  subject.issuer = double create: false, error: :invalid
36
42
  end
37
43
 
38
- it 'has an error response' do
44
+ it "has an error response" do
39
45
  subject.authorize
40
46
  expect(subject.response).to be_a(Doorkeeper::OAuth::ErrorResponse)
41
47
  end
42
48
 
43
- it 'delegates the error to issuer' do
49
+ it "delegates the error to issuer" do
44
50
  subject.authorize
45
51
  expect(subject.error).to eq(:invalid)
46
52
  end
47
53
  end
48
54
 
49
- context 'with scopes' do
50
- let(:default_scopes) { Doorkeeper::OAuth::Scopes.from_string('public email') }
55
+ context "with scopes" do
56
+ let(:default_scopes) { Doorkeeper::OAuth::Scopes.from_string("public email") }
51
57
 
52
58
  before do
53
59
  allow(server).to receive(:default_scopes).and_return(default_scopes)
54
60
  end
55
61
 
56
- it 'issues an access token with default scopes if none was requested' do
62
+ it "issues an access token with default scopes if none was requested" do
57
63
  expect(token_creator).to receive(:create).with(client, default_scopes)
58
64
  subject.authorize
59
65
  end
60
66
 
61
- it 'issues an access token with requested scopes' do
62
- subject = ClientCredentialsRequest.new(server, client, scope: 'email')
67
+ it "issues an access token with requested scopes" do
68
+ subject = ClientCredentialsRequest.new(server, client, scope: "email")
63
69
  subject.issuer = token_creator
64
- expect(token_creator).to receive(:create).with(client, Doorkeeper::OAuth::Scopes.from_string('email'))
70
+ expect(token_creator).to receive(:create).with(client, Doorkeeper::OAuth::Scopes.from_string("email"))
65
71
  subject.authorize
66
72
  end
67
73
  end
68
74
 
69
- context 'with restricted client' do
75
+ context "with restricted client" do
70
76
  let(:default_scopes) do
71
- Doorkeeper::OAuth::Scopes.from_string('public email')
77
+ Doorkeeper::OAuth::Scopes.from_string("public email")
72
78
  end
73
79
  let(:server_scopes) do
74
- Doorkeeper::OAuth::Scopes.from_string('public email phone')
80
+ Doorkeeper::OAuth::Scopes.from_string("public email phone")
75
81
  end
76
82
  let(:client_scopes) do
77
- Doorkeeper::OAuth::Scopes.from_string('public phone')
83
+ Doorkeeper::OAuth::Scopes.from_string("public phone")
78
84
  end
79
85
 
80
86
  before do
@@ -85,18 +91,18 @@ module Doorkeeper::OAuth
85
91
  allow(client).to receive(:id).and_return(nil)
86
92
  end
87
93
 
88
- it 'delegates the error to issuer if no scope was requested' do
94
+ it "delegates the error to issuer if no scope was requested" do
89
95
  subject = ClientCredentialsRequest.new(server, client)
90
96
  subject.authorize
91
97
  expect(subject.response).to be_a(Doorkeeper::OAuth::ErrorResponse)
92
98
  expect(subject.error).to eq(:invalid_scope)
93
99
  end
94
100
 
95
- it 'issues an access token with requested scopes' do
96
- subject = ClientCredentialsRequest.new(server, client, scope: 'phone')
101
+ it "issues an access token with requested scopes" do
102
+ subject = ClientCredentialsRequest.new(server, client, scope: "phone")
97
103
  subject.authorize
98
104
  expect(subject.response).to be_a(Doorkeeper::OAuth::TokenResponse)
99
- expect(subject.response.token.scopes_string).to eq('phone')
105
+ expect(subject.response.token.scopes_string).to eq("phone")
100
106
  end
101
107
  end
102
108
  end
@@ -1,34 +1,36 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth
4
6
  describe Client do
5
7
  describe :find do
6
8
  let(:method) { double }
7
9
 
8
- it 'finds the client via uid' do
10
+ it "finds the client via uid" do
9
11
  client = double
10
- expect(method).to receive(:call).with('uid').and_return(client)
11
- expect(Client.find('uid', method)).to be_a(Client)
12
+ expect(method).to receive(:call).with("uid").and_return(client)
13
+ expect(Client.find("uid", method)).to be_a(Client)
12
14
  end
13
15
 
14
- it 'returns nil if client was not found' do
15
- expect(method).to receive(:call).with('uid').and_return(nil)
16
- expect(Client.find('uid', method)).to be_nil
16
+ it "returns nil if client was not found" do
17
+ expect(method).to receive(:call).with("uid").and_return(nil)
18
+ expect(Client.find("uid", method)).to be_nil
17
19
  end
18
20
  end
19
21
 
20
22
  describe :authenticate do
21
- it 'returns the authenticated client via credentials' do
22
- credentials = Client::Credentials.new('some-uid', 'some-secret')
23
+ it "returns the authenticated client via credentials" do
24
+ credentials = Client::Credentials.new("some-uid", "some-secret")
23
25
  authenticator = double
24
- expect(authenticator).to receive(:call).with('some-uid', 'some-secret').and_return(double)
26
+ expect(authenticator).to receive(:call).with("some-uid", "some-secret").and_return(double)
25
27
  expect(Client.authenticate(credentials, authenticator)).to be_a(Client)
26
28
  end
27
29
 
28
- it 'returns nil if client was not authenticated' do
29
- credentials = Client::Credentials.new('some-uid', 'some-secret')
30
+ it "returns nil if client was not authenticated" do
31
+ credentials = Client::Credentials.new("some-uid", "some-secret")
30
32
  authenticator = double
31
- expect(authenticator).to receive(:call).with('some-uid', 'some-secret').and_return(nil)
33
+ expect(authenticator).to receive(:call).with("some-uid", "some-secret").and_return(nil)
32
34
  expect(Client.authenticate(credentials, authenticator)).to be_nil
33
35
  end
34
36
  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::OAuth
4
6
  describe CodeRequest do
@@ -6,7 +8,7 @@ module Doorkeeper::OAuth
6
8
  double(
7
9
  :pre_auth,
8
10
  client: double(:application, id: 9990),
9
- redirect_uri: 'http://tst.com/cb',
11
+ redirect_uri: "http://tst.com/cb",
10
12
  scopes: nil,
11
13
  state: nil,
12
14
  error: nil,
@@ -22,22 +24,22 @@ module Doorkeeper::OAuth
22
24
  CodeRequest.new(pre_auth, owner)
23
25
  end
24
26
 
25
- it 'creates an access grant' do
27
+ it "creates an access grant" do
26
28
  expect do
27
29
  subject.authorize
28
30
  end.to change { Doorkeeper::AccessGrant.count }.by(1)
29
31
  end
30
32
 
31
- it 'returns a code response' do
33
+ it "returns a code response" do
32
34
  expect(subject.authorize).to be_a(CodeResponse)
33
35
  end
34
36
 
35
- it 'does not create grant when not authorizable' do
37
+ it "does not create grant when not authorizable" do
36
38
  allow(pre_auth).to receive(:authorizable?).and_return(false)
37
39
  expect { subject.authorize }.not_to(change { Doorkeeper::AccessGrant.count })
38
40
  end
39
41
 
40
- it 'returns a error response' do
42
+ it "returns a error response" do
41
43
  allow(pre_auth).to receive(:authorizable?).and_return(false)
42
44
  expect(subject.authorize).to be_a(ErrorResponse)
43
45
  end
@@ -1,17 +1,19 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper
4
6
  module OAuth
5
7
  describe CodeResponse do
6
- describe '.redirect_uri' do
7
- context 'when generating the redirect URI for an implicit grant' do
8
+ describe ".redirect_uri" do
9
+ context "when generating the redirect URI for an implicit grant" do
8
10
  let :pre_auth do
9
11
  double(
10
12
  :pre_auth,
11
13
  client: double(:application, id: 1),
12
- redirect_uri: 'http://tst.com/cb',
14
+ redirect_uri: "http://tst.com/cb",
13
15
  state: nil,
14
- scopes: Scopes.from_string('public')
16
+ scopes: Scopes.from_string("public")
15
17
  )
16
18
  end
17
19
 
@@ -24,8 +26,8 @@ module Doorkeeper
24
26
 
25
27
  subject { CodeResponse.new(pre_auth, auth, response_on_fragment: true).redirect_uri }
26
28
 
27
- it 'includes the remaining TTL of the token relative to the time the token was generated' do
28
- expect(subject).to include('expires_in=3600')
29
+ it "includes the remaining TTL of the token relative to the time the token was generated" do
30
+ expect(subject).to include("expires_in=3600")
29
31
  end
30
32
  end
31
33
  end