doorkeeper 4.2.0 → 5.5.2
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 +1038 -0
- data/README.md +110 -348
- 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 -20
- 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 +112 -35
- data/app/helpers/doorkeeper/dashboard_helper.rb +10 -6
- data/app/views/doorkeeper/applications/_delete_form.html.erb +4 -3
- 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 +7 -1
- data/app/views/doorkeeper/authorized_applications/_delete_form.html.erb +1 -2
- 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 +33 -9
- 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 +545 -143
- data/lib/doorkeeper/engine.rb +11 -5
- data/lib/doorkeeper/errors.rb +37 -10
- 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 +24 -12
- data/lib/doorkeeper/helpers/controller.rb +49 -27
- data/lib/doorkeeper/models/access_grant_mixin.rb +100 -21
- data/lib/doorkeeper/models/access_token_mixin.rb +379 -75
- data/lib/doorkeeper/models/application_mixin.rb +72 -25
- data/lib/doorkeeper/models/concerns/accessible.rb +6 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +20 -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 +12 -18
- 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 +22 -18
- data/lib/doorkeeper/oauth/authorization_code_request.rb +64 -14
- data/lib/doorkeeper/oauth/base_request.rb +66 -0
- data/lib/doorkeeper/oauth/base_response.rb +31 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +23 -10
- data/lib/doorkeeper/oauth/client.rb +10 -12
- 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 +11 -15
- data/lib/doorkeeper/oauth/code_request.rb +8 -12
- data/lib/doorkeeper/oauth/code_response.rb +28 -15
- data/lib/doorkeeper/oauth/error.rb +5 -3
- data/lib/doorkeeper/oauth/error_response.rb +41 -20
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +10 -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 +31 -5
- data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +45 -13
- data/lib/doorkeeper/oauth/pre_authorization.rb +135 -26
- data/lib/doorkeeper/oauth/refresh_token_request.rb +61 -36
- data/lib/doorkeeper/oauth/scopes.rb +26 -12
- data/lib/doorkeeper/oauth/token.rb +25 -23
- data/lib/doorkeeper/oauth/token_introspection.rb +202 -0
- data/lib/doorkeeper/oauth/token_request.rb +8 -21
- 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 -25
- data/lib/doorkeeper/orm/active_record/application.rb +6 -15
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +68 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +59 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +198 -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 -15
- data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +3 -1
- data/lib/doorkeeper/rails/routes/mapping.rb +10 -8
- data/lib/doorkeeper/rails/routes/registry.rb +45 -0
- data/lib/doorkeeper/rails/routes.rb +42 -30
- 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 +12 -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 -19
- 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 -56
- 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/lib/generators/doorkeeper/templates/{add_previous_refresh_token_to_access_tokens.rb → 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 +410 -31
- 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 +132 -286
- data/.gitignore +0 -14
- data/.hound.yml +0 -13
- data/.rspec +0 -1
- data/.travis.yml +0 -20
- data/CONTRIBUTING.md +0 -47
- data/Gemfile +0 -14
- data/NEWS.md +0 -593
- data/RELEASING.md +0 -17
- data/Rakefile +0 -20
- data/app/validators/redirect_uri_validator.rb +0 -34
- data/doorkeeper.gemspec +0 -28
- data/lib/doorkeeper/oauth/client/methods.rb +0 -18
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +0 -45
- data/lib/doorkeeper/oauth/request_concern.rb +0 -48
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +0 -7
- 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 -189
- 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/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -11
- 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 -28
- data/spec/lib/models/expirable_spec.rb +0 -51
- 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 -42
- data/spec/lib/oauth/authorization_code_request_spec.rb +0 -80
- data/spec/lib/oauth/client/credentials_spec.rb +0 -47
- data/spec/lib/oauth/client/methods_spec.rb +0 -54
- 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 -28
- 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 -52
- 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 -72
- data/spec/requests/endpoints/token_spec.rb +0 -64
- data/spec/requests/flows/authorization_code_errors_spec.rb +0 -66
- data/spec/requests/flows/authorization_code_spec.rb +0 -156
- 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 -2
- data/spec/spec_helper_integration.rb +0 -59
- 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 -76
- data/spec/support/helpers/url_helper.rb +0 -55
- data/spec/support/http_method_shim.rb +0 -24
- 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,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'active_support/i18n'
|
3
|
-
require 'doorkeeper/oauth/error'
|
4
|
-
|
5
|
-
module Doorkeeper::OAuth
|
6
|
-
describe Error do
|
7
|
-
subject(:error) { Error.new(:some_error, :some_state) }
|
8
|
-
|
9
|
-
it { expect(subject).to respond_to(:name) }
|
10
|
-
it { expect(subject).to respond_to(:state) }
|
11
|
-
|
12
|
-
describe :description do
|
13
|
-
it 'is translated from translation messages' do
|
14
|
-
expect(I18n).to receive(:translate).with(
|
15
|
-
:some_error,
|
16
|
-
scope: [:doorkeeper, :errors, :messages],
|
17
|
-
default: :server_error
|
18
|
-
)
|
19
|
-
error.description
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'active_model'
|
3
|
-
require 'doorkeeper'
|
4
|
-
require 'doorkeeper/oauth/forbidden_token_response'
|
5
|
-
|
6
|
-
module Doorkeeper::OAuth
|
7
|
-
describe ForbiddenTokenResponse do
|
8
|
-
describe '#name' do
|
9
|
-
it { expect(subject.name).to eq(:invalid_scope) }
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '#status' do
|
13
|
-
it { expect(subject.status).to eq(:forbidden) }
|
14
|
-
end
|
15
|
-
|
16
|
-
describe :from_scopes do
|
17
|
-
it 'should have a list of acceptable scopes' do
|
18
|
-
response = ForbiddenTokenResponse.from_scopes(["public"])
|
19
|
-
expect(response.description).to include('public')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'active_support/core_ext/string'
|
3
|
-
require 'doorkeeper/oauth/helpers/scope_checker'
|
4
|
-
require 'doorkeeper/oauth/scopes'
|
5
|
-
|
6
|
-
module Doorkeeper::OAuth::Helpers
|
7
|
-
describe ScopeChecker, '.valid?' do
|
8
|
-
let(:server_scopes) { Doorkeeper::OAuth::Scopes.new }
|
9
|
-
|
10
|
-
it 'is valid if scope is present' do
|
11
|
-
server_scopes.add :scope
|
12
|
-
expect(ScopeChecker.valid?('scope', server_scopes)).to be_truthy
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'is invalid if includes tabs space' do
|
16
|
-
expect(ScopeChecker.valid?("\tsomething", server_scopes)).to be_falsey
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'is invalid if scope is not present' do
|
20
|
-
expect(ScopeChecker.valid?(nil, server_scopes)).to be_falsey
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'is invalid if scope is blank' do
|
24
|
-
expect(ScopeChecker.valid?(' ', server_scopes)).to be_falsey
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'is invalid if includes return space' do
|
28
|
-
expect(ScopeChecker.valid?("scope\r", server_scopes)).to be_falsey
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'is invalid if includes new lines' do
|
32
|
-
expect(ScopeChecker.valid?("scope\nanother", server_scopes)).to be_falsey
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'is invalid if any scope is not included in server scopes' do
|
36
|
-
expect(ScopeChecker.valid?('scope another', server_scopes)).to be_falsey
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'with application_scopes' do
|
40
|
-
let(:server_scopes) do
|
41
|
-
Doorkeeper::OAuth::Scopes.from_string 'common svr'
|
42
|
-
end
|
43
|
-
let(:application_scopes) do
|
44
|
-
Doorkeeper::OAuth::Scopes.from_string 'app123'
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'is valid if scope is included in the application scope list' do
|
48
|
-
expect(ScopeChecker.valid?(
|
49
|
-
'app123',
|
50
|
-
server_scopes,
|
51
|
-
application_scopes
|
52
|
-
)).to be_truthy
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'is invalid if any scope is not included in the application' do
|
56
|
-
expect(ScopeChecker.valid?(
|
57
|
-
'svr',
|
58
|
-
server_scopes,
|
59
|
-
application_scopes
|
60
|
-
)).to be_falsey
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'doorkeeper/oauth/helpers/unique_token'
|
3
|
-
|
4
|
-
module Doorkeeper::OAuth::Helpers
|
5
|
-
describe UniqueToken do
|
6
|
-
let :generator do
|
7
|
-
->(size) { 'a' * size }
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'is able to customize the generator method' do
|
11
|
-
token = UniqueToken.generate(generator: generator)
|
12
|
-
expect(token).to eq('a' * 32)
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'is able to customize the size of the token' do
|
16
|
-
token = UniqueToken.generate(generator: generator, size: 2)
|
17
|
-
expect(token).to eq('aa')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'uri'
|
3
|
-
require 'doorkeeper/oauth/helpers/uri_checker'
|
4
|
-
|
5
|
-
module Doorkeeper::OAuth::Helpers
|
6
|
-
describe URIChecker do
|
7
|
-
describe '.valid?' do
|
8
|
-
it 'is valid for valid uris' do
|
9
|
-
uri = 'http://app.co'
|
10
|
-
expect(URIChecker.valid?(uri)).to be_truthy
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'is valid if include path param' do
|
14
|
-
uri = 'http://app.co/path'
|
15
|
-
expect(URIChecker.valid?(uri)).to be_truthy
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'is valid if include query param' do
|
19
|
-
uri = 'http://app.co/?query=1'
|
20
|
-
expect(URIChecker.valid?(uri)).to be_truthy
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'is invalid if uri includes fragment' do
|
24
|
-
uri = 'http://app.co/test#fragment'
|
25
|
-
expect(URIChecker.valid?(uri)).to be_falsey
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'is invalid if scheme is missing' do
|
29
|
-
uri = 'app.co'
|
30
|
-
expect(URIChecker.valid?(uri)).to be_falsey
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'is invalid if is a relative uri' do
|
34
|
-
uri = '/abc/123'
|
35
|
-
expect(URIChecker.valid?(uri)).to be_falsey
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'is invalid if is not a url' do
|
39
|
-
uri = 'http://'
|
40
|
-
expect(URIChecker.valid?(uri)).to be_falsey
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe '.matches?' do
|
45
|
-
it 'is true if both url matches' do
|
46
|
-
uri = client_uri = 'http://app.co/aaa'
|
47
|
-
expect(URIChecker.matches?(uri, client_uri)).to be_truthy
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'ignores query parameter on comparsion' do
|
51
|
-
uri = 'http://app.co/?query=hello'
|
52
|
-
client_uri = 'http://app.co'
|
53
|
-
expect(URIChecker.matches?(uri, client_uri)).to be_truthy
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'doesn\'t allow non-matching domains through' do
|
57
|
-
uri = 'http://app.abc/?query=hello'
|
58
|
-
client_uri = 'http://app.co'
|
59
|
-
expect(URIChecker.matches?(uri, client_uri)).to be_falsey
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'doesn\'t allow non-matching domains that don\'t start at the beginning' do
|
63
|
-
uri = 'http://app.co/?query=hello'
|
64
|
-
client_uri = 'http://example.com?app.co=test'
|
65
|
-
expect(URIChecker.matches?(uri, client_uri)).to be_falsey
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
describe '.valid_for_authorization?' do
|
70
|
-
it 'is true if valid and matches' do
|
71
|
-
uri = client_uri = 'http://app.co/aaa'
|
72
|
-
expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_truthy
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'is false if valid and mismatches' do
|
76
|
-
uri = 'http://app.co/aaa'
|
77
|
-
client_uri = 'http://app.co/bbb'
|
78
|
-
expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_falsey
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'is true if valid and included in array' do
|
82
|
-
uri = 'http://app.co/aaa'
|
83
|
-
client_uri = "http://example.com/bbb\nhttp://app.co/aaa"
|
84
|
-
expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_truthy
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'is false if valid and not included in array' do
|
88
|
-
uri = 'http://app.co/aaa'
|
89
|
-
client_uri = "http://example.com/bbb\nhttp://app.co/cc"
|
90
|
-
expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be_falsey
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'is true if valid and matches' do
|
94
|
-
uri = client_uri = 'http://app.co/aaa'
|
95
|
-
expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be true
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'is false if invalid' do
|
99
|
-
uri = client_uri = 'http://app.co/aaa?waffles=abc'
|
100
|
-
expect(URIChecker.valid_for_authorization?(uri, client_uri)).to be false
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'active_model'
|
3
|
-
require 'doorkeeper'
|
4
|
-
require 'doorkeeper/oauth/invalid_token_response'
|
5
|
-
|
6
|
-
module Doorkeeper::OAuth
|
7
|
-
describe InvalidTokenResponse do
|
8
|
-
describe '#name' do
|
9
|
-
it { expect(subject.name).to eq(:invalid_token) }
|
10
|
-
end
|
11
|
-
|
12
|
-
describe '#status' do
|
13
|
-
it { expect(subject.status).to eq(:unauthorized) }
|
14
|
-
end
|
15
|
-
|
16
|
-
describe :from_access_token do
|
17
|
-
it 'revoked' do
|
18
|
-
response = InvalidTokenResponse.from_access_token double(revoked?: true, expired?: true)
|
19
|
-
expect(response.description).to include('revoked')
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'expired' do
|
23
|
-
response = InvalidTokenResponse.from_access_token double(revoked?: false, expired?: true)
|
24
|
-
expect(response.description).to include('expired')
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,90 +0,0 @@
|
|
1
|
-
require 'spec_helper_integration'
|
2
|
-
|
3
|
-
module Doorkeeper::OAuth
|
4
|
-
describe PasswordAccessTokenRequest do
|
5
|
-
let(:server) do
|
6
|
-
double(
|
7
|
-
:server,
|
8
|
-
default_scopes: Doorkeeper::OAuth::Scopes.new,
|
9
|
-
access_token_expires_in: 2.hours,
|
10
|
-
refresh_token_enabled?: false,
|
11
|
-
custom_access_token_expires_in: ->(_app) { nil }
|
12
|
-
)
|
13
|
-
end
|
14
|
-
let(:client) { FactoryGirl.create(:application) }
|
15
|
-
let(:owner) { double :owner, id: 99 }
|
16
|
-
|
17
|
-
subject do
|
18
|
-
PasswordAccessTokenRequest.new(server, client, owner)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'issues a new token for the client' do
|
22
|
-
expect do
|
23
|
-
subject.authorize
|
24
|
-
end.to change { client.reload.access_tokens.count }.by(1)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'issues a new token without a client' do
|
28
|
-
expect do
|
29
|
-
subject.client = nil
|
30
|
-
subject.authorize
|
31
|
-
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'does not issue a new token with an invalid client' do
|
35
|
-
expect do
|
36
|
-
subject.client = nil
|
37
|
-
subject.parameters = { client_id: 'bad_id' }
|
38
|
-
subject.authorize
|
39
|
-
end.to_not change { Doorkeeper::AccessToken.count }
|
40
|
-
|
41
|
-
expect(subject.error).to eq(:invalid_client)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'requires the owner' do
|
45
|
-
subject.resource_owner = nil
|
46
|
-
subject.validate
|
47
|
-
expect(subject.error).to eq(:invalid_grant)
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'optionally accepts the client' do
|
51
|
-
subject.client = nil
|
52
|
-
expect(subject).to be_valid
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'creates token even when there is already one (default)' do
|
56
|
-
FactoryGirl.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
|
57
|
-
expect do
|
58
|
-
subject.authorize
|
59
|
-
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'skips token creation if there is already one' do
|
63
|
-
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
64
|
-
FactoryGirl.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
|
65
|
-
expect do
|
66
|
-
subject.authorize
|
67
|
-
end.to_not change { Doorkeeper::AccessToken.count }
|
68
|
-
end
|
69
|
-
|
70
|
-
describe 'with scopes' do
|
71
|
-
subject do
|
72
|
-
PasswordAccessTokenRequest.new(server, client, owner, scope: 'public')
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'validates the current scope' do
|
76
|
-
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('another'))
|
77
|
-
subject.validate
|
78
|
-
expect(subject.error).to eq(:invalid_scope)
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'creates the token with scopes' do
|
82
|
-
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('public'))
|
83
|
-
expect do
|
84
|
-
subject.authorize
|
85
|
-
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
86
|
-
expect(Doorkeeper::AccessToken.last.scopes).to include('public')
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -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
|