doorkeeper 4.2.6 → 5.5.4
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 +5 -5
- data/CHANGELOG.md +1049 -0
- data/README.md +110 -353
- data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
- data/app/controllers/doorkeeper/application_controller.rb +6 -7
- data/app/controllers/doorkeeper/application_metal_controller.rb +7 -11
- data/app/controllers/doorkeeper/applications_controller.rb +65 -16
- data/app/controllers/doorkeeper/authorizations_controller.rb +97 -17
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +22 -3
- data/app/controllers/doorkeeper/token_info_controller.rb +16 -4
- data/app/controllers/doorkeeper/tokens_controller.rb +115 -38
- data/app/helpers/doorkeeper/dashboard_helper.rb +10 -6
- data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
- data/app/views/doorkeeper/applications/_form.html.erb +33 -21
- data/app/views/doorkeeper/applications/edit.html.erb +1 -1
- data/app/views/doorkeeper/applications/index.html.erb +18 -6
- data/app/views/doorkeeper/applications/new.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +40 -16
- data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
- data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
- data/app/views/doorkeeper/authorizations/new.html.erb +6 -0
- data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
- data/app/views/layouts/doorkeeper/admin.html.erb +16 -14
- data/config/locales/en.yml +34 -7
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +82 -0
- data/lib/doorkeeper/config/validations.rb +53 -0
- data/lib/doorkeeper/config.rb +514 -167
- data/lib/doorkeeper/engine.rb +11 -5
- data/lib/doorkeeper/errors.rb +25 -16
- data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
- data/lib/doorkeeper/grant_flow/flow.rb +44 -0
- data/lib/doorkeeper/grant_flow/registry.rb +50 -0
- data/lib/doorkeeper/grant_flow.rb +45 -0
- data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
- data/lib/doorkeeper/grape/helpers.rb +23 -12
- data/lib/doorkeeper/helpers/controller.rb +51 -14
- data/lib/doorkeeper/models/access_grant_mixin.rb +94 -27
- data/lib/doorkeeper/models/access_token_mixin.rb +284 -96
- data/lib/doorkeeper/models/application_mixin.rb +58 -27
- data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +12 -6
- data/lib/doorkeeper/models/concerns/orderable.rb +15 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +4 -7
- data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
- data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +3 -27
- data/lib/doorkeeper/models/concerns/scopes.rb +12 -2
- data/lib/doorkeeper/models/concerns/secret_storable.rb +106 -0
- data/lib/doorkeeper/oauth/authorization/code.rb +48 -12
- data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +66 -28
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +7 -5
- data/lib/doorkeeper/oauth/authorization_code_request.rb +63 -10
- data/lib/doorkeeper/oauth/base_request.rb +35 -19
- data/lib/doorkeeper/oauth/base_response.rb +2 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +9 -7
- data/lib/doorkeeper/oauth/client.rb +10 -11
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +47 -4
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +16 -9
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +56 -0
- data/lib/doorkeeper/oauth/client_credentials_request.rb +10 -11
- data/lib/doorkeeper/oauth/code_request.rb +8 -12
- data/lib/doorkeeper/oauth/code_response.rb +27 -15
- data/lib/doorkeeper/oauth/error.rb +5 -3
- data/lib/doorkeeper/oauth/error_response.rb +35 -15
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +11 -3
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +23 -18
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +20 -3
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +53 -3
- data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
- data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
- data/lib/doorkeeper/oauth/invalid_token_response.rb +29 -5
- data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +44 -10
- data/lib/doorkeeper/oauth/pre_authorization.rb +135 -26
- data/lib/doorkeeper/oauth/refresh_token_request.rb +60 -31
- data/lib/doorkeeper/oauth/scopes.rb +26 -12
- data/lib/doorkeeper/oauth/token.rb +13 -9
- data/lib/doorkeeper/oauth/token_introspection.rb +202 -0
- data/lib/doorkeeper/oauth/token_request.rb +8 -20
- data/lib/doorkeeper/oauth/token_response.rb +14 -10
- data/lib/doorkeeper/oauth.rb +13 -0
- data/lib/doorkeeper/orm/active_record/access_grant.rb +6 -4
- data/lib/doorkeeper/orm/active_record/access_token.rb +5 -42
- data/lib/doorkeeper/orm/active_record/application.rb +6 -20
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +69 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +60 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +199 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +33 -0
- data/lib/doorkeeper/orm/active_record.rb +37 -8
- data/lib/doorkeeper/rails/helpers.rb +14 -13
- data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +4 -2
- data/lib/doorkeeper/rails/routes/mapping.rb +9 -7
- data/lib/doorkeeper/rails/routes/registry.rb +45 -0
- data/lib/doorkeeper/rails/routes.rb +41 -28
- data/lib/doorkeeper/rake/db.rake +40 -0
- data/lib/doorkeeper/rake/setup.rake +11 -0
- data/lib/doorkeeper/rake.rb +14 -0
- data/lib/doorkeeper/request/authorization_code.rb +6 -4
- data/lib/doorkeeper/request/client_credentials.rb +3 -3
- data/lib/doorkeeper/request/code.rb +1 -1
- data/lib/doorkeeper/request/password.rb +5 -14
- data/lib/doorkeeper/request/refresh_token.rb +6 -5
- data/lib/doorkeeper/request/strategy.rb +4 -2
- data/lib/doorkeeper/request/token.rb +1 -1
- data/lib/doorkeeper/request.rb +62 -29
- data/lib/doorkeeper/secret_storing/base.rb +64 -0
- data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
- data/lib/doorkeeper/secret_storing/plain.rb +33 -0
- data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
- data/lib/doorkeeper/server.rb +9 -11
- data/lib/doorkeeper/stale_records_cleaner.rb +24 -0
- data/lib/doorkeeper/validations.rb +5 -2
- data/lib/doorkeeper/version.rb +12 -1
- data/lib/doorkeeper.rb +111 -62
- data/lib/generators/doorkeeper/application_owner_generator.rb +28 -13
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +33 -0
- data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
- data/lib/generators/doorkeeper/install_generator.rb +19 -9
- data/lib/generators/doorkeeper/migration_generator.rb +27 -10
- data/lib/generators/doorkeeper/pkce_generator.rb +33 -0
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +31 -19
- data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +9 -0
- data/{spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb → lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb} +3 -1
- data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +8 -0
- data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +412 -33
- data/lib/generators/doorkeeper/templates/migration.rb.erb +88 -0
- data/lib/generators/doorkeeper/views_generator.rb +8 -4
- data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
- metadata +114 -276
- data/.coveralls.yml +0 -1
- data/.gitignore +0 -19
- data/.hound.yml +0 -13
- data/.rspec +0 -1
- data/.travis.yml +0 -26
- data/Appraisals +0 -14
- data/CONTRIBUTING.md +0 -47
- data/Gemfile +0 -10
- data/NEWS.md +0 -606
- data/RELEASING.md +0 -10
- data/Rakefile +0 -20
- data/app/validators/redirect_uri_validator.rb +0 -34
- data/doorkeeper.gemspec +0 -29
- data/gemfiles/rails_4_2.gemfile +0 -11
- data/gemfiles/rails_5_0.gemfile +0 -12
- data/gemfiles/rails_5_1.gemfile +0 -13
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +0 -45
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +0 -7
- data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb +0 -11
- data/lib/generators/doorkeeper/templates/migration.rb +0 -68
- data/spec/controllers/application_metal_controller.rb +0 -10
- data/spec/controllers/applications_controller_spec.rb +0 -58
- data/spec/controllers/authorizations_controller_spec.rb +0 -218
- data/spec/controllers/protected_resources_controller_spec.rb +0 -300
- data/spec/controllers/token_info_controller_spec.rb +0 -52
- data/spec/controllers/tokens_controller_spec.rb +0 -88
- data/spec/dummy/Rakefile +0 -7
- data/spec/dummy/app/controllers/application_controller.rb +0 -3
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -7
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -12
- data/spec/dummy/app/controllers/home_controller.rb +0 -17
- data/spec/dummy/app/controllers/metal_controller.rb +0 -11
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -11
- data/spec/dummy/app/helpers/application_helper.rb +0 -5
- data/spec/dummy/app/models/user.rb +0 -5
- data/spec/dummy/app/views/home/index.html.erb +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/config/application.rb +0 -23
- data/spec/dummy/config/boot.rb +0 -9
- data/spec/dummy/config/database.yml +0 -15
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -29
- data/spec/dummy/config/environments/production.rb +0 -62
- data/spec/dummy/config/environments/test.rb +0 -44
- data/spec/dummy/config/initializers/active_record_belongs_to_required_by_default.rb +0 -6
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/doorkeeper.rb +0 -96
- data/spec/dummy/config/initializers/secret_token.rb +0 -9
- data/spec/dummy/config/initializers/session_store.rb +0 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -52
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -9
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -5
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -60
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -7
- data/spec/dummy/db/schema.rb +0 -67
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -26
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +0 -6
- data/spec/factories.rb +0 -28
- data/spec/generators/application_owner_generator_spec.rb +0 -22
- data/spec/generators/install_generator_spec.rb +0 -31
- data/spec/generators/migration_generator_spec.rb +0 -20
- data/spec/generators/templates/routes.rb +0 -3
- data/spec/generators/views_generator_spec.rb +0 -27
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -24
- data/spec/lib/config_spec.rb +0 -334
- data/spec/lib/doorkeeper_spec.rb +0 -150
- data/spec/lib/models/expirable_spec.rb +0 -50
- data/spec/lib/models/revocable_spec.rb +0 -59
- data/spec/lib/models/scopes_spec.rb +0 -43
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -41
- data/spec/lib/oauth/authorization_code_request_spec.rb +0 -80
- data/spec/lib/oauth/base_request_spec.rb +0 -160
- data/spec/lib/oauth/base_response_spec.rb +0 -45
- data/spec/lib/oauth/client/credentials_spec.rb +0 -88
- data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -44
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -86
- data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -54
- data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
- data/spec/lib/oauth/client_credentials_request_spec.rb +0 -104
- data/spec/lib/oauth/client_spec.rb +0 -39
- data/spec/lib/oauth/code_request_spec.rb +0 -45
- data/spec/lib/oauth/code_response_spec.rb +0 -34
- data/spec/lib/oauth/error_response_spec.rb +0 -61
- data/spec/lib/oauth/error_spec.rb +0 -23
- data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -23
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -64
- data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -20
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -104
- data/spec/lib/oauth/invalid_token_response_spec.rb +0 -56
- data/spec/lib/oauth/password_access_token_request_spec.rb +0 -90
- data/spec/lib/oauth/pre_authorization_spec.rb +0 -155
- data/spec/lib/oauth/refresh_token_request_spec.rb +0 -154
- data/spec/lib/oauth/scopes_spec.rb +0 -122
- data/spec/lib/oauth/token_request_spec.rb +0 -98
- data/spec/lib/oauth/token_response_spec.rb +0 -85
- data/spec/lib/oauth/token_spec.rb +0 -116
- data/spec/lib/request/strategy_spec.rb +0 -53
- data/spec/lib/server_spec.rb +0 -49
- data/spec/models/doorkeeper/access_grant_spec.rb +0 -36
- data/spec/models/doorkeeper/access_token_spec.rb +0 -394
- data/spec/models/doorkeeper/application_spec.rb +0 -179
- data/spec/requests/applications/applications_request_spec.rb +0 -94
- data/spec/requests/applications/authorized_applications_spec.rb +0 -30
- data/spec/requests/endpoints/authorization_spec.rb +0 -71
- data/spec/requests/endpoints/token_spec.rb +0 -64
- data/spec/requests/flows/authorization_code_errors_spec.rb +0 -76
- data/spec/requests/flows/authorization_code_spec.rb +0 -148
- data/spec/requests/flows/client_credentials_spec.rb +0 -58
- data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -32
- data/spec/requests/flows/implicit_grant_spec.rb +0 -61
- data/spec/requests/flows/password_spec.rb +0 -115
- data/spec/requests/flows/refresh_token_spec.rb +0 -174
- data/spec/requests/flows/revoke_token_spec.rb +0 -157
- data/spec/requests/flows/skip_authorization_spec.rb +0 -59
- data/spec/requests/protected_resources/metal_spec.rb +0 -14
- data/spec/requests/protected_resources/private_api_spec.rb +0 -81
- data/spec/routing/custom_controller_routes_spec.rb +0 -71
- data/spec/routing/default_routes_spec.rb +0 -35
- data/spec/routing/scoped_routes_spec.rb +0 -31
- data/spec/spec_helper.rb +0 -4
- data/spec/spec_helper_integration.rb +0 -63
- data/spec/support/dependencies/factory_girl.rb +0 -2
- data/spec/support/helpers/access_token_request_helper.rb +0 -11
- data/spec/support/helpers/authorization_request_helper.rb +0 -41
- data/spec/support/helpers/config_helper.rb +0 -9
- data/spec/support/helpers/model_helper.rb +0 -67
- data/spec/support/helpers/request_spec_helper.rb +0 -84
- data/spec/support/helpers/url_helper.rb +0 -55
- data/spec/support/http_method_shim.rb +0 -38
- data/spec/support/orm/active_record.rb +0 -3
- data/spec/support/shared/controllers_shared_context.rb +0 -69
- data/spec/support/shared/models_shared_examples.rb +0 -52
- data/spec/validators/redirect_uri_validator_spec.rb +0 -78
@@ -1,155 +0,0 @@
|
|
1
|
-
require 'spec_helper_integration'
|
2
|
-
|
3
|
-
module Doorkeeper::OAuth
|
4
|
-
describe PreAuthorization do
|
5
|
-
let(:server) {
|
6
|
-
server = Doorkeeper.configuration
|
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
|
-
server
|
10
|
-
}
|
11
|
-
|
12
|
-
let(:application) do
|
13
|
-
application = double :application
|
14
|
-
allow(application).to receive(:scopes).and_return(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
|
21
|
-
|
22
|
-
let :attributes do
|
23
|
-
{
|
24
|
-
response_type: 'code',
|
25
|
-
redirect_uri: 'http://tst.com/auth',
|
26
|
-
state: 'save-this'
|
27
|
-
}
|
28
|
-
end
|
29
|
-
|
30
|
-
subject do
|
31
|
-
PreAuthorization.new(server, client, attributes)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'is authorizable when request is valid' do
|
35
|
-
expect(subject).to be_authorizable
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'accepts code as response type' do
|
39
|
-
subject.response_type = 'code'
|
40
|
-
expect(subject).to be_authorizable
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'accepts token as response type' do
|
44
|
-
allow(server).to receive(:grant_flows).and_return(['implicit'])
|
45
|
-
subject.response_type = 'token'
|
46
|
-
expect(subject).to be_authorizable
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'when using default grant flows' do
|
50
|
-
it 'accepts "code" as response type' do
|
51
|
-
subject.response_type = 'code'
|
52
|
-
expect(subject).to be_authorizable
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'accepts "token" as response type' do
|
56
|
-
allow(server).to receive(:grant_flows).and_return(['implicit'])
|
57
|
-
subject.response_type = 'token'
|
58
|
-
expect(subject).to be_authorizable
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
context 'when authorization code grant flow is disabled' do
|
63
|
-
before do
|
64
|
-
allow(server).to receive(:grant_flows).and_return(['implicit'])
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'does not accept "code" as response type' do
|
68
|
-
subject.response_type = 'code'
|
69
|
-
expect(subject).not_to be_authorizable
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'when implicit grant flow is disabled' do
|
74
|
-
before do
|
75
|
-
allow(server).to receive(:grant_flows).and_return(['authorization_code'])
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'does not accept "token" as response type' do
|
79
|
-
subject.response_type = 'token'
|
80
|
-
expect(subject).not_to be_authorizable
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
context 'client application does not restrict valid scopes' do
|
85
|
-
it 'accepts valid scopes' do
|
86
|
-
subject.scope = 'public'
|
87
|
-
expect(subject).to be_authorizable
|
88
|
-
end
|
89
|
-
|
90
|
-
it 'rejects (globally) non-valid scopes' do
|
91
|
-
subject.scope = 'invalid'
|
92
|
-
expect(subject).not_to be_authorizable
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
context 'client application restricts valid scopes' do
|
97
|
-
let(:application) do
|
98
|
-
application = double :application
|
99
|
-
allow(application).to receive(:scopes).and_return(Scopes.from_string('public nonsense'))
|
100
|
-
application
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'accepts valid scopes' do
|
104
|
-
subject.scope = 'public'
|
105
|
-
expect(subject).to be_authorizable
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'rejects (globally) non-valid scopes' do
|
109
|
-
subject.scope = 'invalid'
|
110
|
-
expect(subject).not_to be_authorizable
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'rejects (application level) non-valid scopes' do
|
114
|
-
subject.scope = 'profile'
|
115
|
-
expect(subject).to_not be_authorizable
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
it 'uses default scopes when none is required' do
|
120
|
-
allow(server).to receive(:default_scopes).and_return(Scopes.from_string('default'))
|
121
|
-
subject.scope = nil
|
122
|
-
expect(subject.scope).to eq('default')
|
123
|
-
expect(subject.scopes).to eq(Scopes.from_string('default'))
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'accepts test uri' do
|
127
|
-
subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
|
128
|
-
expect(subject).to be_authorizable
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'matches the redirect uri against client\'s one' do
|
132
|
-
subject.redirect_uri = 'http://nothesame.com'
|
133
|
-
expect(subject).not_to be_authorizable
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'stores the state' do
|
137
|
-
expect(subject.state).to eq('save-this')
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'rejects if response type is not allowed' do
|
141
|
-
subject.response_type = 'whops'
|
142
|
-
expect(subject).not_to be_authorizable
|
143
|
-
end
|
144
|
-
|
145
|
-
it 'requires an existing client' do
|
146
|
-
subject.client = nil
|
147
|
-
expect(subject).not_to be_authorizable
|
148
|
-
end
|
149
|
-
|
150
|
-
it 'requires a redirect uri' do
|
151
|
-
subject.redirect_uri = nil
|
152
|
-
expect(subject).not_to be_authorizable
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
@@ -1,154 +0,0 @@
|
|
1
|
-
require 'spec_helper_integration'
|
2
|
-
|
3
|
-
module Doorkeeper::OAuth
|
4
|
-
describe RefreshTokenRequest do
|
5
|
-
before do
|
6
|
-
allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(false)
|
7
|
-
end
|
8
|
-
let(:server) do
|
9
|
-
double :server,
|
10
|
-
access_token_expires_in: 2.minutes,
|
11
|
-
custom_access_token_expires_in: -> (_oauth_client) { nil }
|
12
|
-
end
|
13
|
-
let(:refresh_token) do
|
14
|
-
FactoryGirl.create(:access_token, use_refresh_token: true)
|
15
|
-
end
|
16
|
-
let(:client) { refresh_token.application }
|
17
|
-
let(:credentials) { Client::Credentials.new(client.uid, client.secret) }
|
18
|
-
|
19
|
-
subject { RefreshTokenRequest.new server, refresh_token, credentials }
|
20
|
-
|
21
|
-
it 'issues a new token for the client' do
|
22
|
-
expect { subject.authorize }.to change { client.reload.access_tokens.count }.by(1)
|
23
|
-
expect(client.reload.access_tokens.last.expires_in).to eq(120)
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'issues a new token for the client with custom expires_in' do
|
27
|
-
server = double :server,
|
28
|
-
access_token_expires_in: 2.minutes,
|
29
|
-
custom_access_token_expires_in: ->(_oauth_client) { 1234 }
|
30
|
-
|
31
|
-
allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(false)
|
32
|
-
|
33
|
-
RefreshTokenRequest.new(server, refresh_token, credentials).authorize
|
34
|
-
|
35
|
-
expect(client.reload.access_tokens.last.expires_in).to eq(1234)
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'revokes the previous token' do
|
39
|
-
expect { subject.authorize }.to change { refresh_token.revoked? }.from(false).to(true)
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'requires the refresh token' do
|
43
|
-
subject.refresh_token = nil
|
44
|
-
subject.validate
|
45
|
-
expect(subject.error).to eq(:invalid_request)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'requires credentials to be valid if provided' do
|
49
|
-
subject.client = nil
|
50
|
-
subject.validate
|
51
|
-
expect(subject.error).to eq(:invalid_client)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "requires the token's client and current client to match" do
|
55
|
-
subject.client = FactoryGirl.create(:application)
|
56
|
-
subject.validate
|
57
|
-
expect(subject.error).to eq(:invalid_grant)
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'rejects revoked tokens' do
|
61
|
-
refresh_token.revoke
|
62
|
-
subject.validate
|
63
|
-
expect(subject.error).to eq(:invalid_grant)
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'accepts expired tokens' do
|
67
|
-
refresh_token.expires_in = -1
|
68
|
-
refresh_token.save
|
69
|
-
subject.validate
|
70
|
-
expect(subject).to be_valid
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'refresh tokens expire on access token use' do
|
74
|
-
let(:server) do
|
75
|
-
double :server,
|
76
|
-
access_token_expires_in: 2.minutes,
|
77
|
-
custom_access_token_expires_in: ->(_oauth_client) { 1234 }
|
78
|
-
end
|
79
|
-
|
80
|
-
before do
|
81
|
-
allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(true)
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'issues a new token for the client' do
|
85
|
-
expect { subject.authorize }.to change { client.reload.access_tokens.count }.by(1)
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'does not revoke the previous token' do
|
89
|
-
subject.authorize
|
90
|
-
expect(refresh_token).not_to be_revoked
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'sets the previous refresh token in the new access token' do
|
94
|
-
subject.authorize
|
95
|
-
expect(
|
96
|
-
client.access_tokens.last.previous_refresh_token
|
97
|
-
).to eq(refresh_token.refresh_token)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
context 'clientless access tokens' do
|
102
|
-
let!(:refresh_token) { FactoryGirl.create(:clientless_access_token, use_refresh_token: true) }
|
103
|
-
|
104
|
-
subject { RefreshTokenRequest.new server, refresh_token, nil }
|
105
|
-
|
106
|
-
it 'issues a new token without a client' do
|
107
|
-
expect { subject.authorize }.to change { Doorkeeper::AccessToken.count }.by(1)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context 'with scopes' do
|
112
|
-
let(:refresh_token) do
|
113
|
-
FactoryGirl.create :access_token,
|
114
|
-
use_refresh_token: true,
|
115
|
-
scopes: 'public write'
|
116
|
-
end
|
117
|
-
let(:parameters) { {} }
|
118
|
-
subject { RefreshTokenRequest.new server, refresh_token, credentials, parameters }
|
119
|
-
|
120
|
-
it 'transfers scopes from the old token to the new token' do
|
121
|
-
subject.authorize
|
122
|
-
expect(Doorkeeper::AccessToken.last.scopes).to eq([:public, :write])
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'reduces scopes to the provided scopes' do
|
126
|
-
parameters[:scopes] = 'public'
|
127
|
-
subject.authorize
|
128
|
-
expect(Doorkeeper::AccessToken.last.scopes).to eq([:public])
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'validates that scopes are included in the original access token' do
|
132
|
-
parameters[:scopes] = 'public update'
|
133
|
-
|
134
|
-
subject.validate
|
135
|
-
expect(subject.error).to eq(:invalid_scope)
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'uses params[:scope] in favor of scopes if present (valid)' do
|
139
|
-
parameters[:scopes] = 'public update'
|
140
|
-
parameters[:scope] = 'public'
|
141
|
-
subject.authorize
|
142
|
-
expect(Doorkeeper::AccessToken.last.scopes).to eq([:public])
|
143
|
-
end
|
144
|
-
|
145
|
-
it 'uses params[:scope] in favor of scopes if present (invalid)' do
|
146
|
-
parameters[:scopes] = 'public'
|
147
|
-
parameters[:scope] = 'public update'
|
148
|
-
|
149
|
-
subject.validate
|
150
|
-
expect(subject.error).to eq(:invalid_scope)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
@@ -1,122 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'active_support/core_ext/module/delegation'
|
3
|
-
require 'active_support/core_ext/string'
|
4
|
-
require 'doorkeeper/oauth/scopes'
|
5
|
-
|
6
|
-
module Doorkeeper::OAuth
|
7
|
-
describe Scopes do
|
8
|
-
describe '#add' do
|
9
|
-
it 'allows you to add scopes with symbols' do
|
10
|
-
subject.add :public
|
11
|
-
expect(subject.all).to eq(['public'])
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'allows you to add scopes with strings' do
|
15
|
-
subject.add 'public'
|
16
|
-
expect(subject.all).to eq(['public'])
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'do not add already included scopes' do
|
20
|
-
subject.add :public
|
21
|
-
subject.add :public
|
22
|
-
expect(subject.all).to eq(['public'])
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '#exists' do
|
27
|
-
before do
|
28
|
-
subject.add :public
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'returns true if scope with given name is present' do
|
32
|
-
expect(subject.exists?('public')).to be_truthy
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'returns false if scope with given name does not exist' do
|
36
|
-
expect(subject.exists?('other')).to be_falsey
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'handles symbols' do
|
40
|
-
expect(subject.exists?(:public)).to be_truthy
|
41
|
-
expect(subject.exists?(:other)).to be_falsey
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
describe '.from_string' do
|
46
|
-
let(:string) { 'public write' }
|
47
|
-
|
48
|
-
subject { Scopes.from_string(string) }
|
49
|
-
|
50
|
-
it { expect(subject).to be_a(Scopes) }
|
51
|
-
|
52
|
-
describe '#all' do
|
53
|
-
it 'should be an array of the expected scopes' do
|
54
|
-
scopes_array = subject.all
|
55
|
-
expect(scopes_array.size).to eq(2)
|
56
|
-
expect(scopes_array).to include('public')
|
57
|
-
expect(scopes_array).to include('write')
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe '#+' do
|
63
|
-
it 'can add to another scope object' do
|
64
|
-
scopes = Scopes.from_string('public') + Scopes.from_string('admin')
|
65
|
-
expect(scopes.all).to eq(%w(public admin))
|
66
|
-
end
|
67
|
-
|
68
|
-
it 'does not change the existing object' do
|
69
|
-
origin = Scopes.from_string('public')
|
70
|
-
expect(origin.to_s).to eq('public')
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'raises an error if cannot handle addition' do
|
74
|
-
expect do
|
75
|
-
Scopes.from_string('public') + 'admin'
|
76
|
-
end.to raise_error(NoMethodError)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
describe '#==' do
|
81
|
-
it 'is equal to another set of scopes' do
|
82
|
-
expect(Scopes.from_string('public')).to eq(Scopes.from_string('public'))
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'is equal to another set of scopes with no particular order' do
|
86
|
-
expect(Scopes.from_string('public write')).to eq(Scopes.from_string('write public'))
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'differs from another set of scopes when scopes are not the same' do
|
90
|
-
expect(Scopes.from_string('public write')).not_to eq(Scopes.from_string('write'))
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
describe '#has_scopes?' do
|
95
|
-
subject { Scopes.from_string('public admin') }
|
96
|
-
|
97
|
-
it 'returns true when at least one scope is included' do
|
98
|
-
expect(subject.has_scopes?(Scopes.from_string('public'))).to be_truthy
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'returns true when all scopes are included' do
|
102
|
-
expect(subject.has_scopes?(Scopes.from_string('public admin'))).to be_truthy
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'is true if all scopes are included in any order' do
|
106
|
-
expect(subject.has_scopes?(Scopes.from_string('admin public'))).to be_truthy
|
107
|
-
end
|
108
|
-
|
109
|
-
it 'is false if no scopes are included' do
|
110
|
-
expect(subject.has_scopes?(Scopes.from_string('notexistent'))).to be_falsey
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'returns false when any scope is not included' do
|
114
|
-
expect(subject.has_scopes?(Scopes.from_string('public nope'))).to be_falsey
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'is false if no scopes are included even for existing ones' do
|
118
|
-
expect(subject.has_scopes?(Scopes.from_string('public admin notexistent'))).to be_falsey
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
require 'spec_helper_integration'
|
2
|
-
|
3
|
-
module Doorkeeper::OAuth
|
4
|
-
describe TokenRequest do
|
5
|
-
let :application do
|
6
|
-
scopes = double(all: ['public'])
|
7
|
-
double(:application, id: 9990, scopes: scopes)
|
8
|
-
end
|
9
|
-
let :pre_auth do
|
10
|
-
double(
|
11
|
-
:pre_auth,
|
12
|
-
client: application,
|
13
|
-
redirect_uri: 'http://tst.com/cb',
|
14
|
-
state: nil,
|
15
|
-
scopes: Scopes.from_string('public'),
|
16
|
-
error: nil,
|
17
|
-
authorizable?: true
|
18
|
-
)
|
19
|
-
end
|
20
|
-
|
21
|
-
let :owner do
|
22
|
-
double :owner, id: 7866
|
23
|
-
end
|
24
|
-
|
25
|
-
subject do
|
26
|
-
TokenRequest.new(pre_auth, owner)
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'creates an access token' do
|
30
|
-
expect do
|
31
|
-
subject.authorize
|
32
|
-
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'returns a code response' do
|
36
|
-
expect(subject.authorize).to be_a(CodeResponse)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'does not create token when not authorizable' do
|
40
|
-
allow(pre_auth).to receive(:authorizable?).and_return(false)
|
41
|
-
expect do
|
42
|
-
subject.authorize
|
43
|
-
end.to_not change { Doorkeeper::AccessToken.count }
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'returns a error response' do
|
47
|
-
allow(pre_auth).to receive(:authorizable?).and_return(false)
|
48
|
-
expect(subject.authorize).to be_a(ErrorResponse)
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'with custom expirations' do
|
52
|
-
before do
|
53
|
-
Doorkeeper.configure do
|
54
|
-
orm DOORKEEPER_ORM
|
55
|
-
custom_access_token_expires_in do |_oauth_client|
|
56
|
-
1234
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should use the custom ttl' do
|
62
|
-
subject.authorize
|
63
|
-
token = Doorkeeper::AccessToken.first
|
64
|
-
expect(token.expires_in).to eq(1234)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context 'token reuse' do
|
69
|
-
it 'creates a new token if there are no matching tokens' do
|
70
|
-
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
71
|
-
expect do
|
72
|
-
subject.authorize
|
73
|
-
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'creates a new token if scopes do not match' do
|
77
|
-
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
78
|
-
FactoryGirl.create(:access_token, application_id: pre_auth.client.id,
|
79
|
-
resource_owner_id: owner.id, scopes: '')
|
80
|
-
expect do
|
81
|
-
subject.authorize
|
82
|
-
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'skips token creation if there is a matching one' do
|
86
|
-
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
87
|
-
allow(application.scopes).to receive(:has_scopes?).and_return(true)
|
88
|
-
allow(application.scopes).to receive(:all?).and_return(true)
|
89
|
-
FactoryGirl.create(:access_token, application_id: pre_auth.client.id,
|
90
|
-
resource_owner_id: owner.id, scopes: 'public')
|
91
|
-
|
92
|
-
expect do
|
93
|
-
subject.authorize
|
94
|
-
end.to_not change { Doorkeeper::AccessToken.count }
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'doorkeeper/oauth/token_response'
|
3
|
-
|
4
|
-
module Doorkeeper::OAuth
|
5
|
-
describe TokenResponse do
|
6
|
-
subject { TokenResponse.new(double.as_null_object) }
|
7
|
-
|
8
|
-
it 'includes access token response headers' do
|
9
|
-
headers = subject.headers
|
10
|
-
expect(headers.fetch('Cache-Control')).to eq('no-store')
|
11
|
-
expect(headers.fetch('Pragma')).to eq('no-cache')
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'status is ok' do
|
15
|
-
expect(subject.status).to eq(:ok)
|
16
|
-
end
|
17
|
-
|
18
|
-
describe '.body' do
|
19
|
-
let(:access_token) do
|
20
|
-
double :access_token,
|
21
|
-
token: 'some-token',
|
22
|
-
expires_in: '3600',
|
23
|
-
expires_in_seconds: '300',
|
24
|
-
scopes_string: 'two scopes',
|
25
|
-
refresh_token: 'some-refresh-token',
|
26
|
-
token_type: 'bearer',
|
27
|
-
created_at: 0
|
28
|
-
end
|
29
|
-
|
30
|
-
subject { TokenResponse.new(access_token).body }
|
31
|
-
|
32
|
-
it 'includes :access_token' do
|
33
|
-
expect(subject['access_token']).to eq('some-token')
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'includes :token_type' do
|
37
|
-
expect(subject['token_type']).to eq('bearer')
|
38
|
-
end
|
39
|
-
|
40
|
-
# expires_in_seconds is returned as `expires_in` in order to match
|
41
|
-
# the OAuth spec (section 4.2.2)
|
42
|
-
it 'includes :expires_in' do
|
43
|
-
expect(subject['expires_in']).to eq('300')
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'includes :scope' do
|
47
|
-
expect(subject['scope']).to eq('two scopes')
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'includes :refresh_token' do
|
51
|
-
expect(subject['refresh_token']).to eq('some-refresh-token')
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'includes :created_at' do
|
55
|
-
expect(subject['created_at']).to eq(0)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe '.body filters out empty values' do
|
60
|
-
let(:access_token) do
|
61
|
-
double :access_token,
|
62
|
-
token: 'some-token',
|
63
|
-
expires_in_seconds: '',
|
64
|
-
scopes_string: '',
|
65
|
-
refresh_token: '',
|
66
|
-
token_type: 'bearer',
|
67
|
-
created_at: 0
|
68
|
-
end
|
69
|
-
|
70
|
-
subject { TokenResponse.new(access_token).body }
|
71
|
-
|
72
|
-
it 'includes :expires_in' do
|
73
|
-
expect(subject['expires_in']).to be_nil
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'includes :scope' do
|
77
|
-
expect(subject['scope']).to be_nil
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'includes :refresh_token' do
|
81
|
-
expect(subject['refresh_token']).to be_nil
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|