doorkeeper 4.4.3 → 5.0.0

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

Potentially problematic release.


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

Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitlab-ci.yml +16 -0
  4. data/.travis.yml +2 -0
  5. data/Appraisals +2 -2
  6. data/Gemfile +1 -1
  7. data/NEWS.md +61 -8
  8. data/README.md +92 -9
  9. data/Rakefile +6 -0
  10. data/UPGRADE.md +2 -0
  11. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  12. data/app/controllers/doorkeeper/application_controller.rb +4 -3
  13. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -0
  14. data/app/controllers/doorkeeper/applications_controller.rb +42 -22
  15. data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
  16. data/app/controllers/doorkeeper/authorized_applications_controller.rb +19 -2
  17. data/app/controllers/doorkeeper/tokens_controller.rb +2 -6
  18. data/app/helpers/doorkeeper/dashboard_helper.rb +7 -7
  19. data/app/validators/redirect_uri_validator.rb +3 -2
  20. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  21. data/app/views/doorkeeper/applications/_form.html.erb +25 -24
  22. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  23. data/app/views/doorkeeper/applications/index.html.erb +17 -7
  24. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  25. data/app/views/doorkeeper/applications/show.html.erb +6 -6
  26. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  27. data/app/views/doorkeeper/authorizations/new.html.erb +4 -0
  28. data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
  29. data/config/locales/en.yml +10 -1
  30. data/doorkeeper.gemspec +18 -20
  31. data/gemfiles/rails_5_2.gemfile +1 -1
  32. data/gemfiles/rails_master.gemfile +4 -1
  33. data/lib/doorkeeper/config.rb +75 -39
  34. data/lib/doorkeeper/engine.rb +4 -0
  35. data/lib/doorkeeper/errors.rb +2 -5
  36. data/lib/doorkeeper/grape/helpers.rb +1 -1
  37. data/lib/doorkeeper/helpers/controller.rb +7 -2
  38. data/lib/doorkeeper/models/access_grant_mixin.rb +71 -0
  39. data/lib/doorkeeper/models/access_token_mixin.rb +39 -22
  40. data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
  41. data/lib/doorkeeper/oauth/authorization/code.rb +31 -8
  42. data/lib/doorkeeper/oauth/authorization/context.rb +15 -0
  43. data/lib/doorkeeper/oauth/authorization/token.rb +36 -14
  44. data/lib/doorkeeper/oauth/authorization_code_request.rb +27 -2
  45. data/lib/doorkeeper/oauth/base_request.rb +20 -9
  46. data/lib/doorkeeper/oauth/client/credentials.rb +1 -1
  47. data/lib/doorkeeper/oauth/client.rb +0 -2
  48. data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -1
  49. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +6 -3
  50. data/lib/doorkeeper/oauth/client_credentials/validation.rb +4 -6
  51. data/lib/doorkeeper/oauth/client_credentials_request.rb +0 -4
  52. data/lib/doorkeeper/oauth/error_response.rb +11 -3
  53. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +0 -8
  54. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -4
  55. data/lib/doorkeeper/oauth/pre_authorization.rb +41 -11
  56. data/lib/doorkeeper/oauth/refresh_token_request.rb +6 -1
  57. data/lib/doorkeeper/oauth/scopes.rb +1 -1
  58. data/lib/doorkeeper/oauth/token.rb +5 -2
  59. data/lib/doorkeeper/oauth/token_introspection.rb +2 -2
  60. data/lib/doorkeeper/oauth/token_response.rb +4 -2
  61. data/lib/doorkeeper/oauth.rb +13 -0
  62. data/lib/doorkeeper/orm/active_record/application.rb +22 -14
  63. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
  64. data/lib/doorkeeper/orm/active_record.rb +2 -0
  65. data/lib/doorkeeper/rails/helpers.rb +2 -4
  66. data/lib/doorkeeper/rails/routes.rb +14 -6
  67. data/lib/doorkeeper/rake/db.rake +40 -0
  68. data/lib/doorkeeper/rake/setup.rake +6 -0
  69. data/lib/doorkeeper/rake.rb +14 -0
  70. data/lib/doorkeeper/request/authorization_code.rb +0 -2
  71. data/lib/doorkeeper/request/client_credentials.rb +0 -2
  72. data/lib/doorkeeper/request/code.rb +0 -2
  73. data/lib/doorkeeper/request/password.rb +0 -2
  74. data/lib/doorkeeper/request/refresh_token.rb +0 -2
  75. data/lib/doorkeeper/request/token.rb +0 -2
  76. data/lib/doorkeeper/request.rb +28 -35
  77. data/lib/doorkeeper/version.rb +5 -25
  78. data/lib/doorkeeper.rb +19 -17
  79. data/lib/generators/doorkeeper/application_owner_generator.rb +23 -18
  80. data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
  81. data/lib/generators/doorkeeper/install_generator.rb +17 -9
  82. data/lib/generators/doorkeeper/migration_generator.rb +23 -18
  83. data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
  84. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -24
  85. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  86. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
  87. data/lib/generators/doorkeeper/templates/initializer.rb +76 -11
  88. data/lib/generators/doorkeeper/views_generator.rb +3 -1
  89. data/spec/controllers/application_metal_controller_spec.rb +50 -0
  90. data/spec/controllers/applications_controller_spec.rb +126 -13
  91. data/spec/controllers/authorizations_controller_spec.rb +277 -47
  92. data/spec/controllers/protected_resources_controller_spec.rb +16 -16
  93. data/spec/controllers/token_info_controller_spec.rb +4 -12
  94. data/spec/controllers/tokens_controller_spec.rb +13 -15
  95. data/spec/dummy/app/assets/config/manifest.js +2 -0
  96. data/spec/dummy/config/environments/test.rb +4 -5
  97. data/spec/dummy/config/initializers/doorkeeper.rb +10 -5
  98. data/spec/dummy/config/initializers/new_framework_defaults.rb +4 -0
  99. data/spec/dummy/config/routes.rb +3 -42
  100. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
  101. data/spec/dummy/db/migrate/{20180210183654_add_confidential_to_application.rb → 20180210183654_add_confidential_to_applications.rb} +1 -1
  102. data/spec/dummy/db/schema.rb +36 -36
  103. data/spec/generators/application_owner_generator_spec.rb +1 -1
  104. data/spec/generators/confidential_applications_generator_spec.rb +45 -0
  105. data/spec/generators/install_generator_spec.rb +1 -1
  106. data/spec/generators/migration_generator_spec.rb +1 -1
  107. data/spec/generators/pkce_generator_spec.rb +43 -0
  108. data/spec/generators/previous_refresh_token_generator_spec.rb +1 -1
  109. data/spec/generators/views_generator_spec.rb +1 -1
  110. data/spec/grape/grape_integration_spec.rb +1 -1
  111. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  112. data/spec/lib/config_spec.rb +80 -31
  113. data/spec/lib/doorkeeper_spec.rb +1 -126
  114. data/spec/lib/models/expirable_spec.rb +0 -3
  115. data/spec/lib/models/revocable_spec.rb +0 -2
  116. data/spec/lib/models/scopes_spec.rb +0 -4
  117. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
  118. data/spec/lib/oauth/authorization_code_request_spec.rb +9 -2
  119. data/spec/lib/oauth/base_request_spec.rb +40 -2
  120. data/spec/lib/oauth/base_response_spec.rb +1 -1
  121. data/spec/lib/oauth/client/credentials_spec.rb +1 -3
  122. data/spec/lib/oauth/client_credentials/creator_spec.rb +5 -1
  123. data/spec/lib/oauth/client_credentials/issuer_spec.rb +26 -7
  124. data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -3
  125. data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
  126. data/spec/lib/oauth/client_credentials_request_spec.rb +3 -5
  127. data/spec/lib/oauth/client_spec.rb +0 -3
  128. data/spec/lib/oauth/code_request_spec.rb +4 -2
  129. data/spec/lib/oauth/error_response_spec.rb +0 -3
  130. data/spec/lib/oauth/error_spec.rb +0 -2
  131. data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
  132. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -3
  133. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
  134. data/spec/lib/oauth/helpers/uri_checker_spec.rb +5 -7
  135. data/spec/lib/oauth/invalid_token_response_spec.rb +1 -4
  136. data/spec/lib/oauth/password_access_token_request_spec.rb +37 -2
  137. data/spec/lib/oauth/pre_authorization_spec.rb +33 -4
  138. data/spec/lib/oauth/refresh_token_request_spec.rb +11 -7
  139. data/spec/lib/oauth/scopes_spec.rb +0 -3
  140. data/spec/lib/oauth/token_request_spec.rb +4 -5
  141. data/spec/lib/oauth/token_response_spec.rb +0 -1
  142. data/spec/lib/oauth/token_spec.rb +37 -14
  143. data/spec/lib/orm/active_record/stale_records_cleaner_spec.rb +79 -0
  144. data/spec/lib/request/strategy_spec.rb +0 -1
  145. data/spec/lib/server_spec.rb +1 -1
  146. data/spec/models/doorkeeper/access_grant_spec.rb +44 -1
  147. data/spec/models/doorkeeper/access_token_spec.rb +66 -22
  148. data/spec/models/doorkeeper/application_spec.rb +14 -47
  149. data/spec/requests/applications/applications_request_spec.rb +134 -1
  150. data/spec/requests/applications/authorized_applications_spec.rb +1 -1
  151. data/spec/requests/endpoints/authorization_spec.rb +1 -1
  152. data/spec/requests/endpoints/token_spec.rb +7 -5
  153. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -1
  154. data/spec/requests/flows/authorization_code_spec.rb +197 -1
  155. data/spec/requests/flows/client_credentials_spec.rb +46 -6
  156. data/spec/requests/flows/implicit_grant_errors_spec.rb +1 -1
  157. data/spec/requests/flows/implicit_grant_spec.rb +38 -11
  158. data/spec/requests/flows/password_spec.rb +56 -2
  159. data/spec/requests/flows/refresh_token_spec.rb +2 -2
  160. data/spec/requests/flows/revoke_token_spec.rb +11 -11
  161. data/spec/requests/flows/skip_authorization_spec.rb +16 -11
  162. data/spec/requests/protected_resources/metal_spec.rb +1 -1
  163. data/spec/requests/protected_resources/private_api_spec.rb +1 -1
  164. data/spec/routing/custom_controller_routes_spec.rb +59 -7
  165. data/spec/routing/default_routes_spec.rb +2 -2
  166. data/spec/routing/scoped_routes_spec.rb +16 -2
  167. data/spec/spec_helper.rb +54 -3
  168. data/spec/spec_helper_integration.rb +2 -74
  169. data/spec/support/dependencies/{factory_girl.rb → factory_bot.rb} +0 -0
  170. data/spec/support/doorkeeper_rspec.rb +19 -0
  171. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  172. data/spec/support/helpers/request_spec_helper.rb +10 -2
  173. data/spec/support/helpers/url_helper.rb +7 -3
  174. data/spec/support/http_method_shim.rb +12 -16
  175. data/spec/validators/redirect_uri_validator_spec.rb +7 -1
  176. data/spec/version/version_spec.rb +3 -3
  177. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  178. metadata +37 -33
  179. data/lib/generators/doorkeeper/add_client_confidentiality_generator.rb +0 -31
  180. data/lib/generators/doorkeeper/templates/add_confidential_to_application_migration.rb.erb +0 -11
  181. data/spec/controllers/application_metal_controller.rb +0 -10
@@ -1,12 +1,9 @@
1
1
  require 'spec_helper'
2
- require 'active_model'
3
- require 'doorkeeper'
4
- require 'doorkeeper/oauth/forbidden_token_response'
5
2
 
6
3
  module Doorkeeper::OAuth
7
4
  describe ForbiddenTokenResponse do
8
5
  describe '#name' do
9
- it { expect(subject.name).to eq(:invalid_scope) }
6
+ it { expect(subject.name).to eq(:invalid_scope) }
10
7
  end
11
8
 
12
9
  describe '#status' do
@@ -1,7 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/core_ext/string'
3
- require 'doorkeeper/oauth/helpers/scope_checker'
4
- require 'doorkeeper/oauth/scopes'
5
2
 
6
3
  module Doorkeeper::OAuth::Helpers
7
4
  describe ScopeChecker, '.valid?' do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'doorkeeper/oauth/helpers/unique_token'
3
2
 
4
3
  module Doorkeeper::OAuth::Helpers
5
4
  describe UniqueToken do
@@ -1,15 +1,8 @@
1
1
  require 'spec_helper'
2
- require 'uri'
3
- require 'doorkeeper/oauth/helpers/uri_checker'
4
2
 
5
3
  module Doorkeeper::OAuth::Helpers
6
4
  describe URIChecker do
7
5
  describe '.valid?' do
8
- it 'is valid for native uris' do
9
- uri = 'urn:ietf:wg:oauth:2.0:oob'
10
- expect(URIChecker.valid?(uri)).to be_truthy
11
- end
12
-
13
6
  it 'is valid for valid uris' do
14
7
  uri = 'http://app.co'
15
8
  expect(URIChecker.valid?(uri)).to be_truthy
@@ -49,6 +42,11 @@ module Doorkeeper::OAuth::Helpers
49
42
  uri = ' '
50
43
  expect(URIChecker.valid?(uri)).to be_falsey
51
44
  end
45
+
46
+ it 'is valid for native uris' do
47
+ uri = 'urn:ietf:wg:oauth:2.0:oob'
48
+ expect(URIChecker.valid?(uri)).to be_truthy
49
+ end
52
50
  end
53
51
 
54
52
  describe '.matches?' do
@@ -1,12 +1,9 @@
1
1
  require 'spec_helper'
2
- require 'active_model'
3
- require 'doorkeeper'
4
- require 'doorkeeper/oauth/invalid_token_response'
5
2
 
6
3
  module Doorkeeper::OAuth
7
4
  describe InvalidTokenResponse do
8
5
  describe "#name" do
9
- it { expect(subject.name).to eq(:invalid_token) }
6
+ it { expect(subject.name).to eq(:invalid_token) }
10
7
  end
11
8
 
12
9
  describe "#status" do
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe PasswordAccessTokenRequest do
@@ -8,7 +8,9 @@ module Doorkeeper::OAuth
8
8
  default_scopes: Doorkeeper::OAuth::Scopes.new,
9
9
  access_token_expires_in: 2.hours,
10
10
  refresh_token_enabled?: false,
11
- custom_access_token_expires_in: ->(_app) { nil }
11
+ custom_access_token_expires_in: lambda { |context|
12
+ context.grant_type == Doorkeeper::OAuth::PASSWORD ? 1234 : nil
13
+ }
12
14
  )
13
15
  end
14
16
  let(:client) { FactoryBot.create(:application) }
@@ -22,6 +24,7 @@ module Doorkeeper::OAuth
22
24
  expect do
23
25
  subject.authorize
24
26
  end.to change { client.reload.access_tokens.count }.by(1)
27
+ expect(client.reload.access_tokens.sort_by(&:created_at).last.expires_in).to eq(1234)
25
28
  end
26
29
 
27
30
  it 'issues a new token without a client' do
@@ -92,5 +95,37 @@ module Doorkeeper::OAuth
92
95
  expect(Doorkeeper::AccessToken.last.scopes).to include('public')
93
96
  end
94
97
  end
98
+
99
+ describe 'with custom expiry' do
100
+ let(:server) do
101
+ double(
102
+ :server,
103
+ default_scopes: Doorkeeper::OAuth::Scopes.new,
104
+ access_token_expires_in: 2.hours,
105
+ refresh_token_enabled?: false,
106
+ custom_access_token_expires_in: lambda { |context|
107
+ context.scopes.exists?('public') ? 222 : nil
108
+ }
109
+ )
110
+ end
111
+
112
+ it 'checks scopes' do
113
+ subject = PasswordAccessTokenRequest.new(server, client, owner, scope: 'public')
114
+ allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('public'))
115
+ expect do
116
+ subject.authorize
117
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
118
+ expect(Doorkeeper::AccessToken.last.expires_in).to eq(222)
119
+ end
120
+
121
+ it 'falls back to the default otherwise' do
122
+ subject = PasswordAccessTokenRequest.new(server, client, owner, scope: 'private')
123
+ allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('private'))
124
+ expect do
125
+ subject.authorize
126
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
127
+ expect(Doorkeeper::AccessToken.last.expires_in).to eq(2.hours)
128
+ end
129
+ end
95
130
  end
96
131
  end
@@ -1,13 +1,13 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe PreAuthorization do
5
- let(:server) {
5
+ let(:server) do
6
6
  server = Doorkeeper.configuration
7
7
  allow(server).to receive(:default_scopes).and_return(Scopes.new)
8
8
  allow(server).to receive(:scopes).and_return(Scopes.from_string('public profile'))
9
9
  server
10
- }
10
+ end
11
11
 
12
12
  let(:application) do
13
13
  application = double :application
@@ -133,11 +133,16 @@ module Doorkeeper::OAuth
133
133
  end
134
134
 
135
135
  it 'invalidates redirect_uri when it does\'n match with the client' do
136
- subject.redirect_uri = native_redirect_uri
136
+ subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
137
137
  expect(subject).not_to be_authorizable
138
138
  end
139
139
  end
140
140
 
141
+ it 'matches the redirect uri against client\'s one' do
142
+ subject.redirect_uri = 'http://nothesame.com'
143
+ expect(subject).not_to be_authorizable
144
+ end
145
+
141
146
  it 'stores the state' do
142
147
  expect(subject.state).to eq('save-this')
143
148
  end
@@ -156,5 +161,29 @@ module Doorkeeper::OAuth
156
161
  subject.redirect_uri = nil
157
162
  expect(subject).not_to be_authorizable
158
163
  end
164
+
165
+ describe "as_json" do
166
+ let(:client_id) { "client_uid_123" }
167
+ let(:client_name) { "Acme Co." }
168
+
169
+ before do
170
+ allow(client).to receive(:uid).and_return client_id
171
+ allow(client).to receive(:name).and_return client_name
172
+ end
173
+
174
+ let(:json) { subject.as_json({}) }
175
+
176
+ it { is_expected.to respond_to :as_json }
177
+
178
+ it "returns correct values" do
179
+ expect(json[:client_id]).to eq client_id
180
+ expect(json[:redirect_uri]).to eq subject.redirect_uri
181
+ expect(json[:state]).to eq subject.state
182
+ expect(json[:response_type]).to eq subject.response_type
183
+ expect(json[:scope]).to eq subject.scope
184
+ expect(json[:client_name]).to eq client_name
185
+ expect(json[:status]).to eq I18n.t('doorkeeper.pre_authorization.status')
186
+ end
187
+ end
159
188
  end
160
189
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe RefreshTokenRequest do
@@ -9,7 +9,7 @@ module Doorkeeper::OAuth
9
9
  let(:server) do
10
10
  double :server,
11
11
  access_token_expires_in: 2.minutes,
12
- custom_access_token_expires_in: -> (_oauth_client) { nil }
12
+ custom_access_token_expires_in: ->(_context) { nil }
13
13
  end
14
14
 
15
15
  let(:refresh_token) do
@@ -30,7 +30,9 @@ module Doorkeeper::OAuth
30
30
  it 'issues a new token for the client with custom expires_in' do
31
31
  server = double :server,
32
32
  access_token_expires_in: 2.minutes,
33
- custom_access_token_expires_in: ->(_oauth_client) { 1234 }
33
+ custom_access_token_expires_in: lambda { |context|
34
+ context.grant_type == Doorkeeper::OAuth::REFRESH_TOKEN ? 1234 : nil
35
+ }
34
36
 
35
37
  allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(false)
36
38
 
@@ -85,7 +87,9 @@ module Doorkeeper::OAuth
85
87
  let(:server) do
86
88
  double :server,
87
89
  access_token_expires_in: 2.minutes,
88
- custom_access_token_expires_in: ->(_oauth_client) { 1234 }
90
+ custom_access_token_expires_in: lambda { |context|
91
+ context.grant_type == Doorkeeper::OAuth::REFRESH_TOKEN ? 1234 : nil
92
+ }
89
93
  end
90
94
 
91
95
  before do
@@ -131,13 +135,13 @@ module Doorkeeper::OAuth
131
135
 
132
136
  it 'transfers scopes from the old token to the new token' do
133
137
  subject.authorize
134
- expect(Doorkeeper::AccessToken.last.scopes).to eq([:public, :write])
138
+ expect(Doorkeeper::AccessToken.last.scopes).to eq(%i[public write])
135
139
  end
136
140
 
137
141
  it 'reduces scopes to the provided scopes' do
138
142
  parameters[:scopes] = 'public'
139
143
  subject.authorize
140
- expect(Doorkeeper::AccessToken.last.scopes).to eq([:public])
144
+ expect(Doorkeeper::AccessToken.last.scopes).to eq(%i[public])
141
145
  end
142
146
 
143
147
  it 'validates that scopes are included in the original access token' do
@@ -151,7 +155,7 @@ module Doorkeeper::OAuth
151
155
  parameters[:scopes] = 'public update'
152
156
  parameters[:scope] = 'public'
153
157
  subject.authorize
154
- expect(Doorkeeper::AccessToken.last.scopes).to eq([:public])
158
+ expect(Doorkeeper::AccessToken.last.scopes).to eq(%i[public])
155
159
  end
156
160
 
157
161
  it 'uses params[:scope] in favor of scopes if present (invalid)' do
@@ -1,7 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/core_ext/module/delegation'
3
- require 'active_support/core_ext/string'
4
- require 'doorkeeper/oauth/scopes'
5
2
 
6
3
  module Doorkeeper::OAuth
7
4
  describe Scopes do
@@ -1,10 +1,9 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe TokenRequest do
5
5
  let :application do
6
- scopes = double(all: ['public'])
7
- double(:application, id: 9990, scopes: scopes)
6
+ FactoryBot.create(:application, scopes: "public")
8
7
  end
9
8
 
10
9
  let :pre_auth do
@@ -51,8 +50,8 @@ module Doorkeeper::OAuth
51
50
  before do
52
51
  Doorkeeper.configure do
53
52
  orm DOORKEEPER_ORM
54
- custom_access_token_expires_in do |_oauth_client|
55
- 1234
53
+ custom_access_token_expires_in do |context|
54
+ context.grant_type == Doorkeeper::OAuth::IMPLICIT ? 1234 : nil
56
55
  end
57
56
  end
58
57
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'doorkeeper/oauth/token_response'
3
2
 
4
3
  module Doorkeeper::OAuth
5
4
  describe TokenResponse do
@@ -1,6 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/core_ext/string'
3
- require 'doorkeeper/oauth/token'
4
2
 
5
3
  module Doorkeeper
6
4
  unless defined?(AccessToken)
@@ -14,7 +12,7 @@ module Doorkeeper
14
12
  let(:request) { double.as_null_object }
15
13
 
16
14
  let(:method) do
17
- ->(request) { return 'token-value' }
15
+ ->(*) { 'token-value' }
18
16
  end
19
17
 
20
18
  it 'accepts anything that responds to #call' do
@@ -96,19 +94,44 @@ module Doorkeeper
96
94
  end
97
95
 
98
96
  describe :authenticate do
99
- it 'calls the finder if token was returned' do
100
- token = ->(_r) { 'token' }
101
- expect(AccessToken).to receive(:by_token).with('token')
102
- Token.authenticate double, token
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' }
101
+ expect(
102
+ AccessToken
103
+ ).to receive(:by_token).with('token').and_return(token)
104
+ expect(token).not_to receive(:revoke_previous_refresh_token!)
105
+ Token.authenticate double, token
106
+ end
107
+ end
108
+
109
+ it 'calls the finder if token was returned' do
110
+ token = ->(_r) { 'token' }
111
+ expect(AccessToken).to receive(:by_token).with('token')
112
+ Token.authenticate double, token
113
+ end
103
114
  end
104
115
 
105
- it 'revokes previous refresh_token if token was found' do
106
- token = ->(_r) { 'token' }
107
- expect(
108
- AccessToken
109
- ).to receive(:by_token).with('token').and_return(token)
110
- expect(token).to receive(:revoke_previous_refresh_token!)
111
- Token.authenticate double, token
116
+ context 'refresh tokens are enabled' do
117
+ before do
118
+ Doorkeeper.configure { use_refresh_token }
119
+ end
120
+
121
+ it 'revokes previous refresh_token if token was found' do
122
+ token = ->(_r) { 'token' }
123
+ expect(
124
+ AccessToken
125
+ ).to receive(:by_token).with('token').and_return(token)
126
+ expect(token).to receive(:revoke_previous_refresh_token!)
127
+ Token.authenticate double, token
128
+ end
129
+
130
+ it 'calls the finder if token was returned' do
131
+ token = ->(_r) { 'token' }
132
+ expect(AccessToken).to receive(:by_token).with('token')
133
+ Token.authenticate double, token
134
+ end
112
135
  end
113
136
  end
114
137
  end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Doorkeeper::Orm::ActiveRecord::StaleRecordsCleaner do
6
+ let(:cleaner) { described_class.new(model) }
7
+ let(:models_by_name) do
8
+ {
9
+ access_token: Doorkeeper::AccessToken,
10
+ access_grant: Doorkeeper::AccessGrant
11
+ }
12
+ end
13
+
14
+ %i[access_token access_grant].each do |model_name|
15
+ context "(#{model_name})" do
16
+ let(:model) { models_by_name.fetch(model_name) }
17
+
18
+ describe '#clean_revoked' do
19
+ subject { cleaner.clean_revoked }
20
+
21
+ context 'with revoked record' do
22
+ before do
23
+ FactoryBot.create model_name, revoked_at: Time.current - 1.minute
24
+ end
25
+
26
+ it 'removes the record' do
27
+ expect { subject }.to change { model.count }.to(0)
28
+ end
29
+ end
30
+
31
+ context 'with record revoked in the future' do
32
+ before do
33
+ FactoryBot.create model_name, revoked_at: Time.current + 1.minute
34
+ end
35
+
36
+ it 'keeps the record' do
37
+ expect { subject }.not_to change { model.count }
38
+ end
39
+ end
40
+
41
+ context 'with unrevoked record' do
42
+ before do
43
+ FactoryBot.create model_name, revoked_at: nil
44
+ end
45
+
46
+ it 'keeps the record' do
47
+ expect { subject }.not_to change { model.count }
48
+ end
49
+ end
50
+ end
51
+
52
+ describe '#clean_expired' do
53
+ subject { cleaner.clean_expired(ttl) }
54
+ let(:ttl) { 500 }
55
+ let(:expiry_border) { ttl.seconds.ago }
56
+
57
+ context 'with record that is expired' do
58
+ before do
59
+ FactoryBot.create model_name, created_at: expiry_border - 1.minute
60
+ end
61
+
62
+ it 'removes the record' do
63
+ expect { subject }.to change { model.count }.to(0)
64
+ end
65
+ end
66
+
67
+ context 'with record that is not expired' do
68
+ before do
69
+ FactoryBot.create model_name, created_at: expiry_border + 1.minute
70
+ end
71
+
72
+ it 'keeps the record' do
73
+ expect { subject }.not_to change { model.count }
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'doorkeeper/request/strategy'
3
2
 
4
3
  module Doorkeeper
5
4
  module Request
@@ -46,7 +46,7 @@ describe Doorkeeper::Server do
46
46
  subject.authorization_request :code
47
47
  end
48
48
 
49
- it 'builds the request with composit strategy name' do
49
+ it 'builds the request with composite strategy name' do
50
50
  allow(Doorkeeper.configuration).
51
51
  to receive(:authorization_response_types).
52
52
  and_return(['id_token token'])
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Doorkeeper::AccessGrant do
4
4
  subject { FactoryBot.build(:access_grant) }
@@ -33,4 +33,47 @@ describe Doorkeeper::AccessGrant do
33
33
  expect(subject).not_to be_valid
34
34
  end
35
35
  end
36
+
37
+ describe '.revoke_all_for' do
38
+ let(:resource_owner) { double(id: 100) }
39
+ let(:application) { FactoryBot.create :application }
40
+ let(:default_attributes) do
41
+ {
42
+ application: application,
43
+ resource_owner_id: resource_owner.id
44
+ }
45
+ end
46
+
47
+ it 'revokes all tokens for given application and resource owner' do
48
+ FactoryBot.create :access_grant, default_attributes
49
+
50
+ described_class.revoke_all_for(application.id, resource_owner)
51
+
52
+ described_class.all.each do |token|
53
+ expect(token).to be_revoked
54
+ end
55
+ end
56
+
57
+ it 'matches application' do
58
+ access_grant_for_different_app = FactoryBot.create(
59
+ :access_grant,
60
+ default_attributes.merge(application: FactoryBot.create(:application))
61
+ )
62
+
63
+ described_class.revoke_all_for(application.id, resource_owner)
64
+
65
+ expect(access_grant_for_different_app.reload).not_to be_revoked
66
+ end
67
+
68
+ it 'matches resource owner' do
69
+ access_grant_for_different_owner = FactoryBot.create(
70
+ :access_grant,
71
+ default_attributes.merge(resource_owner_id: 90)
72
+ )
73
+
74
+ described_class.revoke_all_for application.id, resource_owner
75
+
76
+ expect(access_grant_for_different_owner.reload).not_to be_revoked
77
+ end
78
+ end
36
79
  end