doorkeeper 2.1.4 → 3.1.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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/.hound.yml +4 -0
  3. data/.travis.yml +5 -24
  4. data/CONTRIBUTING.md +23 -13
  5. data/Gemfile +3 -7
  6. data/{CHANGELOG.md → NEWS.md} +137 -42
  7. data/README.md +60 -46
  8. data/RELEASING.md +5 -3
  9. data/app/assets/stylesheets/doorkeeper/admin/application.css +1 -5
  10. data/app/controllers/doorkeeper/applications_controller.rb +2 -2
  11. data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
  12. data/app/validators/redirect_uri_validator.rb +1 -1
  13. data/app/views/doorkeeper/applications/_form.html.erb +13 -2
  14. data/app/views/doorkeeper/applications/show.html.erb +3 -2
  15. data/app/views/doorkeeper/authorizations/new.html.erb +1 -1
  16. data/app/views/layouts/doorkeeper/admin.html.erb +5 -2
  17. data/config/locales/en.yml +4 -32
  18. data/doorkeeper.gemspec +4 -8
  19. data/lib/doorkeeper/config.rb +20 -29
  20. data/lib/doorkeeper/engine.rb +7 -1
  21. data/lib/doorkeeper/errors.rb +12 -0
  22. data/lib/doorkeeper/grape/helpers.rb +1 -1
  23. data/lib/doorkeeper/helpers/controller.rb +6 -0
  24. data/lib/doorkeeper/models/access_grant_mixin.rb +3 -2
  25. data/lib/doorkeeper/models/access_token_mixin.rb +12 -4
  26. data/lib/doorkeeper/models/application_mixin.rb +11 -18
  27. data/lib/doorkeeper/models/concerns/revocable.rb +2 -2
  28. data/lib/doorkeeper/oauth/authorization/token.rb +15 -6
  29. data/lib/doorkeeper/oauth/authorization_code_request.rb +10 -5
  30. data/lib/doorkeeper/oauth/client.rb +9 -8
  31. data/lib/doorkeeper/oauth/client_credentials/creator.rb +3 -4
  32. data/lib/doorkeeper/oauth/error.rb +5 -1
  33. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -1
  34. data/lib/doorkeeper/oauth/refresh_token_request.rb +17 -7
  35. data/lib/doorkeeper/orm/active_record/access_grant.rb +2 -2
  36. data/lib/doorkeeper/orm/active_record/access_token.rb +2 -2
  37. data/lib/doorkeeper/orm/active_record/application.rb +2 -2
  38. data/lib/doorkeeper/orm/active_record.rb +22 -0
  39. data/lib/doorkeeper/rails/helpers.rb +19 -29
  40. data/lib/doorkeeper/request/authorization_code.rb +10 -15
  41. data/lib/doorkeeper/request/client_credentials.rb +9 -15
  42. data/lib/doorkeeper/request/code.rb +7 -13
  43. data/lib/doorkeeper/request/password.rb +10 -15
  44. data/lib/doorkeeper/request/refresh_token.rb +11 -13
  45. data/lib/doorkeeper/request/strategy.rb +17 -0
  46. data/lib/doorkeeper/request/token.rb +7 -13
  47. data/lib/doorkeeper/request.rb +18 -8
  48. data/lib/doorkeeper/server.rb +2 -2
  49. data/lib/doorkeeper/version.rb +1 -1
  50. data/lib/doorkeeper.rb +0 -4
  51. data/lib/generators/doorkeeper/templates/README +0 -20
  52. data/lib/generators/doorkeeper/templates/initializer.rb +5 -3
  53. data/lib/generators/doorkeeper/templates/migration.rb +8 -0
  54. data/spec/controllers/applications_controller_spec.rb +0 -1
  55. data/spec/controllers/protected_resources_controller_spec.rb +115 -14
  56. data/spec/controllers/token_info_controller_spec.rb +0 -4
  57. data/spec/controllers/tokens_controller_spec.rb +34 -3
  58. data/spec/dummy/app/models/user.rb +2 -24
  59. data/spec/dummy/config/application.rb +2 -1
  60. data/spec/dummy/config/initializers/doorkeeper.rb +0 -2
  61. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +24 -0
  62. data/spec/lib/config_spec.rb +20 -4
  63. data/spec/lib/models/revocable_spec.rb +2 -2
  64. data/spec/lib/oauth/authorization_code_request_spec.rb +1 -1
  65. data/spec/lib/oauth/client/credentials_spec.rb +2 -2
  66. data/spec/lib/oauth/client_credentials/creator_spec.rb +25 -1
  67. data/spec/lib/oauth/error_response_spec.rb +7 -7
  68. data/spec/lib/oauth/error_spec.rb +9 -5
  69. data/spec/lib/oauth/helpers/scope_checker_spec.rb +3 -3
  70. data/spec/lib/oauth/password_access_token_request_spec.rb +1 -1
  71. data/spec/lib/oauth/pre_authorization_spec.rb +9 -10
  72. data/spec/lib/oauth/refresh_token_request_spec.rb +26 -6
  73. data/spec/lib/oauth/scopes_spec.rb +1 -1
  74. data/spec/lib/oauth/token_request_spec.rb +6 -3
  75. data/spec/lib/request/strategy_spec.rb +53 -0
  76. data/spec/lib/server_spec.rb +4 -2
  77. data/spec/models/doorkeeper/access_grant_spec.rb +5 -5
  78. data/spec/models/doorkeeper/access_token_spec.rb +102 -5
  79. data/spec/models/doorkeeper/application_spec.rb +13 -16
  80. data/spec/requests/applications/applications_request_spec.rb +1 -1
  81. data/spec/requests/endpoints/authorization_spec.rb +2 -1
  82. data/spec/requests/endpoints/token_spec.rb +9 -9
  83. data/spec/requests/flows/authorization_code_errors_spec.rb +4 -4
  84. data/spec/requests/flows/authorization_code_spec.rb +36 -2
  85. data/spec/requests/flows/implicit_grant_spec.rb +14 -5
  86. data/spec/requests/flows/password_spec.rb +14 -20
  87. data/spec/requests/flows/refresh_token_spec.rb +15 -7
  88. data/spec/requests/flows/revoke_token_spec.rb +9 -31
  89. data/spec/requests/protected_resources/metal_spec.rb +3 -3
  90. data/spec/requests/protected_resources/private_api_spec.rb +11 -0
  91. data/spec/routing/custom_controller_routes_spec.rb +1 -2
  92. data/spec/routing/default_routes_spec.rb +1 -2
  93. data/spec/routing/scoped_routes_spec.rb +0 -1
  94. data/spec/spec_helper_integration.rb +10 -7
  95. data/spec/support/helpers/access_token_request_helper.rb +1 -1
  96. data/spec/support/helpers/authorization_request_helper.rb +1 -1
  97. data/spec/support/helpers/config_helper.rb +1 -1
  98. data/spec/support/helpers/model_helper.rb +1 -1
  99. data/spec/support/helpers/request_spec_helper.rb +1 -1
  100. data/spec/support/helpers/url_helper.rb +1 -1
  101. data/spec/support/shared/models_shared_examples.rb +1 -1
  102. data/spec/validators/redirect_uri_validator_spec.rb +5 -0
  103. metadata +127 -98
  104. data/gemfiles/Gemfile.common.rb +0 -14
  105. data/gemfiles/Gemfile.mongo_mapper.rb +0 -5
  106. data/gemfiles/Gemfile.mongoid2.rb +0 -5
  107. data/gemfiles/Gemfile.mongoid3.rb +0 -4
  108. data/gemfiles/Gemfile.mongoid4.rb +0 -5
  109. data/lib/doorkeeper/generators/doorkeeper/mongo_mapper/indexes_generator.rb +0 -12
  110. data/lib/doorkeeper/generators/doorkeeper/mongo_mapper/templates/indexes.rb +0 -3
  111. data/lib/doorkeeper/orm/mongo_mapper/access_grant.rb +0 -24
  112. data/lib/doorkeeper/orm/mongo_mapper/access_token.rb +0 -43
  113. data/lib/doorkeeper/orm/mongo_mapper/application.rb +0 -29
  114. data/lib/doorkeeper/orm/mongo_mapper.rb +0 -11
  115. data/lib/doorkeeper/orm/mongoid2/access_grant.rb +0 -22
  116. data/lib/doorkeeper/orm/mongoid2/access_token.rb +0 -37
  117. data/lib/doorkeeper/orm/mongoid2/application.rb +0 -25
  118. data/lib/doorkeeper/orm/mongoid2/concerns/scopes.rb +0 -30
  119. data/lib/doorkeeper/orm/mongoid2.rb +0 -11
  120. data/lib/doorkeeper/orm/mongoid3/access_grant.rb +0 -22
  121. data/lib/doorkeeper/orm/mongoid3/access_token.rb +0 -37
  122. data/lib/doorkeeper/orm/mongoid3/application.rb +0 -25
  123. data/lib/doorkeeper/orm/mongoid3/concerns/scopes.rb +0 -30
  124. data/lib/doorkeeper/orm/mongoid3.rb +0 -11
  125. data/lib/doorkeeper/orm/mongoid4/access_grant.rb +0 -22
  126. data/lib/doorkeeper/orm/mongoid4/access_token.rb +0 -37
  127. data/lib/doorkeeper/orm/mongoid4/application.rb +0 -25
  128. data/lib/doorkeeper/orm/mongoid4/concerns/scopes.rb +0 -17
  129. data/lib/doorkeeper/orm/mongoid4.rb +0 -11
  130. data/spec/dummy/config/mongo.yml +0 -11
  131. data/spec/dummy/config/mongoid2.yml +0 -9
  132. data/spec/dummy/config/mongoid3.yml +0 -18
  133. data/spec/dummy/config/mongoid4.yml +0 -19
  134. data/spec/support/orm/mongo_mapper.rb +0 -10
  135. data/spec/support/orm/mongoid.rb +0 -10
@@ -8,12 +8,12 @@ module Doorkeeper
8
8
 
9
9
  def authorization_request(strategy)
10
10
  klass = Request.authorization_strategy strategy
11
- klass.build self
11
+ klass.new self
12
12
  end
13
13
 
14
14
  def token_request(strategy)
15
15
  klass = Request.token_strategy strategy
16
- klass.build self
16
+ klass.new self
17
17
  end
18
18
 
19
19
  # TODO: context should be the request
@@ -1,3 +1,3 @@
1
1
  module Doorkeeper
2
- VERSION = '2.1.4'
2
+ VERSION = "3.1.0"
3
3
  end
data/lib/doorkeeper.rb CHANGED
@@ -47,10 +47,6 @@ require 'doorkeeper/rails/routes'
47
47
  require 'doorkeeper/rails/helpers'
48
48
 
49
49
  require 'doorkeeper/orm/active_record'
50
- require 'doorkeeper/orm/mongo_mapper'
51
- require 'doorkeeper/orm/mongoid2'
52
- require 'doorkeeper/orm/mongoid3'
53
- require 'doorkeeper/orm/mongoid4'
54
50
 
55
51
  module Doorkeeper
56
52
  def self.configured?
@@ -17,26 +17,6 @@ And run
17
17
 
18
18
  rake db:migrate
19
19
 
20
- If you want to use Mongoid, configure the orm in initializers/doorkeeper.rb:
21
-
22
- # Mongoid
23
- Doorkeeper.configure do
24
- orm :mongoid
25
- end
26
-
27
- If you want to use MongoMapper, configure the orm in
28
- initializers/doorkeeper.rb:
29
-
30
- # MongoMapper
31
- Doorkeeper.configure do
32
- orm :mongo_mapper
33
- end
34
-
35
- And run
36
-
37
- rails generate doorkeeper:mongo_mapper:indexes
38
- rake db:index
39
-
40
20
  Step 3.
41
21
  That's it, that's all. Enjoy!
42
22
 
@@ -1,7 +1,5 @@
1
1
  Doorkeeper.configure do
2
- # Change the ORM that doorkeeper will use.
3
- # Currently supported options are :active_record, :mongoid2, :mongoid3,
4
- # :mongoid4, :mongo_mapper
2
+ # Change the ORM that doorkeeper will use (needs plugins)
5
3
  orm :active_record
6
4
 
7
5
  # This block will be called to check whether the resource owner is authenticated or not.
@@ -31,6 +29,10 @@ Doorkeeper.configure do
31
29
  # oauth_client.application.additional_settings.implicit_oauth_expiration
32
30
  # end
33
31
 
32
+ # Use a custom class for generating the access token.
33
+ # https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
34
+ # access_token_generator "::Doorkeeper::JWT"
35
+
34
36
  # Reuse access token for the same resource owner within an application (disabled by default)
35
37
  # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
36
38
  # reuse_access_token
@@ -27,7 +27,15 @@ class CreateDoorkeeperTables < ActiveRecord::Migration
27
27
  create_table :oauth_access_tokens do |t|
28
28
  t.integer :resource_owner_id
29
29
  t.integer :application_id
30
+
31
+ # If you use a custom token generator you may need to change this column
32
+ # from string to text, so that it accepts tokens larger than 255
33
+ # characters. More info on custom token generators in:
34
+ # https://github.com/doorkeeper-gem/doorkeeper/tree/v3.0.0.rc1#custom-access-token-generator
35
+ #
36
+ # t.text :token, null: false
30
37
  t.string :token, null: false
38
+
31
39
  t.string :refresh_token
32
40
  t.integer :expires_in
33
41
  t.datetime :revoked_at
@@ -54,6 +54,5 @@ module Doorkeeper
54
54
  expect(application.reload.name).to eq 'Example'
55
55
  end
56
56
  end
57
-
58
57
  end
59
58
  end
@@ -126,7 +126,17 @@ describe 'doorkeeper authorize filter' do
126
126
 
127
127
  context 'with a JSON custom render', token: :invalid do
128
128
  before do
129
- expect(controller).to receive(:doorkeeper_unauthorized_render_options).and_return(json: ActiveSupport::JSON.encode(error: 'Unauthorized'))
129
+ module ControllerActions
130
+ def doorkeeper_unauthorized_render_options(error: nil)
131
+ { json: ActiveSupport::JSON.encode(error_message: error.description) }
132
+ end
133
+ end
134
+ end
135
+ after do
136
+ module ControllerActions
137
+ def doorkeeper_unauthorized_render_options(error: nil)
138
+ end
139
+ end
130
140
  end
131
141
 
132
142
  it 'it renders a custom JSON response', token: :invalid do
@@ -136,16 +146,26 @@ describe 'doorkeeper authorize filter' do
136
146
  expect(response.header['WWW-Authenticate']).to match(/^Bearer/)
137
147
  parsed_body = JSON.parse(response.body)
138
148
  expect(parsed_body).not_to be_nil
139
- expect(parsed_body['error']).to eq('Unauthorized')
149
+ expect(parsed_body['error_message']).to match('token is invalid')
140
150
  end
141
151
  end
142
152
 
143
153
  context 'with a text custom render', token: :invalid do
144
154
  before do
145
- expect(controller).to receive(:doorkeeper_unauthorized_render_options).and_return(text: 'Unauthorized')
155
+ module ControllerActions
156
+ def doorkeeper_unauthorized_render_options(error: nil)
157
+ { text: 'Unauthorized' }
158
+ end
159
+ end
160
+ end
161
+ after do
162
+ module ControllerActions
163
+ def doorkeeper_unauthorized_render_options(error: nil)
164
+ end
165
+ end
146
166
  end
147
167
 
148
- it 'it renders a custom JSON response', token: :invalid do
168
+ it 'it renders a custom text response', token: :invalid do
149
169
  get :index, access_token: token_string
150
170
  expect(response.status).to eq 401
151
171
  expect(response.content_type).to eq('text/html')
@@ -155,16 +175,97 @@ describe 'doorkeeper authorize filter' do
155
175
  end
156
176
  end
157
177
 
158
- context 'defined for all actions' do
159
- controller {}
160
-
161
- it 'it renders a custom JSON response', token: :invalid do
162
- expect do
163
- controller.class.doorkeeper_for
164
- end.to raise_error(
165
- Doorkeeper::Errors::DoorkeeperError,
166
- /`doorkeeper_for` no longer available/
167
- )
178
+ context 'when custom forbidden render options are configured' do
179
+ before do
180
+ expect(Doorkeeper::AccessToken).to receive(:by_token).with(token_string).and_return(token)
181
+ expect(token).to receive(:acceptable?).with([:write]).and_return(false)
182
+ end
183
+
184
+ after do
185
+ module ControllerActions
186
+ def doorkeeper_forbidden_render_options(*)
187
+ end
188
+ end
189
+ end
190
+
191
+ controller do
192
+ before_filter -> { doorkeeper_authorize! :write }
193
+
194
+ include ControllerActions
195
+ end
196
+
197
+ let(:token) do
198
+ double(Doorkeeper::AccessToken,
199
+ accessible?: true, scopes: ['public'], revoked?: false, expired?: false)
200
+ end
201
+ let(:token_string) { '1A2DUWE' }
202
+
203
+ context 'with a JSON custom render' do
204
+ before do
205
+ module ControllerActions
206
+ def doorkeeper_forbidden_render_options(*)
207
+ { json: { error_message: 'Forbidden' } }
208
+ end
209
+ end
210
+ end
211
+
212
+ it 'renders a custom JSON response' do
213
+ get :index, access_token: token_string
214
+ expect(response.header).to_not include('WWW-Authenticate')
215
+ expect(response.content_type).to eq('application/json')
216
+ expect(response.status).to eq 403
217
+ parsed_body = JSON.parse(response.body)
218
+ expect(parsed_body).not_to be_nil
219
+ expect(parsed_body['error_message']).to match('Forbidden')
220
+ end
221
+ end
222
+
223
+ context 'with a status and JSON custom render' do
224
+ before do
225
+ module ControllerActions
226
+ def doorkeeper_forbidden_render_options(*)
227
+ { json: { error_message: 'Not Found' },
228
+ respond_not_found_when_forbidden: true }
229
+ end
230
+ end
231
+ end
232
+
233
+ it 'overrides the default status code' do
234
+ get :index, access_token: token_string
235
+ expect(response.status).to eq 404
236
+ end
237
+ end
238
+
239
+ context 'with a text custom render' do
240
+ before do
241
+ module ControllerActions
242
+ def doorkeeper_forbidden_render_options(*)
243
+ { text: 'Forbidden' }
244
+ end
245
+ end
246
+ end
247
+
248
+ it 'renders a custom status code and text response' do
249
+ get :index, access_token: token_string
250
+ expect(response.header).to_not include('WWW-Authenticate')
251
+ expect(response.status).to eq 403
252
+ expect(response.body).to eq('Forbidden')
253
+ end
254
+ end
255
+
256
+ context 'with a status and text custom render' do
257
+ before do
258
+ module ControllerActions
259
+ def doorkeeper_forbidden_render_options(*)
260
+ { respond_not_found_when_forbidden: true, text: 'Not Found' }
261
+ end
262
+ end
263
+ end
264
+
265
+ it 'overrides the default status code' do
266
+ get :index, access_token: token_string
267
+ expect(response.status).to eq 404
268
+ end
168
269
  end
169
270
  end
170
271
  end
@@ -1,9 +1,7 @@
1
1
  require 'spec_helper_integration'
2
2
 
3
3
  describe Doorkeeper::TokenInfoController do
4
-
5
4
  describe 'when requesting tokeninfo with valid token' do
6
-
7
5
  let(:doorkeeper_token) { FactoryGirl.create(:access_token) }
8
6
 
9
7
  before(:each) do
@@ -50,7 +48,5 @@ describe Doorkeeper::TokenInfoController do
50
48
  expect(response.body).to eq(Doorkeeper::OAuth::ErrorResponse.new(name: :invalid_request, status: :unauthorized).body.to_json)
51
49
  end
52
50
  end
53
-
54
51
  end
55
-
56
52
  end
@@ -12,7 +12,9 @@ describe Doorkeeper::TokensController do
12
12
 
13
13
  it 'returns the authorization' do
14
14
  skip 'verify need of these specs'
15
+
15
16
  expect(token).to receive(:authorization)
17
+
16
18
  post :create
17
19
  end
18
20
  end
@@ -29,6 +31,36 @@ describe Doorkeeper::TokensController do
29
31
  end
30
32
  end
31
33
 
34
+ describe 'when there is a failure due to a custom error' do
35
+ it 'returns the error response with a custom message' do
36
+ # I18n looks for `doorkeeper.errors.messages.custom_message` in locale files
37
+ custom_message = "my_message"
38
+ allow(I18n).to receive(:translate).
39
+ with(
40
+ custom_message,
41
+ hash_including(scope: [:doorkeeper, :errors, :messages]),
42
+ ).
43
+ and_return('Authorization custom message')
44
+
45
+ doorkeeper_error = Doorkeeper::Errors::DoorkeeperError.new(custom_message)
46
+
47
+ strategy = double(:strategy)
48
+ request = double(token_request: strategy)
49
+ allow(strategy).to receive(:authorize).and_raise(doorkeeper_error)
50
+ allow(controller).to receive(:server).and_return(request)
51
+
52
+ post :create
53
+
54
+ expected_response_body = {
55
+ "error" => custom_message,
56
+ "error_description" => "Authorization custom message"
57
+ }
58
+ expect(response.status).to eq 401
59
+ expect(response.headers['WWW-Authenticate']).to match(/Bearer/)
60
+ expect(JSON.load(response.body)).to eq expected_response_body
61
+ end
62
+ end
63
+
32
64
  describe 'when revoke authorization has failed' do
33
65
  # http://tools.ietf.org/html/rfc7009#section-2.2
34
66
  it 'returns no error response' do
@@ -46,11 +78,10 @@ describe Doorkeeper::TokensController do
46
78
  strategy = double(:strategy, authorize: true)
47
79
  expect(strategy).to receive(:authorize).once
48
80
  allow(controller).to receive(:strategy) { strategy }
49
-
50
- controller.stub(:create) do
51
- controller.send :authorize_response
81
+ allow(controller).to receive(:create) do
52
82
  controller.send :authorize_response
53
83
  end
84
+
54
85
  post :create
55
86
  end
56
87
  end
@@ -1,27 +1,5 @@
1
- case DOORKEEPER_ORM.to_s
2
- when "active_record"
3
- class User < ActiveRecord::Base
4
- end
5
- when /mongoid/
6
- class User
7
- include Mongoid::Document
8
- include Mongoid::Timestamps
9
-
10
- field :name, type: String
11
- field :password, type: String
12
- end
13
- when "mongo_mapper"
14
- class User
15
- include MongoMapper::Document
16
- timestamps!
17
-
18
- key :name, String
19
- key :password, String
20
- end
21
- end
22
-
23
- class User
24
- if ::Rails.version.to_i < 4 || defined?(::ProtectedAttributes)
1
+ class User < ActiveRecord::Base
2
+ if respond_to?(:attr_accessible)
25
3
  attr_accessible :name, :password
26
4
  end
27
5
 
@@ -5,13 +5,14 @@ require 'sprockets/railtie'
5
5
 
6
6
  Bundler.require :default
7
7
 
8
+ require 'yaml'
9
+
8
10
  orm = if DOORKEEPER_ORM =~ /mongoid/
9
11
  Mongoid.load!(File.join(File.dirname(File.expand_path(__FILE__)), "#{DOORKEEPER_ORM}.yml"))
10
12
  :mongoid
11
13
  else
12
14
  DOORKEEPER_ORM
13
15
  end
14
-
15
16
  require "#{orm}/railtie"
16
17
 
17
18
  module Dummy
@@ -1,7 +1,5 @@
1
1
  Doorkeeper.configure do
2
2
  # Change the ORM that doorkeeper will use.
3
- # Currently supported options are :active_record, :mongoid2, :mongoid3,
4
- # :mongoid4, :mongo_mapper
5
3
  orm DOORKEEPER_ORM
6
4
 
7
5
  # This block will be called to check whether the resource owner is authenticated or not.
@@ -0,0 +1,24 @@
1
+ require 'spec_helper_integration'
2
+
3
+ describe Doorkeeper::DashboardHelper do
4
+ describe '.doorkeeper_errors_for' do
5
+ let(:object) { double errors: { method: messages } }
6
+ let(:messages) { ['first message', 'second message'] }
7
+
8
+ context 'when object has errors' do
9
+ it 'returns error messages' do
10
+ messages.each do |message|
11
+ expect(helper.doorkeeper_errors_for(object, :method)).to include(
12
+ message.capitalize
13
+ )
14
+ end
15
+ end
16
+ end
17
+
18
+ context 'when object has no errors' do
19
+ it 'returns nil' do
20
+ expect(helper.doorkeeper_errors_for(object, :amonter_method)).to be_nil
21
+ end
22
+ end
23
+ end
24
+ end
@@ -14,7 +14,7 @@ describe Doorkeeper, 'configuration' do
14
14
  end
15
15
  end
16
16
 
17
- describe 'enable_orm' do
17
+ describe 'setup_orm_adapter' do
18
18
  it 'adds specific error message to NameError exception' do
19
19
  expect do
20
20
  Doorkeeper.configure { orm 'hibernate' }
@@ -22,11 +22,11 @@ describe Doorkeeper, 'configuration' do
22
22
  end
23
23
 
24
24
  it 'does not change other exceptions' do
25
- String.any_instance.stub(:classify) { raise NoMethodError }
25
+ allow_any_instance_of(String).to receive(:classify) { raise NoMethodError }
26
26
 
27
27
  expect do
28
28
  Doorkeeper.configure { orm 'hibernate' }
29
- end.to raise_error(NoMethodError, 'NoMethodError')
29
+ end.to raise_error(NoMethodError, /ORM adapter not found \(hibernate\)/)
30
30
  end
31
31
  end
32
32
 
@@ -35,7 +35,7 @@ describe Doorkeeper, 'configuration' do
35
35
  block = proc {}
36
36
  Doorkeeper.configure do
37
37
  orm DOORKEEPER_ORM
38
- admin_authenticator &block
38
+ admin_authenticator(&block)
39
39
  end
40
40
  expect(subject.authenticate_admin).to eq(block)
41
41
  end
@@ -298,4 +298,20 @@ describe Doorkeeper, 'configuration' do
298
298
  @config = old_config
299
299
  end
300
300
  end
301
+
302
+ describe 'access_token_generator' do
303
+ it 'is \'Doorkeeper::OAuth::Helpers::UniqueToken\' by default' do
304
+ expect(Doorkeeper.configuration.access_token_generator).to(
305
+ eq('Doorkeeper::OAuth::Helpers::UniqueToken')
306
+ )
307
+ end
308
+
309
+ it 'can change the value' do
310
+ Doorkeeper.configure do
311
+ orm DOORKEEPER_ORM
312
+ access_token_generator 'Example'
313
+ end
314
+ expect(subject.access_token_generator).to eq('Example')
315
+ end
316
+ end
301
317
  end
@@ -19,12 +19,12 @@ describe 'Revocable' do
19
19
 
20
20
  describe :revoked? do
21
21
  it 'is revoked if :revoked_at has passed' do
22
- allow(subject).to receive(:revoked_at).and_return(DateTime.now - 1000)
22
+ allow(subject).to receive(:revoked_at).and_return(Time.now - 1000)
23
23
  expect(subject).to be_revoked
24
24
  end
25
25
 
26
26
  it 'is not revoked if :revoked_at has not passed' do
27
- allow(subject).to receive(:revoked_at).and_return(DateTime.now + 1000)
27
+ allow(subject).to receive(:revoked_at).and_return(Time.now + 1000)
28
28
  expect(subject).not_to be_revoked
29
29
  end
30
30
 
@@ -69,7 +69,7 @@ module Doorkeeper::OAuth
69
69
  end
70
70
 
71
71
  it 'skips token creation if there is a matching one' do
72
- Doorkeeper.configuration.stub(:reuse_access_token).and_return(true)
72
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
73
73
  FactoryGirl.create(:access_token, application_id: client.id,
74
74
  resource_owner_id: grant.resource_owner_id, scopes: grant.scopes.to_s)
75
75
  expect do
@@ -13,7 +13,7 @@ class Doorkeeper::OAuth::Client
13
13
  let(:request) { double.as_null_object }
14
14
 
15
15
  let(:method) do
16
- ->(request) { return 'uid', 'secret' }
16
+ ->(_request) { return 'uid', 'secret' }
17
17
  end
18
18
 
19
19
  it 'accepts anything that responds to #call' do
@@ -29,7 +29,7 @@ class Doorkeeper::OAuth::Client
29
29
  it 'stops at the first credentials found' do
30
30
  not_called_method = double
31
31
  expect(not_called_method).not_to receive(:call)
32
- credentials = Credentials.from_request request, ->(r) {}, method, not_called_method
32
+ Credentials.from_request request, ->(_) {}, method, not_called_method
33
33
  end
34
34
 
35
35
  it 'returns new Credentials' do
@@ -11,8 +11,32 @@ class Doorkeeper::OAuth::ClientCredentialsRequest
11
11
  end.to change { Doorkeeper::AccessToken.count }.by(1)
12
12
  end
13
13
 
14
+ context "when reuse_access_token is true" do
15
+ it "returns the existing valid token" do
16
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
17
+ existing_token = subject.call(client, scopes)
18
+
19
+ result = subject.call(client, scopes)
20
+
21
+ expect(Doorkeeper::AccessToken.count).to eq(1)
22
+ expect(result).to eq(existing_token)
23
+ end
24
+ end
25
+
26
+ context "when reuse_access_token is false" do
27
+ it "returns a new token" do
28
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(false)
29
+ existing_token = subject.call(client, scopes)
30
+
31
+ result = subject.call(client, scopes)
32
+
33
+ expect(Doorkeeper::AccessToken.count).to eq(2)
34
+ expect(result).not_to eq(existing_token)
35
+ end
36
+ end
37
+
14
38
  it 'returns false if creation fails' do
15
- expect(Doorkeeper::AccessToken).to receive(:create).and_return(false)
39
+ expect(Doorkeeper::AccessToken).to receive(:find_or_create_for).and_return(false)
16
40
  created = subject.call(client, scopes)
17
41
  expect(created).to be_falsey
18
42
  end
@@ -37,9 +37,9 @@ module Doorkeeper::OAuth
37
37
  subject { ErrorResponse.new(name: :some_error, state: :some_state).body }
38
38
 
39
39
  describe '#body' do
40
- it { should have_key(:error) }
41
- it { should have_key(:error_description) }
42
- it { should have_key(:state) }
40
+ it { expect(subject).to have_key(:error) }
41
+ it { expect(subject).to have_key(:error_description) }
42
+ it { expect(subject).to have_key(:state) }
43
43
  end
44
44
  end
45
45
 
@@ -47,15 +47,15 @@ module Doorkeeper::OAuth
47
47
  let(:error_response) { ErrorResponse.new(name: :some_error, state: :some_state) }
48
48
  subject { error_response.authenticate_info }
49
49
 
50
- it { should include("realm=\"#{error_response.realm}\"") }
51
- it { should include("error=\"#{error_response.name}\"") }
52
- it { should include("error_description=\"#{error_response.description}\"") }
50
+ it { expect(subject).to include("realm=\"#{error_response.realm}\"") }
51
+ it { expect(subject).to include("error=\"#{error_response.name}\"") }
52
+ it { expect(subject).to include("error_description=\"#{error_response.description}\"") }
53
53
  end
54
54
 
55
55
  describe '.headers' do
56
56
  subject { ErrorResponse.new(name: :some_error, state: :some_state).headers }
57
57
 
58
- it { should include 'WWW-Authenticate' }
58
+ it { expect(subject).to include 'WWW-Authenticate' }
59
59
  end
60
60
  end
61
61
  end
@@ -4,15 +4,19 @@ require 'doorkeeper/oauth/error'
4
4
 
5
5
  module Doorkeeper::OAuth
6
6
  describe Error do
7
- subject { Error.new(:some_error, :some_state) }
7
+ subject(:error) { Error.new(:some_error, :some_state) }
8
8
 
9
- it { should respond_to(:name) }
10
- it { should respond_to(:state) }
9
+ it { expect(subject).to respond_to(:name) }
10
+ it { expect(subject).to respond_to(:state) }
11
11
 
12
12
  describe :description do
13
13
  it 'is translated from translation messages' do
14
- expect(I18n).to receive(:translate).with(:some_error, scope: [:doorkeeper, :errors, :messages])
15
- subject.description
14
+ expect(I18n).to receive(:translate).with(
15
+ :some_error,
16
+ scope: [:doorkeeper, :errors, :messages],
17
+ default: :server_error
18
+ )
19
+ error.description
16
20
  end
17
21
  end
18
22
  end
@@ -41,12 +41,12 @@ module Doorkeeper::OAuth::Helpers
41
41
  Doorkeeper::OAuth::Scopes.from_string 'common svr'
42
42
  end
43
43
  let(:application_scopes) do
44
- Doorkeeper::OAuth::Scopes.from_string 'common'
44
+ Doorkeeper::OAuth::Scopes.from_string 'app123'
45
45
  end
46
46
 
47
- it 'is valid if scope is included in the server and the application' do
47
+ it 'is valid if scope is included in the application scope list' do
48
48
  expect(ScopeChecker.valid?(
49
- 'common',
49
+ 'app123',
50
50
  server_scopes,
51
51
  application_scopes
52
52
  )).to be_truthy
@@ -60,7 +60,7 @@ module Doorkeeper::OAuth
60
60
  end
61
61
 
62
62
  it 'skips token creation if there is already one' do
63
- Doorkeeper.configuration.stub(:reuse_access_token).and_return(true)
63
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
64
64
  FactoryGirl.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
65
65
  expect do
66
66
  subject.authorize