doorkeeper 1.4.1 → 2.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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/.hound.yml +3 -0
  3. data/.travis.yml +38 -10
  4. data/CHANGELOG.md +43 -1
  5. data/CONTRIBUTING.md +35 -0
  6. data/Gemfile +4 -26
  7. data/README.md +21 -55
  8. data/Rakefile +3 -1
  9. data/app/controllers/doorkeeper/application_controller.rb +2 -2
  10. data/app/controllers/doorkeeper/applications_controller.rb +4 -5
  11. data/app/controllers/doorkeeper/authorizations_controller.rb +4 -2
  12. data/app/controllers/doorkeeper/tokens_controller.rb +2 -2
  13. data/app/helpers/doorkeeper/{form_errors_helper.rb → dashboard_helper.rb} +5 -1
  14. data/app/validators/redirect_uri_validator.rb +6 -0
  15. data/app/views/doorkeeper/applications/_delete_form.html.erb +1 -1
  16. data/app/views/doorkeeper/applications/_form.html.erb +3 -3
  17. data/app/views/doorkeeper/applications/index.html.erb +1 -1
  18. data/config/locales/en.yml +6 -3
  19. data/doorkeeper.gemspec +3 -3
  20. data/gemfiles/Gemfile.common.rb +11 -0
  21. data/gemfiles/Gemfile.mongo_mapper.rb +5 -0
  22. data/gemfiles/Gemfile.mongoid2.rb +5 -0
  23. data/gemfiles/Gemfile.mongoid3.rb +4 -0
  24. data/gemfiles/Gemfile.mongoid4.rb +5 -0
  25. data/lib/doorkeeper/config.rb +34 -24
  26. data/lib/doorkeeper/engine.rb +1 -2
  27. data/lib/doorkeeper/generators/doorkeeper/mongo_mapper/indexes_generator.rb +12 -0
  28. data/lib/doorkeeper/models/access_grant_mixin.rb +36 -0
  29. data/lib/doorkeeper/models/access_token_mixin.rb +122 -0
  30. data/lib/doorkeeper/models/application_mixin.rb +60 -0
  31. data/lib/doorkeeper/models/{expirable.rb → concerns/expirable.rb} +6 -5
  32. data/lib/doorkeeper/models/{ownership.rb → concerns/ownership.rb} +7 -7
  33. data/lib/doorkeeper/models/{revocable.rb → concerns/revocable.rb} +1 -1
  34. data/lib/doorkeeper/models/concerns/scopes.rb +17 -0
  35. data/lib/doorkeeper/oauth/authorization/token.rb +6 -6
  36. data/lib/doorkeeper/oauth/client.rb +1 -1
  37. data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -3
  38. data/lib/doorkeeper/oauth/pre_authorization.rb +5 -1
  39. data/lib/doorkeeper/oauth/refresh_token_request.rb +6 -6
  40. data/lib/doorkeeper/oauth/scopes.rb +6 -1
  41. data/lib/doorkeeper/oauth/token.rb +3 -2
  42. data/lib/doorkeeper/orm/active_record/access_grant.rb +7 -0
  43. data/lib/doorkeeper/orm/active_record/access_token.rb +21 -0
  44. data/lib/doorkeeper/{models → orm}/active_record/application.rb +1 -3
  45. data/lib/doorkeeper/orm/active_record.rb +17 -0
  46. data/lib/doorkeeper/{models → orm}/mongo_mapper/access_grant.rb +4 -5
  47. data/lib/doorkeeper/{models → orm}/mongo_mapper/access_token.rb +12 -17
  48. data/lib/doorkeeper/{models → orm}/mongo_mapper/application.rb +3 -4
  49. data/lib/doorkeeper/orm/mongo_mapper.rb +11 -0
  50. data/lib/doorkeeper/{models → orm}/mongoid2/access_grant.rb +5 -3
  51. data/lib/doorkeeper/{models → orm}/mongoid2/access_token.rb +10 -12
  52. data/lib/doorkeeper/{models → orm}/mongoid2/application.rb +3 -0
  53. data/lib/doorkeeper/orm/mongoid2/concerns/scopes.rb +30 -0
  54. data/lib/doorkeeper/orm/mongoid2.rb +11 -0
  55. data/lib/doorkeeper/orm/mongoid3/access_grant.rb +22 -0
  56. data/lib/doorkeeper/orm/mongoid3/access_token.rb +37 -0
  57. data/lib/doorkeeper/{models/mongoid3_4 → orm/mongoid3}/application.rb +3 -0
  58. data/lib/doorkeeper/orm/mongoid3/concerns/scopes.rb +30 -0
  59. data/lib/doorkeeper/orm/mongoid3.rb +11 -0
  60. data/lib/doorkeeper/orm/mongoid4/access_grant.rb +22 -0
  61. data/lib/doorkeeper/orm/mongoid4/access_token.rb +37 -0
  62. data/lib/doorkeeper/orm/mongoid4/application.rb +25 -0
  63. data/lib/doorkeeper/orm/mongoid4/concerns/scopes.rb +17 -0
  64. data/lib/doorkeeper/orm/mongoid4.rb +11 -0
  65. data/lib/doorkeeper/rails/helpers.rb +63 -0
  66. data/lib/doorkeeper/rails/routes.rb +1 -12
  67. data/lib/doorkeeper/request/code.rb +0 -1
  68. data/lib/doorkeeper/request/token.rb +0 -1
  69. data/lib/doorkeeper/server.rb +1 -1
  70. data/lib/doorkeeper/version.rb +1 -1
  71. data/lib/doorkeeper.rb +15 -6
  72. data/lib/generators/doorkeeper/application_owner_generator.rb +4 -1
  73. data/lib/generators/doorkeeper/application_scopes_generator.rb +34 -0
  74. data/lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb +5 -0
  75. data/lib/generators/doorkeeper/templates/initializer.rb +8 -1
  76. data/lib/generators/doorkeeper/templates/migration.rb +1 -0
  77. data/lib/generators/doorkeeper/views_generator.rb +4 -5
  78. data/spec/controllers/applications_controller_spec.rb +7 -7
  79. data/spec/controllers/protected_resources_controller_spec.rb +25 -175
  80. data/spec/controllers/tokens_controller_spec.rb +15 -9
  81. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +2 -2
  82. data/spec/dummy/app/controllers/metal_controller.rb +2 -2
  83. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +2 -2
  84. data/spec/dummy/app/models/user.rb +5 -5
  85. data/spec/dummy/config/application.rb +3 -1
  86. data/spec/dummy/config/boot.rb +4 -1
  87. data/spec/dummy/db/development.sqlite3 +0 -0
  88. data/spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb +5 -0
  89. data/spec/dummy/db/schema.rb +41 -40
  90. data/spec/factories.rb +24 -0
  91. data/spec/lib/config_spec.rb +30 -10
  92. data/spec/lib/models/expirable_spec.rb +1 -1
  93. data/spec/lib/models/revocable_spec.rb +8 -3
  94. data/spec/lib/models/scopes_spec.rb +3 -3
  95. data/spec/lib/oauth/client_spec.rb +1 -1
  96. data/spec/lib/oauth/password_access_token_request_spec.rb +1 -1
  97. data/spec/lib/oauth/pre_authorization_spec.rb +43 -9
  98. data/spec/lib/oauth/token_request_spec.rb +28 -1
  99. data/spec/lib/oauth/token_spec.rb +1 -1
  100. data/spec/models/doorkeeper/application_spec.rb +16 -1
  101. data/spec/requests/applications/applications_request_spec.rb +6 -4
  102. data/spec/requests/flows/implicit_grant_spec.rb +32 -0
  103. data/spec/requests/flows/refresh_token_spec.rb +12 -3
  104. data/spec/spec_helper_integration.rb +8 -2
  105. data/spec/support/shared/controllers_shared_context.rb +2 -2
  106. data/spec/validators/redirect_uri_validator_spec.rb +30 -3
  107. metadata +52 -39
  108. data/lib/doorkeeper/doorkeeper_for.rb +0 -69
  109. data/lib/doorkeeper/helpers/filter.rb +0 -64
  110. data/lib/doorkeeper/models/access_grant.rb +0 -30
  111. data/lib/doorkeeper/models/access_token.rb +0 -106
  112. data/lib/doorkeeper/models/active_record/access_grant.rb +0 -9
  113. data/lib/doorkeeper/models/active_record/access_token.rb +0 -25
  114. data/lib/doorkeeper/models/application.rb +0 -40
  115. data/lib/doorkeeper/models/mongoid/scopes.rb +0 -15
  116. data/lib/doorkeeper/models/mongoid/version.rb +0 -15
  117. data/lib/doorkeeper/models/mongoid3_4/access_grant.rb +0 -27
  118. data/lib/doorkeeper/models/mongoid3_4/access_token.rb +0 -46
  119. data/lib/doorkeeper/models/scopes.rb +0 -21
  120. data/lib/generators/doorkeeper/mongo_mapper/indexes_generator.rb +0 -12
  121. data/script/rails +0 -5
  122. data/script/run_all +0 -14
  123. data/spec/factories/access_grant.rb +0 -9
  124. data/spec/factories/access_token.rb +0 -11
  125. data/spec/factories/application.rb +0 -6
  126. /data/lib/{generators/doorkeeper → doorkeeper/generators/doorkeeper/mongo_mapper}/templates/indexes.rb +0 -0
  127. /data/lib/doorkeeper/models/{accessible.rb → concerns/accessible.rb} +0 -0
@@ -14,6 +14,22 @@ describe Doorkeeper, 'configuration' do
14
14
  end
15
15
  end
16
16
 
17
+ describe 'enable_orm' do
18
+ it 'adds specific error message to NameError exception' do
19
+ expect do
20
+ Doorkeeper.configure { orm 'hibernate' }
21
+ end.to raise_error(NameError, /ORM adapter not found \(hibernate\)/)
22
+ end
23
+
24
+ it 'does not change other exceptions' do
25
+ String.any_instance.stub(:classify) { raise NoMethodError }
26
+
27
+ expect do
28
+ Doorkeeper.configure { orm 'hibernate' }
29
+ end.to raise_error(NoMethodError, 'NoMethodError')
30
+ end
31
+ end
32
+
17
33
  describe 'admin_authenticator' do
18
34
  it 'sets the block that is accessible via authenticate_admin' do
19
35
  block = proc {}
@@ -119,6 +135,20 @@ describe Doorkeeper, 'configuration' do
119
135
  end
120
136
  end
121
137
 
138
+ describe 'force_ssl_in_redirect_uri' do
139
+ it 'is true by default in non-development environments' do
140
+ expect(subject.force_ssl_in_redirect_uri).to be_truthy
141
+ end
142
+
143
+ it 'can change the value' do
144
+ Doorkeeper.configure do
145
+ orm DOORKEEPER_ORM
146
+ force_ssl_in_redirect_uri(false)
147
+ end
148
+ expect(subject.force_ssl_in_redirect_uri).to be_falsey
149
+ end
150
+ end
151
+
122
152
  describe 'access_token_credentials' do
123
153
  it 'has defaults order' do
124
154
  expect(subject.access_token_methods).to eq([:from_bearer_authorization, :from_access_token_param, :from_bearer_param])
@@ -264,16 +294,6 @@ describe Doorkeeper, 'configuration' do
264
294
  end
265
295
  end
266
296
 
267
- describe 'test_redirect_uri' do
268
- it 'can change the native_redirect_uri value' do
269
- Doorkeeper.configure do
270
- orm DOORKEEPER_ORM
271
- test_redirect_uri 'foo'
272
- end
273
- expect(subject.native_redirect_uri).to eq('foo')
274
- end
275
- end
276
-
277
297
  it 'raises an exception when configuration is not set' do
278
298
  old_config = Doorkeeper.configuration
279
299
  Doorkeeper.module_eval do
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'timecop'
3
3
  require 'active_support/time'
4
- require 'doorkeeper/models/expirable'
4
+ require 'doorkeeper/models/concerns/expirable'
5
5
 
6
6
  describe 'Expirable' do
7
7
  subject do
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'active_support/core_ext/object/blank'
3
- require 'doorkeeper/models/revocable'
3
+ require 'doorkeeper/models/concerns/revocable'
4
4
 
5
5
  describe 'Revocable' do
6
6
  subject do
@@ -18,11 +18,16 @@ describe 'Revocable' do
18
18
  end
19
19
 
20
20
  describe :revoked? do
21
- it 'is revoked if :revoked_at is set' do
22
- allow(subject).to receive(:revoked_at).and_return(double)
21
+ it 'is revoked if :revoked_at has passed' do
22
+ allow(subject).to receive(:revoked_at).and_return(DateTime.now - 1000)
23
23
  expect(subject).to be_revoked
24
24
  end
25
25
 
26
+ it 'is not revoked if :revoked_at has not passed' do
27
+ allow(subject).to receive(:revoked_at).and_return(DateTime.now + 1000)
28
+ expect(subject).not_to be_revoked
29
+ end
30
+
26
31
  it 'is not revoked if :revoked_at is not set' do
27
32
  allow(subject).to receive(:revoked_at).and_return(nil)
28
33
  expect(subject).not_to be_revoked
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'active_support/core_ext/module/delegation'
3
3
  require 'active_support/core_ext/object/blank'
4
4
  require 'doorkeeper/oauth/scopes'
5
- require 'doorkeeper/models/scopes'
5
+ require 'doorkeeper/models/concerns/scopes'
6
6
 
7
7
  describe 'Doorkeeper::Models::Scopes' do
8
8
  subject do
@@ -33,11 +33,11 @@ describe 'Doorkeeper::Models::Scopes' do
33
33
 
34
34
  describe :includes_scope? do
35
35
  it 'should return true if at least one scope is included' do
36
- expect(subject.includes_scope?(['public', 'private'])).to be true
36
+ expect(subject.includes_scope?('public', 'private')).to be true
37
37
  end
38
38
 
39
39
  it 'should return false if no scopes are included' do
40
- expect(subject.includes_scope?(['teacher', 'student'])).to be false
40
+ expect(subject.includes_scope?('teacher', 'student')).to be false
41
41
  end
42
42
  end
43
43
  end
@@ -28,7 +28,7 @@ module Doorkeeper::OAuth
28
28
  expect(Client.authenticate(credentials, authenticator)).to be_a(Client)
29
29
  end
30
30
 
31
- it 'retunrs nil if client was not authenticated' do
31
+ it 'returns nil if client was not authenticated' do
32
32
  credentials = Client::Credentials.new('some-uid', 'some-secret')
33
33
  authenticator = double
34
34
  expect(authenticator).to receive(:call).with('some-uid', 'some-secret').and_return(nil)
@@ -36,7 +36,7 @@ module Doorkeeper::OAuth
36
36
  it 'requires the owner' do
37
37
  subject.resource_owner = nil
38
38
  subject.validate
39
- expect(subject.error).to eq(:invalid_resource_owner)
39
+ expect(subject.error).to eq(:invalid_grant)
40
40
  end
41
41
 
42
42
  it 'optionally accepts the client' do
@@ -5,11 +5,19 @@ module Doorkeeper::OAuth
5
5
  let(:server) {
6
6
  server = Doorkeeper.configuration
7
7
  server.stub(:default_scopes) { Scopes.new }
8
- server.stub(:scopes) { Scopes.from_string('public') }
8
+ server.stub(:scopes) { Scopes.from_string('public profile') }
9
9
  server
10
10
  }
11
11
 
12
- let(:client) { double :client, redirect_uri: 'http://tst.com/auth' }
12
+ let(:application) do
13
+ application = double :application
14
+ application.stub(:scopes) { Scopes.from_string('') }
15
+ application
16
+ end
17
+
18
+ let(:client) do
19
+ double :client, redirect_uri: 'http://tst.com/auth', application: application
20
+ end
13
21
 
14
22
  let :attributes do
15
23
  {
@@ -71,9 +79,39 @@ module Doorkeeper::OAuth
71
79
  end
72
80
  end
73
81
 
74
- it 'accepts valid scopes' do
75
- subject.scope = 'public'
76
- expect(subject).to be_authorizable
82
+ context 'client application does not restrict valid scopes' do
83
+ it 'accepts valid scopes' do
84
+ subject.scope = 'public'
85
+ expect(subject).to be_authorizable
86
+ end
87
+
88
+ it 'rejects (globally) non-valid scopes' do
89
+ subject.scope = 'invalid'
90
+ expect(subject).not_to be_authorizable
91
+ end
92
+ end
93
+
94
+ context 'client application restricts valid scopes' do
95
+ let(:application) do
96
+ application = double :application
97
+ application.stub(:scopes) { Scopes.from_string('public nonsense') }
98
+ application
99
+ end
100
+
101
+ it 'accepts valid scopes' do
102
+ subject.scope = 'public'
103
+ expect(subject).to be_authorizable
104
+ end
105
+
106
+ it 'rejects (globally) non-valid scopes' do
107
+ subject.scope = 'invalid'
108
+ expect(subject).not_to be_authorizable
109
+ end
110
+
111
+ it 'rejects (application level) non-valid scopes' do
112
+ subject.scope = 'profile'
113
+ expect(subject).to_not be_authorizable
114
+ end
77
115
  end
78
116
 
79
117
  it 'uses default scopes when none is required' do
@@ -112,9 +150,5 @@ module Doorkeeper::OAuth
112
150
  expect(subject).not_to be_authorizable
113
151
  end
114
152
 
115
- it 'rejects non-valid scopes' do
116
- subject.scope = 'invalid'
117
- expect(subject).not_to be_authorizable
118
- end
119
153
  end
120
154
  end
@@ -8,7 +8,7 @@ module Doorkeeper::OAuth
8
8
  client: double(:application, id: 9990),
9
9
  redirect_uri: 'http://tst.com/cb',
10
10
  state: nil,
11
- scopes: nil,
11
+ scopes: Scopes.from_string('public'),
12
12
  error: nil,
13
13
  authorizable?: true
14
14
  )
@@ -43,5 +43,32 @@ module Doorkeeper::OAuth
43
43
  allow(pre_auth).to receive(:authorizable?).and_return(false)
44
44
  expect(subject.authorize).to be_a(ErrorResponse)
45
45
  end
46
+
47
+ context 'token reuse' do
48
+ it 'creates a new token if there are no matching tokens' do
49
+ Doorkeeper.configuration.stub(:reuse_access_token).and_return(true)
50
+ expect do
51
+ subject.authorize
52
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
53
+ end
54
+
55
+ it 'creates a new token if scopes do not match' do
56
+ Doorkeeper.configuration.stub(:reuse_access_token).and_return(true)
57
+ FactoryGirl.create(:access_token, application_id: pre_auth.client.id,
58
+ resource_owner_id: owner.id, scopes: '')
59
+ expect do
60
+ subject.authorize
61
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
62
+ end
63
+
64
+ it 'skips token creation if there is a matching one' do
65
+ Doorkeeper.configuration.stub(:reuse_access_token).and_return(true)
66
+ FactoryGirl.create(:access_token, application_id: pre_auth.client.id,
67
+ resource_owner_id: owner.id, scopes: 'public')
68
+ expect do
69
+ subject.authorize
70
+ end.to_not change { Doorkeeper::AccessToken.count }
71
+ end
72
+ end
46
73
  end
47
74
  end
@@ -88,7 +88,7 @@ module Doorkeeper
88
88
 
89
89
  it 'calls the finder if token was found' do
90
90
  token = ->(r) { 'token' }
91
- expect(AccessToken).to receive(:authenticate).with('token')
91
+ expect(AccessToken).to receive(:by_token).with('token')
92
92
  Token.authenticate double, token
93
93
  end
94
94
  end
@@ -169,9 +169,24 @@ module Doorkeeper
169
169
  describe :authenticate do
170
170
  it 'finds the application via uid/secret' do
171
171
  app = FactoryGirl.create :application
172
- authenticated = Application.authenticate(app.uid, app.secret)
172
+ authenticated = Application.by_uid_and_secret(app.uid, app.secret)
173
173
  expect(authenticated).to eq(app)
174
174
  end
175
175
  end
176
+
177
+ if Doorkeeper.configuration.orm == :active_record
178
+ describe :scopes do
179
+ it 'fails on missing column with an upgrade notice' do
180
+ app = FactoryGirl.build :application
181
+ no_scopes_app = double(attributes: [])
182
+ allow(Application).to receive(:new).and_return(no_scopes_app)
183
+
184
+ expect { app.scopes }.to raise_error(
185
+ NameError,
186
+ /Missing column: `applications.scopes`/
187
+ )
188
+ end
189
+ end
190
+ end
176
191
  end
177
192
  end
@@ -7,8 +7,10 @@ feature 'Adding applications' do
7
7
  end
8
8
 
9
9
  scenario 'adding a valid app' do
10
- fill_in 'application_name', with: 'My Application'
11
- fill_in 'application_redirect_uri', with: 'http://example.com'
10
+ fill_in 'doorkeeper_application[name]', with: 'My Application'
11
+ fill_in 'doorkeeper_application[redirect_uri]',
12
+ with: 'https://example.com'
13
+
12
14
  click_button 'Submit'
13
15
  i_should_see 'Application created'
14
16
  i_should_see 'My Application'
@@ -55,7 +57,7 @@ feature 'Edit application' do
55
57
  end
56
58
 
57
59
  scenario 'updating a valid app' do
58
- fill_in 'application[name]', with: 'Serious app'
60
+ fill_in 'doorkeeper_application[name]', with: 'Serious app'
59
61
  click_button 'Submit'
60
62
  i_should_see 'Application updated'
61
63
  i_should_see 'Serious app'
@@ -63,7 +65,7 @@ feature 'Edit application' do
63
65
  end
64
66
 
65
67
  scenario 'updating an invalid app' do
66
- fill_in 'application[name]', with: ''
68
+ fill_in 'doorkeeper_application[name]', with: ''
67
69
  click_button 'Submit'
68
70
  i_should_see 'Whoops! Check your form for possible errors'
69
71
  end
@@ -16,4 +16,36 @@ feature 'Implicit Grant Flow' do
16
16
 
17
17
  i_should_be_on_client_callback @client
18
18
  end
19
+
20
+ context 'token reuse' do
21
+ scenario 'should return a new token each request' do
22
+ Doorkeeper.configuration.stub(:reuse_access_token).and_return(false)
23
+
24
+ token = client_is_authorized(@client, @resource_owner)
25
+
26
+ post "/oauth/authorize",
27
+ client_id: @client.uid,
28
+ state: '',
29
+ redirect_uri: @client.redirect_uri,
30
+ response_type: 'token',
31
+ commit: 'Authorize'
32
+
33
+ expect(response.location).not_to include(token.token)
34
+ end
35
+
36
+ scenario 'should return the same token if it is still accessible' do
37
+ Doorkeeper.configuration.stub(:reuse_access_token).and_return(true)
38
+
39
+ token = client_is_authorized(@client, @resource_owner)
40
+
41
+ post "/oauth/authorize",
42
+ client_id: @client.uid,
43
+ state: '',
44
+ redirect_uri: @client.redirect_uri,
45
+ response_type: 'token',
46
+ commit: 'Authorize'
47
+
48
+ expect(response.location).to include(token.token)
49
+ end
50
+ end
19
51
  end
@@ -74,15 +74,24 @@ feature 'Refresh Token Flow' do
74
74
  # enable password auth to simulate other devices
75
75
  config_is_set(:resource_owner_from_credentials) { User.authenticate! params[:username], params[:password] }
76
76
  create_resource_owner
77
+ _another_token = post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
78
+ last_token.update_attribute :created_at, 5.seconds.ago
79
+
77
80
  @token = FactoryGirl.create(:access_token, application: @client, resource_owner_id: @resource_owner.id, use_refresh_token: true)
81
+ @token.update_attribute :expires_in, -100
78
82
  end
79
83
 
80
84
  scenario 'client request a token after creating another token with the same user' do
81
- @token.update_attribute :expires_in, -100
82
- post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
83
85
  post refresh_token_endpoint_url(client: @client, refresh_token: @token.refresh_token)
84
- should_have_json 'refresh_token', Doorkeeper::AccessToken.last.refresh_token
86
+
87
+ should_have_json 'refresh_token', last_token.refresh_token
85
88
  expect(@token.reload).to be_revoked
86
89
  end
90
+
91
+ def last_token
92
+ Doorkeeper::AccessToken.last_authorized_token_for(
93
+ @client.id, @resource_owner.id
94
+ )
95
+ end
87
96
  end
88
97
  end
@@ -1,8 +1,10 @@
1
1
  ENV['RAILS_ENV'] ||= 'test'
2
- DOORKEEPER_ORM = (ENV['orm'] || :active_record).to_sym
3
2
  TABLE_NAME_PREFIX = ENV['table_name_prefix'] || nil
4
3
  TABLE_NAME_SUFFIX = ENV['table_name_suffix'] || nil
5
4
 
5
+ orm = ENV['BUNDLE_GEMFILE'].match(/Gemfile\.(.+)\.rb/)
6
+ DOORKEEPER_ORM = (orm && orm[1] || :active_record).to_sym
7
+
6
8
  $LOAD_PATH.unshift File.dirname(__FILE__)
7
9
 
8
10
  require 'capybara/rspec'
@@ -22,7 +24,11 @@ end
22
24
  Rails.logger.info "====> Rails version: #{Rails.version}"
23
25
  Rails.logger.info "====> Ruby version: #{RUBY_VERSION}"
24
26
 
25
- require "support/orm/#{Doorkeeper.configuration.orm_name}"
27
+ if [:mongoid2, :mongoid3, :mongoid4].include?(DOORKEEPER_ORM)
28
+ require "support/orm/mongoid"
29
+ else
30
+ require "support/orm/#{DOORKEEPER_ORM}"
31
+ end
26
32
 
27
33
  ENGINE_RAILS_ROOT = File.join(File.dirname(__FILE__), '../')
28
34
 
@@ -8,7 +8,7 @@ shared_context 'valid token', token: :valid do
8
8
  end
9
9
 
10
10
  before :each do
11
- allow(Doorkeeper::AccessToken).to receive(:authenticate).with(token_string).and_return(token)
11
+ allow(Doorkeeper::AccessToken).to receive(:by_token).with(token_string).and_return(token)
12
12
  end
13
13
  end
14
14
 
@@ -22,7 +22,7 @@ shared_context 'invalid token', token: :invalid do
22
22
  end
23
23
 
24
24
  before :each do
25
- allow(Doorkeeper::AccessToken).to receive(:authenticate).with(token_string).and_return(token)
25
+ allow(Doorkeeper::AccessToken).to receive(:by_token).with(token_string).and_return(token)
26
26
  end
27
27
  end
28
28
 
@@ -6,7 +6,7 @@ describe RedirectUriValidator do
6
6
  end
7
7
 
8
8
  it 'is valid when the uri is a uri' do
9
- subject.redirect_uri = 'http://example.com/callback'
9
+ subject.redirect_uri = 'https://example.com/callback'
10
10
  expect(subject).to be_valid
11
11
  end
12
12
 
@@ -34,13 +34,40 @@ describe RedirectUriValidator do
34
34
  end
35
35
 
36
36
  it 'is invalid when the uri has a fragment' do
37
- subject.redirect_uri = 'http://example.com/abcd#xyz'
37
+ subject.redirect_uri = 'https://example.com/abcd#xyz'
38
38
  expect(subject).not_to be_valid
39
39
  expect(subject.errors[:redirect_uri].first).to eq('cannot contain a fragment.')
40
40
  end
41
41
 
42
42
  it 'is invalid when the uri has a query parameter' do
43
- subject.redirect_uri = 'http://example.com/abcd?xyz=123'
43
+ subject.redirect_uri = 'https://example.com/abcd?xyz=123'
44
44
  expect(subject).to be_valid
45
45
  end
46
+
47
+ context 'force secured uri' do
48
+ it 'accepts an valid uri' do
49
+ subject.redirect_uri = 'https://example.com/callback'
50
+ expect(subject).to be_valid
51
+ end
52
+
53
+ it 'accepts native redirect uri' do
54
+ subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
55
+ expect(subject).to be_valid
56
+ end
57
+
58
+ it 'accepts a non secured protocol when disabled' do
59
+ subject.redirect_uri = 'http://example.com/callback'
60
+ allow(Doorkeeper.configuration).to receive(
61
+ :force_ssl_in_redirect_uri
62
+ ).and_return(false)
63
+ expect(subject).to be_valid
64
+ end
65
+
66
+ it 'invalidates the uri when the uri does not use a secure protocol' do
67
+ subject.redirect_uri = 'http://example.com/callback'
68
+ expect(subject).not_to be_valid
69
+ error = subject.errors[:redirect_uri].first
70
+ expect(error).to eq('must be an HTTPS/SSL URI.')
71
+ end
72
+ end
46
73
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doorkeeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felipe Elias Philipp
8
- - Piotr Jakubowski
8
+ - Tute Costa
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-17 00:00:00.000000000 Z
12
+ date: 2014-12-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: railties
@@ -87,14 +87,14 @@ dependencies:
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: 4.4.0
90
+ version: 4.5.0
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: 4.4.0
97
+ version: 4.5.0
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: timecop
100
100
  requirement: !ruby/object:Gem::Requirement
@@ -167,8 +167,7 @@ dependencies:
167
167
  version: 0.10.0
168
168
  description: Doorkeeper is an OAuth 2 provider for Rails.
169
169
  email:
170
- - felipe@applicake.com
171
- - piotr.jakubowski@applicake.com
170
+ - tutecosta@gmail.com
172
171
  executables: []
173
172
  extensions: []
174
173
  extra_rdoc_files: []
@@ -178,6 +177,7 @@ files:
178
177
  - ".rspec"
179
178
  - ".travis.yml"
180
179
  - CHANGELOG.md
180
+ - CONTRIBUTING.md
181
181
  - Gemfile
182
182
  - MIT-LICENSE
183
183
  - README.md
@@ -191,7 +191,7 @@ files:
191
191
  - app/controllers/doorkeeper/authorized_applications_controller.rb
192
192
  - app/controllers/doorkeeper/token_info_controller.rb
193
193
  - app/controllers/doorkeeper/tokens_controller.rb
194
- - app/helpers/doorkeeper/form_errors_helper.rb
194
+ - app/helpers/doorkeeper/dashboard_helper.rb
195
195
  - app/validators/redirect_uri_validator.rb
196
196
  - app/views/doorkeeper/applications/_delete_form.html.erb
197
197
  - app/views/doorkeeper/applications/_form.html.erb
@@ -208,35 +208,26 @@ files:
208
208
  - app/views/layouts/doorkeeper/application.html.erb
209
209
  - config/locales/en.yml
210
210
  - doorkeeper.gemspec
211
+ - gemfiles/Gemfile.common.rb
212
+ - gemfiles/Gemfile.mongo_mapper.rb
213
+ - gemfiles/Gemfile.mongoid2.rb
214
+ - gemfiles/Gemfile.mongoid3.rb
215
+ - gemfiles/Gemfile.mongoid4.rb
211
216
  - lib/doorkeeper.rb
212
217
  - lib/doorkeeper/config.rb
213
- - lib/doorkeeper/doorkeeper_for.rb
214
218
  - lib/doorkeeper/engine.rb
215
219
  - lib/doorkeeper/errors.rb
220
+ - lib/doorkeeper/generators/doorkeeper/mongo_mapper/indexes_generator.rb
221
+ - lib/doorkeeper/generators/doorkeeper/mongo_mapper/templates/indexes.rb
216
222
  - lib/doorkeeper/helpers/controller.rb
217
- - lib/doorkeeper/helpers/filter.rb
218
- - lib/doorkeeper/models/access_grant.rb
219
- - lib/doorkeeper/models/access_token.rb
220
- - lib/doorkeeper/models/accessible.rb
221
- - lib/doorkeeper/models/active_record/access_grant.rb
222
- - lib/doorkeeper/models/active_record/access_token.rb
223
- - lib/doorkeeper/models/active_record/application.rb
224
- - lib/doorkeeper/models/application.rb
225
- - lib/doorkeeper/models/expirable.rb
226
- - lib/doorkeeper/models/mongo_mapper/access_grant.rb
227
- - lib/doorkeeper/models/mongo_mapper/access_token.rb
228
- - lib/doorkeeper/models/mongo_mapper/application.rb
229
- - lib/doorkeeper/models/mongoid/scopes.rb
230
- - lib/doorkeeper/models/mongoid/version.rb
231
- - lib/doorkeeper/models/mongoid2/access_grant.rb
232
- - lib/doorkeeper/models/mongoid2/access_token.rb
233
- - lib/doorkeeper/models/mongoid2/application.rb
234
- - lib/doorkeeper/models/mongoid3_4/access_grant.rb
235
- - lib/doorkeeper/models/mongoid3_4/access_token.rb
236
- - lib/doorkeeper/models/mongoid3_4/application.rb
237
- - lib/doorkeeper/models/ownership.rb
238
- - lib/doorkeeper/models/revocable.rb
239
- - lib/doorkeeper/models/scopes.rb
223
+ - lib/doorkeeper/models/access_grant_mixin.rb
224
+ - lib/doorkeeper/models/access_token_mixin.rb
225
+ - lib/doorkeeper/models/application_mixin.rb
226
+ - lib/doorkeeper/models/concerns/accessible.rb
227
+ - lib/doorkeeper/models/concerns/expirable.rb
228
+ - lib/doorkeeper/models/concerns/ownership.rb
229
+ - lib/doorkeeper/models/concerns/revocable.rb
230
+ - lib/doorkeeper/models/concerns/scopes.rb
240
231
  - lib/doorkeeper/oauth/authorization/code.rb
241
232
  - lib/doorkeeper/oauth/authorization/token.rb
242
233
  - lib/doorkeeper/oauth/authorization/uri_builder.rb
@@ -265,6 +256,30 @@ files:
265
256
  - lib/doorkeeper/oauth/token.rb
266
257
  - lib/doorkeeper/oauth/token_request.rb
267
258
  - lib/doorkeeper/oauth/token_response.rb
259
+ - lib/doorkeeper/orm/active_record.rb
260
+ - lib/doorkeeper/orm/active_record/access_grant.rb
261
+ - lib/doorkeeper/orm/active_record/access_token.rb
262
+ - lib/doorkeeper/orm/active_record/application.rb
263
+ - lib/doorkeeper/orm/mongo_mapper.rb
264
+ - lib/doorkeeper/orm/mongo_mapper/access_grant.rb
265
+ - lib/doorkeeper/orm/mongo_mapper/access_token.rb
266
+ - lib/doorkeeper/orm/mongo_mapper/application.rb
267
+ - lib/doorkeeper/orm/mongoid2.rb
268
+ - lib/doorkeeper/orm/mongoid2/access_grant.rb
269
+ - lib/doorkeeper/orm/mongoid2/access_token.rb
270
+ - lib/doorkeeper/orm/mongoid2/application.rb
271
+ - lib/doorkeeper/orm/mongoid2/concerns/scopes.rb
272
+ - lib/doorkeeper/orm/mongoid3.rb
273
+ - lib/doorkeeper/orm/mongoid3/access_grant.rb
274
+ - lib/doorkeeper/orm/mongoid3/access_token.rb
275
+ - lib/doorkeeper/orm/mongoid3/application.rb
276
+ - lib/doorkeeper/orm/mongoid3/concerns/scopes.rb
277
+ - lib/doorkeeper/orm/mongoid4.rb
278
+ - lib/doorkeeper/orm/mongoid4/access_grant.rb
279
+ - lib/doorkeeper/orm/mongoid4/access_token.rb
280
+ - lib/doorkeeper/orm/mongoid4/application.rb
281
+ - lib/doorkeeper/orm/mongoid4/concerns/scopes.rb
282
+ - lib/doorkeeper/rails/helpers.rb
268
283
  - lib/doorkeeper/rails/routes.rb
269
284
  - lib/doorkeeper/rails/routes/mapper.rb
270
285
  - lib/doorkeeper/rails/routes/mapping.rb
@@ -279,17 +294,15 @@ files:
279
294
  - lib/doorkeeper/validations.rb
280
295
  - lib/doorkeeper/version.rb
281
296
  - lib/generators/doorkeeper/application_owner_generator.rb
297
+ - lib/generators/doorkeeper/application_scopes_generator.rb
282
298
  - lib/generators/doorkeeper/install_generator.rb
283
299
  - lib/generators/doorkeeper/migration_generator.rb
284
- - lib/generators/doorkeeper/mongo_mapper/indexes_generator.rb
285
300
  - lib/generators/doorkeeper/templates/README
286
301
  - lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb
287
- - lib/generators/doorkeeper/templates/indexes.rb
302
+ - lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb
288
303
  - lib/generators/doorkeeper/templates/initializer.rb
289
304
  - lib/generators/doorkeeper/templates/migration.rb
290
305
  - lib/generators/doorkeeper/views_generator.rb
291
- - script/rails
292
- - script/run_all
293
306
  - spec/controllers/applications_controller_spec.rb
294
307
  - spec/controllers/authorizations_controller_spec.rb
295
308
  - spec/controllers/protected_resources_controller_spec.rb
@@ -325,19 +338,19 @@ files:
325
338
  - spec/dummy/config/mongoid3.yml
326
339
  - spec/dummy/config/mongoid4.yml
327
340
  - spec/dummy/config/routes.rb
341
+ - spec/dummy/db/development.sqlite3
328
342
  - spec/dummy/db/migrate/20111122132257_create_users.rb
329
343
  - spec/dummy/db/migrate/20120312140401_add_password_to_users.rb
330
344
  - spec/dummy/db/migrate/20130902165751_create_doorkeeper_tables.rb
331
345
  - spec/dummy/db/migrate/20130902175349_add_owner_to_application.rb
346
+ - spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb
332
347
  - spec/dummy/db/schema.rb
333
348
  - spec/dummy/public/404.html
334
349
  - spec/dummy/public/422.html
335
350
  - spec/dummy/public/500.html
336
351
  - spec/dummy/public/favicon.ico
337
352
  - spec/dummy/script/rails
338
- - spec/factories/access_grant.rb
339
- - spec/factories/access_token.rb
340
- - spec/factories/application.rb
353
+ - spec/factories.rb
341
354
  - spec/generators/application_owner_generator_spec.rb
342
355
  - spec/generators/install_generator_spec.rb
343
356
  - spec/generators/migration_generator_spec.rb