doorkeeper 2.1.4 → 2.2.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -430
  3. data/Gemfile +1 -8
  4. data/NEWS.md +449 -0
  5. data/README.md +46 -3
  6. data/doorkeeper.gemspec +1 -1
  7. data/gemfiles/Gemfile.common.rb +0 -7
  8. data/gemfiles/Gemfile.mongo_mapper.rb +2 -2
  9. data/gemfiles/Gemfile.mongoid2.rb +1 -1
  10. data/gemfiles/Gemfile.mongoid4.rb +0 -1
  11. data/lib/doorkeeper/config.rb +7 -0
  12. data/lib/doorkeeper/engine.rb +4 -0
  13. data/lib/doorkeeper/errors.rb +6 -0
  14. data/lib/doorkeeper/models/access_token_mixin.rb +6 -1
  15. data/lib/doorkeeper/rails/helpers.rb +1 -1
  16. data/lib/doorkeeper/version.rb +1 -1
  17. data/lib/generators/doorkeeper/templates/initializer.rb +4 -0
  18. data/spec/controllers/applications_controller_spec.rb +0 -1
  19. data/spec/controllers/token_info_controller_spec.rb +0 -4
  20. data/spec/controllers/tokens_controller_spec.rb +4 -3
  21. data/spec/dummy/config/application.rb +2 -0
  22. data/spec/lib/config_spec.rb +18 -2
  23. data/spec/lib/oauth/authorization_code_request_spec.rb +1 -1
  24. data/spec/lib/oauth/client/credentials_spec.rb +2 -2
  25. data/spec/lib/oauth/password_access_token_request_spec.rb +1 -1
  26. data/spec/lib/oauth/pre_authorization_spec.rb +9 -10
  27. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -1
  28. data/spec/lib/oauth/token_request_spec.rb +3 -3
  29. data/spec/lib/server_spec.rb +3 -1
  30. data/spec/models/doorkeeper/access_token_spec.rb +48 -0
  31. data/spec/requests/applications/applications_request_spec.rb +1 -1
  32. data/spec/requests/endpoints/authorization_spec.rb +2 -1
  33. data/spec/requests/endpoints/token_spec.rb +9 -9
  34. data/spec/requests/flows/authorization_code_errors_spec.rb +4 -4
  35. data/spec/requests/flows/authorization_code_spec.rb +10 -2
  36. data/spec/requests/flows/implicit_grant_spec.rb +14 -5
  37. data/spec/requests/flows/password_spec.rb +14 -20
  38. data/spec/requests/flows/refresh_token_spec.rb +7 -7
  39. data/spec/requests/flows/revoke_token_spec.rb +9 -31
  40. data/spec/requests/protected_resources/metal_spec.rb +3 -3
  41. data/spec/requests/protected_resources/private_api_spec.rb +11 -0
  42. data/spec/routing/custom_controller_routes_spec.rb +1 -2
  43. data/spec/routing/default_routes_spec.rb +1 -2
  44. data/spec/routing/scoped_routes_spec.rb +0 -1
  45. data/spec/spec_helper_integration.rb +3 -1
  46. data/spec/support/helpers/access_token_request_helper.rb +1 -1
  47. data/spec/support/helpers/authorization_request_helper.rb +1 -1
  48. data/spec/support/helpers/config_helper.rb +1 -1
  49. data/spec/support/helpers/model_helper.rb +1 -1
  50. data/spec/support/helpers/request_spec_helper.rb +1 -1
  51. data/spec/support/helpers/url_helper.rb +1 -1
  52. metadata +5 -4
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency "railties", ">= 3.2"
20
20
 
21
21
  s.add_development_dependency "sqlite3", "~> 1.3.5"
22
- s.add_development_dependency "rspec-rails", "~> 2.99.0"
22
+ s.add_development_dependency "rspec-rails", "~> 3.1.0"
23
23
  s.add_development_dependency "capybara", "~> 2.3.0"
24
24
  s.add_development_dependency "generator_spec", "~> 0.9.0"
25
25
  s.add_development_dependency "factory_girl", "~> 4.5.0"
@@ -4,11 +4,4 @@ source 'https://rubygems.org'
4
4
 
5
5
  gem 'rails', "~> #{ENV['rails']}"
6
6
 
7
- if ENV['rails'][0] == '4'
8
- gem 'database_cleaner', '~> 1.3.0'
9
- end
10
- if ENV['rails'] =~ /4.0|3.2/
11
- gem 'rubysl-test-unit'
12
- end
13
-
14
7
  gemspec path: '../'
@@ -1,5 +1,5 @@
1
1
  gemfile = 'gemfiles/Gemfile.common.rb'
2
2
  instance_eval IO.read(gemfile), gemfile
3
3
 
4
- gem 'mongo_mapper', '~> 0.12'
5
- gem 'bson_ext', '~> 1.7'
4
+ gem 'mongo_mapper'
5
+ gem 'bson_ext'
@@ -2,4 +2,4 @@ gemfile = 'gemfiles/Gemfile.common.rb'
2
2
  instance_eval IO.read(gemfile), gemfile
3
3
 
4
4
  gem 'mongoid', '~> 2'
5
- gem 'bson_ext', '~> 1.7'
5
+ gem 'bson_ext'
@@ -2,4 +2,3 @@ gemfile = 'gemfiles/Gemfile.common.rb'
2
2
  instance_eval IO.read(gemfile), gemfile
3
3
 
4
4
  gem 'mongoid', '~> 4'
5
- gem 'moped'
@@ -108,6 +108,12 @@ and that your `initialize_models!` method doesn't raise any errors.\n
108
108
  def force_ssl_in_redirect_uri(boolean)
109
109
  @config.instance_variable_set("@force_ssl_in_redirect_uri", boolean)
110
110
  end
111
+
112
+ def access_token_generator(access_token_generator)
113
+ @config.instance_variable_set(
114
+ '@access_token_generator', access_token_generator
115
+ )
116
+ end
111
117
  end
112
118
 
113
119
  module Option
@@ -198,6 +204,7 @@ and that your `initialize_models!` method doesn't raise any errors.\n
198
204
  option :realm, default: 'Doorkeeper'
199
205
  option :force_ssl_in_redirect_uri, default: !Rails.env.development?
200
206
  option :grant_flows, default: %w(authorization_code client_credentials)
207
+ option :access_token_generator, default: "Doorkeeper::OAuth::Helpers::UniqueToken"
201
208
 
202
209
  attr_reader :reuse_access_token
203
210
 
@@ -4,6 +4,10 @@ module Doorkeeper
4
4
  app.config.filter_parameters += %i(client_secret code token)
5
5
  end
6
6
 
7
+ initializer "doorkeeper.locales" do |app|
8
+ app.config.i18n.fallbacks = [:en]
9
+ end
10
+
7
11
  initializer "doorkeeper.routes" do
8
12
  Doorkeeper::Rails::Routes.install!
9
13
  end
@@ -11,5 +11,11 @@ module Doorkeeper
11
11
 
12
12
  class MissingRequestStrategy < DoorkeeperError
13
13
  end
14
+
15
+ class UnableToGenerateToken < DoorkeeperError
16
+ end
17
+
18
+ class TokenGeneratorNotFound < DoorkeeperError
19
+ end
14
20
  end
15
21
  end
@@ -128,7 +128,12 @@ module Doorkeeper
128
128
  end
129
129
 
130
130
  def generate_token
131
- self.token = UniqueToken.generate
131
+ generator = Doorkeeper.configuration.access_token_generator.constantize
132
+ self.token = generator.generate(resource_owner_id: resource_owner_id)
133
+ rescue NoMethodError
134
+ raise Errors::UnableToGenerateToken, "#{generator} does not respond to `.generate`."
135
+ rescue NameError
136
+ raise Errors::TokenGeneratorNotFound, "#{generator} not found"
132
137
  end
133
138
  end
134
139
  end
@@ -4,7 +4,7 @@ module Doorkeeper
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  def doorkeeper_authorize!(*scopes)
7
- @_doorkeeper_scopes = scopes || Doorkeeper.configuration.default_scopes
7
+ @_doorkeeper_scopes = scopes.presence || Doorkeeper.configuration.default_scopes
8
8
 
9
9
  if !valid_doorkeeper_token?
10
10
  doorkeeper_render_error
@@ -1,3 +1,3 @@
1
1
  module Doorkeeper
2
- VERSION = '2.1.4'
2
+ VERSION = '2.2.0'
3
3
  end
@@ -31,6 +31,10 @@ Doorkeeper.configure do
31
31
  # oauth_client.application.additional_settings.implicit_oauth_expiration
32
32
  # end
33
33
 
34
+ # Use a custom class for generating the access token.
35
+ # https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
36
+ # access_token_generator "::Doorkeeper::JWT"
37
+
34
38
  # Reuse access token for the same resource owner within an application (disabled by default)
35
39
  # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
36
40
  # reuse_access_token
@@ -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
@@ -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
@@ -46,11 +48,10 @@ describe Doorkeeper::TokensController do
46
48
  strategy = double(:strategy, authorize: true)
47
49
  expect(strategy).to receive(:authorize).once
48
50
  allow(controller).to receive(:strategy) { strategy }
49
-
50
- controller.stub(:create) do
51
- controller.send :authorize_response
51
+ allow(controller).to receive(:create) do
52
52
  controller.send :authorize_response
53
53
  end
54
+
54
55
  post :create
55
56
  end
56
57
  end
@@ -5,6 +5,8 @@ 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
@@ -22,7 +22,7 @@ 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' }
@@ -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
@@ -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
@@ -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
@@ -4,14 +4,14 @@ module Doorkeeper::OAuth
4
4
  describe PreAuthorization do
5
5
  let(:server) {
6
6
  server = Doorkeeper.configuration
7
- server.stub(:default_scopes) { Scopes.new }
8
- server.stub(:scopes) { Scopes.from_string('public profile') }
7
+ allow(server).to receive(:default_scopes).and_return(Scopes.new)
8
+ allow(server).to receive(:scopes).and_return(Scopes.from_string('public profile'))
9
9
  server
10
10
  }
11
11
 
12
12
  let(:application) do
13
13
  application = double :application
14
- application.stub(:scopes) { Scopes.from_string('') }
14
+ allow(application).to receive(:scopes).and_return(Scopes.from_string(''))
15
15
  application
16
16
  end
17
17
 
@@ -41,7 +41,7 @@ module Doorkeeper::OAuth
41
41
  end
42
42
 
43
43
  it 'accepts token as response type' do
44
- server.stub(:grant_flows) { ['implicit'] }
44
+ allow(server).to receive(:grant_flows).and_return(['implicit'])
45
45
  subject.response_type = 'token'
46
46
  expect(subject).to be_authorizable
47
47
  end
@@ -53,7 +53,7 @@ module Doorkeeper::OAuth
53
53
  end
54
54
 
55
55
  it 'accepts "token" as response type' do
56
- server.stub(:grant_flows) { ['implicit'] }
56
+ allow(server).to receive(:grant_flows).and_return(['implicit'])
57
57
  subject.response_type = 'token'
58
58
  expect(subject).to be_authorizable
59
59
  end
@@ -61,7 +61,7 @@ module Doorkeeper::OAuth
61
61
 
62
62
  context 'when authorization code grant flow is disabled' do
63
63
  before do
64
- server.stub(:grant_flows) { ['implicit'] }
64
+ allow(server).to receive(:grant_flows).and_return(['implicit'])
65
65
  end
66
66
 
67
67
  it 'does not accept "code" as response type' do
@@ -72,7 +72,7 @@ module Doorkeeper::OAuth
72
72
 
73
73
  context 'when implicit grant flow is disabled' do
74
74
  before do
75
- server.stub(:grant_flows) { ['authorization_code'] }
75
+ allow(server).to receive(:grant_flows).and_return(['authorization_code'])
76
76
  end
77
77
 
78
78
  it 'does not accept "token" as response type' do
@@ -96,7 +96,7 @@ module Doorkeeper::OAuth
96
96
  context 'client application restricts valid scopes' do
97
97
  let(:application) do
98
98
  application = double :application
99
- application.stub(:scopes) { Scopes.from_string('public nonsense') }
99
+ allow(application).to receive(:scopes).and_return(Scopes.from_string('public nonsense'))
100
100
  application
101
101
  end
102
102
 
@@ -119,7 +119,7 @@ module Doorkeeper::OAuth
119
119
  it 'uses default scopes when none is required' do
120
120
  allow(server).to receive(:default_scopes).and_return(Scopes.from_string('default'))
121
121
  subject.scope = nil
122
- expect(subject.scope).to eq('default')
122
+ expect(subject.scope).to eq('default')
123
123
  expect(subject.scopes).to eq(Scopes.from_string('default'))
124
124
  end
125
125
 
@@ -151,6 +151,5 @@ module Doorkeeper::OAuth
151
151
  subject.redirect_uri = nil
152
152
  expect(subject).not_to be_authorizable
153
153
  end
154
-
155
154
  end
156
155
  end
@@ -98,6 +98,5 @@ module Doorkeeper::OAuth
98
98
  expect(subject.error).to eq(:invalid_scope)
99
99
  end
100
100
  end
101
-
102
101
  end
103
102
  end
@@ -67,14 +67,14 @@ module Doorkeeper::OAuth
67
67
 
68
68
  context 'token reuse' do
69
69
  it 'creates a new token if there are no matching tokens' do
70
- Doorkeeper.configuration.stub(:reuse_access_token).and_return(true)
70
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
71
71
  expect do
72
72
  subject.authorize
73
73
  end.to change { Doorkeeper::AccessToken.count }.by(1)
74
74
  end
75
75
 
76
76
  it 'creates a new token if scopes do not match' do
77
- Doorkeeper.configuration.stub(:reuse_access_token).and_return(true)
77
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
78
78
  FactoryGirl.create(:access_token, application_id: pre_auth.client.id,
79
79
  resource_owner_id: owner.id, scopes: '')
80
80
  expect do
@@ -83,7 +83,7 @@ module Doorkeeper::OAuth
83
83
  end
84
84
 
85
85
  it 'skips token creation if there is a matching one' do
86
- Doorkeeper.configuration.stub(:reuse_access_token).and_return(true)
86
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
87
87
  FactoryGirl.create(:access_token, application_id: pre_auth.client.id,
88
88
  resource_owner_id: owner.id, scopes: 'public')
89
89
  expect do
@@ -25,7 +25,9 @@ describe Doorkeeper::Server do
25
25
 
26
26
  context 'when only Authorization Code strategy is enabled' do
27
27
  before do
28
- Doorkeeper.configuration.stub(:grant_flows) { ['authorization_code'] }
28
+ allow(Doorkeeper.configuration).
29
+ to receive(:grant_flows).
30
+ and_return(['authorization_code'])
29
31
  end
30
32
 
31
33
  it 'raises error when using the disabled Implicit strategy' do
@@ -12,6 +12,54 @@ module Doorkeeper
12
12
  let(:factory_name) { :access_token }
13
13
  end
14
14
 
15
+ describe :generate_token do
16
+ it 'generates a token using the default method' do
17
+ FactoryGirl.create :access_token
18
+
19
+ token = FactoryGirl.create :access_token
20
+ expect(token.token).to be_a(String)
21
+ end
22
+
23
+ it 'generates a token using a custom object' do
24
+ module CustomGeneratorArgs
25
+ def self.generate(opts = {})
26
+ "custom_generator_token_#{opts[:resource_owner_id]}"
27
+ end
28
+ end
29
+
30
+ Doorkeeper.configure do
31
+ orm DOORKEEPER_ORM
32
+ access_token_generator "Doorkeeper::CustomGeneratorArgs"
33
+ end
34
+
35
+ token = FactoryGirl.create :access_token
36
+ expect(token.token).to match(%r{custom_generator_token_\d})
37
+ end
38
+
39
+ it 'raises an error if the custom object does not support generate' do
40
+ module NoGenerate
41
+ end
42
+
43
+ Doorkeeper.configure do
44
+ orm DOORKEEPER_ORM
45
+ access_token_generator "Doorkeeper::NoGenerate"
46
+ end
47
+
48
+ expect { FactoryGirl.create :access_token }.to(
49
+ raise_error(Doorkeeper::Errors::UnableToGenerateToken))
50
+ end
51
+
52
+ it 'raises an error if the custom object does not exist' do
53
+ Doorkeeper.configure do
54
+ orm DOORKEEPER_ORM
55
+ access_token_generator "Doorkeeper::NotReal"
56
+ end
57
+
58
+ expect { FactoryGirl.create :access_token }.to(
59
+ raise_error(Doorkeeper::Errors::TokenGeneratorNotFound))
60
+ end
61
+ end
62
+
15
63
  describe :refresh_token do
16
64
  it 'has empty refresh token if it was not required' do
17
65
  token = FactoryGirl.create :access_token