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.
- checksums.yaml +4 -4
- data/.hound.yml +3 -0
- data/.travis.yml +38 -10
- data/CHANGELOG.md +43 -1
- data/CONTRIBUTING.md +35 -0
- data/Gemfile +4 -26
- data/README.md +21 -55
- data/Rakefile +3 -1
- data/app/controllers/doorkeeper/application_controller.rb +2 -2
- data/app/controllers/doorkeeper/applications_controller.rb +4 -5
- data/app/controllers/doorkeeper/authorizations_controller.rb +4 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +2 -2
- data/app/helpers/doorkeeper/{form_errors_helper.rb → dashboard_helper.rb} +5 -1
- data/app/validators/redirect_uri_validator.rb +6 -0
- data/app/views/doorkeeper/applications/_delete_form.html.erb +1 -1
- data/app/views/doorkeeper/applications/_form.html.erb +3 -3
- data/app/views/doorkeeper/applications/index.html.erb +1 -1
- data/config/locales/en.yml +6 -3
- data/doorkeeper.gemspec +3 -3
- data/gemfiles/Gemfile.common.rb +11 -0
- data/gemfiles/Gemfile.mongo_mapper.rb +5 -0
- data/gemfiles/Gemfile.mongoid2.rb +5 -0
- data/gemfiles/Gemfile.mongoid3.rb +4 -0
- data/gemfiles/Gemfile.mongoid4.rb +5 -0
- data/lib/doorkeeper/config.rb +34 -24
- data/lib/doorkeeper/engine.rb +1 -2
- data/lib/doorkeeper/generators/doorkeeper/mongo_mapper/indexes_generator.rb +12 -0
- data/lib/doorkeeper/models/access_grant_mixin.rb +36 -0
- data/lib/doorkeeper/models/access_token_mixin.rb +122 -0
- data/lib/doorkeeper/models/application_mixin.rb +60 -0
- data/lib/doorkeeper/models/{expirable.rb → concerns/expirable.rb} +6 -5
- data/lib/doorkeeper/models/{ownership.rb → concerns/ownership.rb} +7 -7
- data/lib/doorkeeper/models/{revocable.rb → concerns/revocable.rb} +1 -1
- data/lib/doorkeeper/models/concerns/scopes.rb +17 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +6 -6
- data/lib/doorkeeper/oauth/client.rb +1 -1
- data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -3
- data/lib/doorkeeper/oauth/pre_authorization.rb +5 -1
- data/lib/doorkeeper/oauth/refresh_token_request.rb +6 -6
- data/lib/doorkeeper/oauth/scopes.rb +6 -1
- data/lib/doorkeeper/oauth/token.rb +3 -2
- data/lib/doorkeeper/orm/active_record/access_grant.rb +7 -0
- data/lib/doorkeeper/orm/active_record/access_token.rb +21 -0
- data/lib/doorkeeper/{models → orm}/active_record/application.rb +1 -3
- data/lib/doorkeeper/orm/active_record.rb +17 -0
- data/lib/doorkeeper/{models → orm}/mongo_mapper/access_grant.rb +4 -5
- data/lib/doorkeeper/{models → orm}/mongo_mapper/access_token.rb +12 -17
- data/lib/doorkeeper/{models → orm}/mongo_mapper/application.rb +3 -4
- data/lib/doorkeeper/orm/mongo_mapper.rb +11 -0
- data/lib/doorkeeper/{models → orm}/mongoid2/access_grant.rb +5 -3
- data/lib/doorkeeper/{models → orm}/mongoid2/access_token.rb +10 -12
- data/lib/doorkeeper/{models → orm}/mongoid2/application.rb +3 -0
- data/lib/doorkeeper/orm/mongoid2/concerns/scopes.rb +30 -0
- data/lib/doorkeeper/orm/mongoid2.rb +11 -0
- data/lib/doorkeeper/orm/mongoid3/access_grant.rb +22 -0
- data/lib/doorkeeper/orm/mongoid3/access_token.rb +37 -0
- data/lib/doorkeeper/{models/mongoid3_4 → orm/mongoid3}/application.rb +3 -0
- data/lib/doorkeeper/orm/mongoid3/concerns/scopes.rb +30 -0
- data/lib/doorkeeper/orm/mongoid3.rb +11 -0
- data/lib/doorkeeper/orm/mongoid4/access_grant.rb +22 -0
- data/lib/doorkeeper/orm/mongoid4/access_token.rb +37 -0
- data/lib/doorkeeper/orm/mongoid4/application.rb +25 -0
- data/lib/doorkeeper/orm/mongoid4/concerns/scopes.rb +17 -0
- data/lib/doorkeeper/orm/mongoid4.rb +11 -0
- data/lib/doorkeeper/rails/helpers.rb +63 -0
- data/lib/doorkeeper/rails/routes.rb +1 -12
- data/lib/doorkeeper/request/code.rb +0 -1
- data/lib/doorkeeper/request/token.rb +0 -1
- data/lib/doorkeeper/server.rb +1 -1
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +15 -6
- data/lib/generators/doorkeeper/application_owner_generator.rb +4 -1
- data/lib/generators/doorkeeper/application_scopes_generator.rb +34 -0
- data/lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb +5 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +8 -1
- data/lib/generators/doorkeeper/templates/migration.rb +1 -0
- data/lib/generators/doorkeeper/views_generator.rb +4 -5
- data/spec/controllers/applications_controller_spec.rb +7 -7
- data/spec/controllers/protected_resources_controller_spec.rb +25 -175
- data/spec/controllers/tokens_controller_spec.rb +15 -9
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +2 -2
- data/spec/dummy/app/controllers/metal_controller.rb +2 -2
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +2 -2
- data/spec/dummy/app/models/user.rb +5 -5
- data/spec/dummy/config/application.rb +3 -1
- data/spec/dummy/config/boot.rb +4 -1
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb +5 -0
- data/spec/dummy/db/schema.rb +41 -40
- data/spec/factories.rb +24 -0
- data/spec/lib/config_spec.rb +30 -10
- data/spec/lib/models/expirable_spec.rb +1 -1
- data/spec/lib/models/revocable_spec.rb +8 -3
- data/spec/lib/models/scopes_spec.rb +3 -3
- data/spec/lib/oauth/client_spec.rb +1 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +1 -1
- data/spec/lib/oauth/pre_authorization_spec.rb +43 -9
- data/spec/lib/oauth/token_request_spec.rb +28 -1
- data/spec/lib/oauth/token_spec.rb +1 -1
- data/spec/models/doorkeeper/application_spec.rb +16 -1
- data/spec/requests/applications/applications_request_spec.rb +6 -4
- data/spec/requests/flows/implicit_grant_spec.rb +32 -0
- data/spec/requests/flows/refresh_token_spec.rb +12 -3
- data/spec/spec_helper_integration.rb +8 -2
- data/spec/support/shared/controllers_shared_context.rb +2 -2
- data/spec/validators/redirect_uri_validator_spec.rb +30 -3
- metadata +52 -39
- data/lib/doorkeeper/doorkeeper_for.rb +0 -69
- data/lib/doorkeeper/helpers/filter.rb +0 -64
- data/lib/doorkeeper/models/access_grant.rb +0 -30
- data/lib/doorkeeper/models/access_token.rb +0 -106
- data/lib/doorkeeper/models/active_record/access_grant.rb +0 -9
- data/lib/doorkeeper/models/active_record/access_token.rb +0 -25
- data/lib/doorkeeper/models/application.rb +0 -40
- data/lib/doorkeeper/models/mongoid/scopes.rb +0 -15
- data/lib/doorkeeper/models/mongoid/version.rb +0 -15
- data/lib/doorkeeper/models/mongoid3_4/access_grant.rb +0 -27
- data/lib/doorkeeper/models/mongoid3_4/access_token.rb +0 -46
- data/lib/doorkeeper/models/scopes.rb +0 -21
- data/lib/generators/doorkeeper/mongo_mapper/indexes_generator.rb +0 -12
- data/script/rails +0 -5
- data/script/run_all +0 -14
- data/spec/factories/access_grant.rb +0 -9
- data/spec/factories/access_token.rb +0 -11
- data/spec/factories/application.rb +0 -6
- /data/lib/{generators/doorkeeper → doorkeeper/generators/doorkeeper/mongo_mapper}/templates/indexes.rb +0 -0
- /data/lib/doorkeeper/models/{accessible.rb → concerns/accessible.rb} +0 -0
data/spec/lib/config_spec.rb
CHANGED
@@ -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,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
|
22
|
-
allow(subject).to receive(:revoked_at).and_return(
|
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?(
|
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?(
|
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 '
|
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(:
|
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(:
|
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
|
-
|
75
|
-
|
76
|
-
|
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:
|
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(:
|
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.
|
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 '
|
11
|
-
fill_in '
|
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 '
|
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 '
|
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
|
-
|
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
|
-
|
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(:
|
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(:
|
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 = '
|
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 = '
|
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 = '
|
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:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felipe Elias Philipp
|
8
|
-
-
|
8
|
+
- Tute Costa
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-12-
|
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.
|
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.
|
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
|
-
-
|
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/
|
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/
|
218
|
-
- lib/doorkeeper/models/
|
219
|
-
- lib/doorkeeper/models/
|
220
|
-
- lib/doorkeeper/models/accessible.rb
|
221
|
-
- lib/doorkeeper/models/
|
222
|
-
- lib/doorkeeper/models/
|
223
|
-
- lib/doorkeeper/models/
|
224
|
-
- lib/doorkeeper/models/
|
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/
|
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
|
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
|