doorkeeper 5.4.0.rc1 → 5.5.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/CHANGELOG.md +108 -9
- data/README.md +4 -4
- data/app/controllers/doorkeeper/applications_controller.rb +3 -3
- data/app/controllers/doorkeeper/authorizations_controller.rb +16 -5
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
- data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +34 -26
- data/app/views/doorkeeper/applications/_form.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +16 -12
- data/app/views/doorkeeper/authorizations/form_post.html.erb +11 -0
- data/config/locales/en.yml +3 -1
- data/lib/doorkeeper.rb +6 -1
- data/lib/doorkeeper/config.rb +109 -78
- data/lib/doorkeeper/config/abstract_builder.rb +1 -1
- data/lib/doorkeeper/config/option.rb +1 -3
- data/lib/doorkeeper/config/validations.rb +53 -0
- data/lib/doorkeeper/engine.rb +1 -1
- data/lib/doorkeeper/grant_flow.rb +45 -0
- 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/helpers/controller.rb +8 -4
- data/lib/doorkeeper/models/access_grant_mixin.rb +12 -7
- data/lib/doorkeeper/models/access_token_mixin.rb +12 -8
- data/lib/doorkeeper/models/application_mixin.rb +5 -4
- data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
- data/lib/doorkeeper/oauth/authorization/code.rb +5 -1
- data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
- data/lib/doorkeeper/oauth/authorization/token.rb +11 -5
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +1 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +10 -17
- data/lib/doorkeeper/oauth/base_request.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +3 -2
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +1 -0
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +3 -1
- data/lib/doorkeeper/oauth/code_request.rb +2 -2
- data/lib/doorkeeper/oauth/code_response.rb +17 -11
- data/lib/doorkeeper/oauth/error_response.rb +4 -3
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -3
- data/lib/doorkeeper/oauth/password_access_token_request.rb +21 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +37 -11
- data/lib/doorkeeper/oauth/refresh_token_request.rb +13 -0
- data/lib/doorkeeper/oauth/token.rb +4 -5
- data/lib/doorkeeper/oauth/token_introspection.rb +1 -5
- data/lib/doorkeeper/oauth/token_request.rb +1 -1
- data/lib/doorkeeper/orm/active_record.rb +5 -6
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +12 -2
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +10 -2
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +76 -10
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +5 -0
- data/lib/doorkeeper/rails/routes.rb +1 -3
- data/lib/doorkeeper/rake/db.rake +3 -3
- data/lib/doorkeeper/rake/setup.rake +5 -0
- data/lib/doorkeeper/request.rb +49 -12
- data/lib/doorkeeper/request/refresh_token.rb +2 -1
- data/lib/doorkeeper/server.rb +1 -1
- data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
- data/lib/doorkeeper/version.rb +2 -6
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +1 -1
- data/lib/generators/doorkeeper/templates/initializer.rb +9 -7
- data/lib/generators/doorkeeper/templates/migration.rb.erb +12 -5
- metadata +25 -306
- data/Appraisals +0 -26
- data/CODE_OF_CONDUCT.md +0 -46
- data/CONTRIBUTING.md +0 -49
- data/Dangerfile +0 -67
- data/Dockerfile +0 -29
- data/Gemfile +0 -25
- data/NEWS.md +0 -1
- data/RELEASING.md +0 -11
- data/Rakefile +0 -28
- data/SECURITY.md +0 -15
- data/UPGRADE.md +0 -2
- data/bin/console +0 -30
- data/doorkeeper.gemspec +0 -42
- data/gemfiles/rails_5_0.gemfile +0 -19
- data/gemfiles/rails_5_1.gemfile +0 -19
- data/gemfiles/rails_5_2.gemfile +0 -19
- data/gemfiles/rails_6_0.gemfile +0 -19
- data/gemfiles/rails_master.gemfile +0 -19
- data/spec/controllers/application_metal_controller_spec.rb +0 -64
- data/spec/controllers/applications_controller_spec.rb +0 -274
- data/spec/controllers/authorizations_controller_spec.rb +0 -743
- data/spec/controllers/protected_resources_controller_spec.rb +0 -361
- data/spec/controllers/token_info_controller_spec.rb +0 -50
- data/spec/controllers/tokens_controller_spec.rb +0 -499
- data/spec/dummy/Rakefile +0 -9
- data/spec/dummy/app/assets/config/manifest.js +0 -2
- data/spec/dummy/app/controllers/application_controller.rb +0 -5
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
- data/spec/dummy/app/controllers/home_controller.rb +0 -18
- data/spec/dummy/app/controllers/metal_controller.rb +0 -13
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
- data/spec/dummy/app/helpers/application_helper.rb +0 -7
- data/spec/dummy/app/models/user.rb +0 -11
- 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.ru +0 -6
- data/spec/dummy/config/application.rb +0 -51
- data/spec/dummy/config/boot.rb +0 -7
- data/spec/dummy/config/database.yml +0 -15
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -31
- data/spec/dummy/config/environments/production.rb +0 -64
- data/spec/dummy/config/environments/test.rb +0 -45
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
- data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
- data/spec/dummy/config/initializers/secret_token.rb +0 -10
- data/spec/dummy/config/initializers/session_store.rb +0 -10
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
- data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -13
- data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
- data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
- data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
- data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
- data/spec/dummy/db/schema.rb +0 -70
- 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 -9
- data/spec/factories.rb +0 -30
- data/spec/generators/application_owner_generator_spec.rb +0 -28
- data/spec/generators/confidential_applications_generator_spec.rb +0 -29
- data/spec/generators/enable_polymorphic_resource_owner_generator_spec.rb +0 -47
- data/spec/generators/install_generator_spec.rb +0 -36
- data/spec/generators/migration_generator_spec.rb +0 -28
- data/spec/generators/pkce_generator_spec.rb +0 -28
- data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
- data/spec/generators/templates/routes.rb +0 -4
- data/spec/generators/views_generator_spec.rb +0 -29
- data/spec/grape/grape_integration_spec.rb +0 -137
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
- data/spec/lib/config_spec.rb +0 -813
- data/spec/lib/doorkeeper_spec.rb +0 -27
- data/spec/lib/models/expirable_spec.rb +0 -61
- data/spec/lib/models/reusable_spec.rb +0 -40
- data/spec/lib/models/revocable_spec.rb +0 -58
- data/spec/lib/models/scopes_spec.rb +0 -61
- data/spec/lib/models/secret_storable_spec.rb +0 -135
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
- data/spec/lib/oauth/authorization_code_request_spec.rb +0 -180
- data/spec/lib/oauth/base_request_spec.rb +0 -210
- data/spec/lib/oauth/base_response_spec.rb +0 -45
- data/spec/lib/oauth/client/credentials_spec.rb +0 -90
- data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -135
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -110
- data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -57
- data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
- data/spec/lib/oauth/client_credentials_request_spec.rb +0 -108
- data/spec/lib/oauth/client_spec.rb +0 -38
- data/spec/lib/oauth/code_request_spec.rb +0 -46
- data/spec/lib/oauth/code_response_spec.rb +0 -36
- data/spec/lib/oauth/error_response_spec.rb +0 -64
- data/spec/lib/oauth/error_spec.rb +0 -21
- data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
- data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
- data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
- data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
- data/spec/lib/oauth/password_access_token_request_spec.rb +0 -201
- data/spec/lib/oauth/pre_authorization_spec.rb +0 -218
- data/spec/lib/oauth/refresh_token_request_spec.rb +0 -166
- data/spec/lib/oauth/scopes_spec.rb +0 -146
- data/spec/lib/oauth/token_request_spec.rb +0 -164
- data/spec/lib/oauth/token_response_spec.rb +0 -84
- data/spec/lib/oauth/token_spec.rb +0 -156
- data/spec/lib/option_spec.rb +0 -51
- data/spec/lib/request/strategy_spec.rb +0 -54
- data/spec/lib/secret_storing/base_spec.rb +0 -60
- data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
- data/spec/lib/secret_storing/plain_spec.rb +0 -44
- data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
- data/spec/lib/server_spec.rb +0 -49
- data/spec/lib/stale_records_cleaner_spec.rb +0 -102
- data/spec/models/doorkeeper/access_grant_spec.rb +0 -175
- data/spec/models/doorkeeper/access_token_spec.rb +0 -650
- data/spec/models/doorkeeper/application_spec.rb +0 -442
- data/spec/requests/applications/applications_request_spec.rb +0 -259
- data/spec/requests/applications/authorized_applications_spec.rb +0 -32
- data/spec/requests/endpoints/authorization_spec.rb +0 -91
- data/spec/requests/endpoints/token_spec.rb +0 -79
- data/spec/requests/flows/authorization_code_errors_spec.rb +0 -82
- data/spec/requests/flows/authorization_code_spec.rb +0 -530
- data/spec/requests/flows/client_credentials_spec.rb +0 -207
- data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
- data/spec/requests/flows/implicit_grant_spec.rb +0 -91
- data/spec/requests/flows/password_spec.rb +0 -316
- data/spec/requests/flows/refresh_token_spec.rb +0 -241
- data/spec/requests/flows/revoke_token_spec.rb +0 -196
- data/spec/requests/flows/skip_authorization_spec.rb +0 -66
- data/spec/requests/protected_resources/metal_spec.rb +0 -16
- data/spec/requests/protected_resources/private_api_spec.rb +0 -83
- data/spec/routing/custom_controller_routes_spec.rb +0 -133
- data/spec/routing/default_routes_spec.rb +0 -41
- data/spec/routing/scoped_routes_spec.rb +0 -47
- data/spec/spec_helper.rb +0 -54
- data/spec/spec_helper_integration.rb +0 -4
- data/spec/support/dependencies/factory_bot.rb +0 -4
- data/spec/support/doorkeeper_rspec.rb +0 -22
- data/spec/support/helpers/access_token_request_helper.rb +0 -14
- data/spec/support/helpers/authorization_request_helper.rb +0 -43
- data/spec/support/helpers/config_helper.rb +0 -11
- data/spec/support/helpers/model_helper.rb +0 -78
- data/spec/support/helpers/request_spec_helper.rb +0 -110
- data/spec/support/helpers/url_helper.rb +0 -62
- data/spec/support/orm/active_record.rb +0 -5
- data/spec/support/shared/controllers_shared_context.rb +0 -133
- data/spec/support/shared/hashing_shared_context.rb +0 -36
- data/spec/support/shared/models_shared_examples.rb +0 -56
- data/spec/validators/redirect_uri_validator_spec.rb +0 -183
- data/spec/version/version_spec.rb +0 -17
@@ -1,32 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
feature "Authorized applications" do
|
6
|
-
background do
|
7
|
-
@user = User.create!(name: "Joe", password: "sekret")
|
8
|
-
@client = client_exists(name: "Amazing Client App")
|
9
|
-
resource_owner_is_authenticated @user
|
10
|
-
client_is_authorized @client, @user
|
11
|
-
end
|
12
|
-
|
13
|
-
scenario "display user's authorized applications" do
|
14
|
-
visit "/oauth/authorized_applications"
|
15
|
-
i_should_see "Amazing Client App"
|
16
|
-
end
|
17
|
-
|
18
|
-
scenario "do not display other user's authorized applications" do
|
19
|
-
client = client_exists(name: "Another Client App")
|
20
|
-
client_is_authorized client, User.create!(name: "Joe", password: "sekret")
|
21
|
-
visit "/oauth/authorized_applications"
|
22
|
-
i_should_not_see "Another Client App"
|
23
|
-
end
|
24
|
-
|
25
|
-
scenario "user revoke access to application" do
|
26
|
-
visit "/oauth/authorized_applications"
|
27
|
-
i_should_see "Amazing Client App"
|
28
|
-
click_on "Revoke"
|
29
|
-
i_should_see "Application revoked"
|
30
|
-
i_should_not_see "Amazing Client App"
|
31
|
-
end
|
32
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
feature "Authorization endpoint" do
|
6
|
-
background do
|
7
|
-
default_scopes_exist :default
|
8
|
-
config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
|
9
|
-
client_exists(name: "MyApp")
|
10
|
-
end
|
11
|
-
|
12
|
-
scenario "requires resource owner to be authenticated" do
|
13
|
-
visit authorization_endpoint_url(client: @client)
|
14
|
-
i_should_see "Sign in"
|
15
|
-
i_should_be_on "/"
|
16
|
-
end
|
17
|
-
|
18
|
-
context "with authenticated resource owner" do
|
19
|
-
background do
|
20
|
-
create_resource_owner
|
21
|
-
sign_in
|
22
|
-
end
|
23
|
-
|
24
|
-
scenario "displays the authorization form" do
|
25
|
-
visit authorization_endpoint_url(client: @client)
|
26
|
-
i_should_see "Authorize MyApp to use your account?"
|
27
|
-
end
|
28
|
-
|
29
|
-
scenario "displays all requested scopes" do
|
30
|
-
default_scopes_exist :public
|
31
|
-
optional_scopes_exist :write
|
32
|
-
visit authorization_endpoint_url(client: @client, scope: "public write")
|
33
|
-
i_should_see "Access your public data"
|
34
|
-
i_should_see "Update your data"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context "with a invalid request's param" do
|
39
|
-
background do
|
40
|
-
create_resource_owner
|
41
|
-
sign_in
|
42
|
-
end
|
43
|
-
|
44
|
-
context "when missing required param" do
|
45
|
-
scenario "displays invalid_request error when missing client" do
|
46
|
-
visit authorization_endpoint_url(client: nil, response_type: "code")
|
47
|
-
i_should_not_see "Authorize"
|
48
|
-
i_should_see_translated_invalid_request_error_message :missing_param, :client_id
|
49
|
-
end
|
50
|
-
|
51
|
-
scenario "displays invalid_request error when missing response_type param" do
|
52
|
-
visit authorization_endpoint_url(client: @client, response_type: "")
|
53
|
-
i_should_not_see "Authorize"
|
54
|
-
i_should_see_translated_invalid_request_error_message :missing_param, :response_type
|
55
|
-
end
|
56
|
-
|
57
|
-
scenario "displays invalid_request error when missing scope param and authorization server has no default scopes" do
|
58
|
-
config_is_set(:default_scopes, [])
|
59
|
-
visit authorization_endpoint_url(client: @client, response_type: "code", scope: "")
|
60
|
-
i_should_not_see "Authorize"
|
61
|
-
i_should_see_translated_invalid_request_error_message :missing_param, :scope
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
scenario "displays unsupported_response_type error when using a disabled response type" do
|
66
|
-
config_is_set(:grant_flows, ["implicit"])
|
67
|
-
visit authorization_endpoint_url(client: @client, response_type: "code")
|
68
|
-
i_should_not_see "Authorize"
|
69
|
-
i_should_see_translated_error_message :unsupported_response_type
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
context "forgery protection enabled" do
|
74
|
-
background do
|
75
|
-
create_resource_owner
|
76
|
-
sign_in
|
77
|
-
end
|
78
|
-
|
79
|
-
scenario "raises exception on forged requests" do
|
80
|
-
allowing_forgery_protection do
|
81
|
-
expect do
|
82
|
-
page.driver.post authorization_endpoint_url(
|
83
|
-
client_id: @client.uid,
|
84
|
-
redirect_uri: @client.redirect_uri,
|
85
|
-
response_type: "code",
|
86
|
-
)
|
87
|
-
end.to raise_error(ActionController::InvalidAuthenticityToken)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
describe "Token endpoint" do
|
6
|
-
before do
|
7
|
-
client_exists
|
8
|
-
create_resource_owner
|
9
|
-
authorization_code_exists application: @client,
|
10
|
-
scopes: "public",
|
11
|
-
resource_owner_id: @resource_owner.id,
|
12
|
-
resource_owner_type: @resource_owner.class.name
|
13
|
-
end
|
14
|
-
|
15
|
-
it "respond with correct headers" do
|
16
|
-
post token_endpoint_url(code: @authorization.token, client: @client)
|
17
|
-
should_have_header "Pragma", "no-cache"
|
18
|
-
|
19
|
-
# Rails 5.2 changed headers
|
20
|
-
if ::Rails::VERSION::MAJOR >= 5 && ::Rails::VERSION::MINOR >= 2 || ::Rails::VERSION::MAJOR >= 6
|
21
|
-
should_have_header "Cache-Control", "private, no-store"
|
22
|
-
else
|
23
|
-
should_have_header "Cache-Control", "no-store"
|
24
|
-
end
|
25
|
-
|
26
|
-
should_have_header "Content-Type", "application/json; charset=utf-8"
|
27
|
-
end
|
28
|
-
|
29
|
-
it "accepts client credentials with basic auth header" do
|
30
|
-
post token_endpoint_url,
|
31
|
-
params: {
|
32
|
-
code: @authorization.token,
|
33
|
-
redirect_uri: @client.redirect_uri,
|
34
|
-
},
|
35
|
-
headers: { "HTTP_AUTHORIZATION" => basic_auth_header_for_client(@client) }
|
36
|
-
|
37
|
-
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
38
|
-
end
|
39
|
-
|
40
|
-
it "returns null for expires_in when a permanent token is set" do
|
41
|
-
config_is_set(:access_token_expires_in, nil)
|
42
|
-
post token_endpoint_url(code: @authorization.token, client: @client)
|
43
|
-
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
44
|
-
should_not_have_json "expires_in"
|
45
|
-
end
|
46
|
-
|
47
|
-
it "returns unsupported_grant_type for invalid grant_type param" do
|
48
|
-
post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "nothing")
|
49
|
-
|
50
|
-
should_not_have_json "access_token"
|
51
|
-
should_have_json "error", "unsupported_grant_type"
|
52
|
-
should_have_json "error_description", translated_error_message("unsupported_grant_type")
|
53
|
-
end
|
54
|
-
|
55
|
-
it "returns unsupported_grant_type for disabled grant flows" do
|
56
|
-
config_is_set(:grant_flows, ["implicit"])
|
57
|
-
post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "authorization_code")
|
58
|
-
|
59
|
-
should_not_have_json "access_token"
|
60
|
-
should_have_json "error", "unsupported_grant_type"
|
61
|
-
should_have_json "error_description", translated_error_message("unsupported_grant_type")
|
62
|
-
end
|
63
|
-
|
64
|
-
it "returns unsupported_grant_type when refresh_token is not in use" do
|
65
|
-
post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "refresh_token")
|
66
|
-
|
67
|
-
should_not_have_json "access_token"
|
68
|
-
should_have_json "error", "unsupported_grant_type"
|
69
|
-
should_have_json "error_description", translated_error_message("unsupported_grant_type")
|
70
|
-
end
|
71
|
-
|
72
|
-
it "returns invalid_request if grant_type is missing" do
|
73
|
-
post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "")
|
74
|
-
|
75
|
-
should_not_have_json "access_token"
|
76
|
-
should_have_json "error", "invalid_request"
|
77
|
-
should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :grant_type)
|
78
|
-
end
|
79
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
feature "Authorization Code Flow Errors" do
|
6
|
-
let(:client_params) { {} }
|
7
|
-
background do
|
8
|
-
default_scopes_exist :default
|
9
|
-
config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
|
10
|
-
client_exists client_params
|
11
|
-
create_resource_owner
|
12
|
-
sign_in
|
13
|
-
end
|
14
|
-
|
15
|
-
after do
|
16
|
-
access_grant_should_not_exist
|
17
|
-
end
|
18
|
-
|
19
|
-
context "with a client trying to xss resource owner" do
|
20
|
-
let(:client_name) { "<div id='xss'>XSS</div>" }
|
21
|
-
let(:client_params) { { name: client_name } }
|
22
|
-
scenario "resource owner visit authorization endpoint" do
|
23
|
-
visit authorization_endpoint_url(client: @client)
|
24
|
-
expect(page).not_to have_css("#xss")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context "when access was denied" do
|
29
|
-
scenario "redirects with error" do
|
30
|
-
visit authorization_endpoint_url(client: @client)
|
31
|
-
click_on "Deny"
|
32
|
-
|
33
|
-
i_should_be_on_client_callback @client
|
34
|
-
url_should_not_have_param "code"
|
35
|
-
url_should_have_param "error", "access_denied"
|
36
|
-
url_should_have_param "error_description", translated_error_message(:access_denied)
|
37
|
-
end
|
38
|
-
|
39
|
-
scenario "redirects with state parameter" do
|
40
|
-
visit authorization_endpoint_url(client: @client, state: "return-this")
|
41
|
-
click_on "Deny"
|
42
|
-
|
43
|
-
i_should_be_on_client_callback @client
|
44
|
-
url_should_not_have_param "code"
|
45
|
-
url_should_have_param "state", "return-this"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
describe "Authorization Code Flow Errors", "after authorization" do
|
51
|
-
before do
|
52
|
-
client_exists
|
53
|
-
create_resource_owner
|
54
|
-
authorization_code_exists application: @client,
|
55
|
-
resource_owner_id: @resource_owner.id,
|
56
|
-
resource_owner_type: @resource_owner.class.name
|
57
|
-
end
|
58
|
-
|
59
|
-
it "returns :invalid_grant error when posting an already revoked grant code" do
|
60
|
-
# First successful request
|
61
|
-
post token_endpoint_url(code: @authorization.token, client: @client)
|
62
|
-
|
63
|
-
# Second attempt with same token
|
64
|
-
expect do
|
65
|
-
post token_endpoint_url(code: @authorization.token, client: @client)
|
66
|
-
end.to_not(change { Doorkeeper::AccessToken.count })
|
67
|
-
|
68
|
-
should_not_have_json "access_token"
|
69
|
-
should_have_json "error", "invalid_grant"
|
70
|
-
should_have_json "error_description", translated_error_message("invalid_grant")
|
71
|
-
end
|
72
|
-
|
73
|
-
it "returns :invalid_grant error for invalid grant code" do
|
74
|
-
post token_endpoint_url(code: "invalid", client: @client)
|
75
|
-
|
76
|
-
access_token_should_not_exist
|
77
|
-
|
78
|
-
should_not_have_json "access_token"
|
79
|
-
should_have_json "error", "invalid_grant"
|
80
|
-
should_have_json "error_description", translated_error_message("invalid_grant")
|
81
|
-
end
|
82
|
-
end
|
@@ -1,530 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
feature "Authorization Code Flow" do
|
6
|
-
background do
|
7
|
-
default_scopes_exist :default
|
8
|
-
config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
|
9
|
-
client_exists
|
10
|
-
create_resource_owner
|
11
|
-
sign_in
|
12
|
-
end
|
13
|
-
|
14
|
-
scenario "resource owner authorizes the client" do
|
15
|
-
visit authorization_endpoint_url(client: @client)
|
16
|
-
click_on "Authorize"
|
17
|
-
|
18
|
-
access_grant_should_exist_for(@client, @resource_owner)
|
19
|
-
|
20
|
-
i_should_be_on_client_callback(@client)
|
21
|
-
|
22
|
-
url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
|
23
|
-
url_should_not_have_param("state")
|
24
|
-
url_should_not_have_param("error")
|
25
|
-
end
|
26
|
-
|
27
|
-
context "when configured to check application supported grant flow" do
|
28
|
-
before do
|
29
|
-
config_is_set(:allow_grant_flow_for_client, ->(_grant_flow, client) { client.name == "admin" })
|
30
|
-
end
|
31
|
-
|
32
|
-
scenario "forbids the request when doesn't satisfy condition" do
|
33
|
-
@client.update(name: "sample app")
|
34
|
-
|
35
|
-
visit authorization_endpoint_url(client: @client)
|
36
|
-
|
37
|
-
i_should_see_translated_error_message("unauthorized_client")
|
38
|
-
end
|
39
|
-
|
40
|
-
scenario "allows the request when satisfies condition" do
|
41
|
-
@client.update(name: "admin")
|
42
|
-
|
43
|
-
visit authorization_endpoint_url(client: @client)
|
44
|
-
i_should_not_see_translated_error_message("unauthorized_client")
|
45
|
-
click_on "Authorize"
|
46
|
-
|
47
|
-
authorization_code = Doorkeeper::AccessGrant.first.token
|
48
|
-
create_access_token authorization_code, @client
|
49
|
-
|
50
|
-
access_token_should_exist_for(@client, @resource_owner)
|
51
|
-
|
52
|
-
should_not_have_json "error"
|
53
|
-
|
54
|
-
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
55
|
-
should_have_json "token_type", "Bearer"
|
56
|
-
should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
context "with grant hashing enabled" do
|
61
|
-
background do
|
62
|
-
config_is_set(:token_secret_strategy, ::Doorkeeper::SecretStoring::Sha256Hash)
|
63
|
-
end
|
64
|
-
|
65
|
-
def authorize(redirect_url)
|
66
|
-
@client.redirect_uri = redirect_url
|
67
|
-
@client.save!
|
68
|
-
visit authorization_endpoint_url(client: @client)
|
69
|
-
click_on "Authorize"
|
70
|
-
|
71
|
-
access_grant_should_exist_for(@client, @resource_owner)
|
72
|
-
|
73
|
-
code = current_params["code"]
|
74
|
-
expect(code).not_to be_nil
|
75
|
-
|
76
|
-
hashed_code = Doorkeeper::AccessGrant.secret_strategy.transform_secret code
|
77
|
-
expect(hashed_code).to eq Doorkeeper::AccessGrant.first.token
|
78
|
-
|
79
|
-
[code, hashed_code]
|
80
|
-
end
|
81
|
-
|
82
|
-
scenario "using redirect_url urn:ietf:wg:oauth:2.0:oob" do
|
83
|
-
code, hashed_code = authorize("urn:ietf:wg:oauth:2.0:oob")
|
84
|
-
expect(code).not_to eq(hashed_code)
|
85
|
-
i_should_see "Authorization code:"
|
86
|
-
i_should_see code
|
87
|
-
i_should_not_see hashed_code
|
88
|
-
end
|
89
|
-
|
90
|
-
scenario "using redirect_url urn:ietf:wg:oauth:2.0:oob:auto" do
|
91
|
-
code, hashed_code = authorize("urn:ietf:wg:oauth:2.0:oob:auto")
|
92
|
-
expect(code).not_to eq(hashed_code)
|
93
|
-
i_should_see "Authorization code:"
|
94
|
-
i_should_see code
|
95
|
-
i_should_not_see hashed_code
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
scenario "resource owner authorizes using oob url" do
|
100
|
-
@client.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
|
101
|
-
@client.save!
|
102
|
-
visit authorization_endpoint_url(client: @client)
|
103
|
-
click_on "Authorize"
|
104
|
-
|
105
|
-
access_grant_should_exist_for(@client, @resource_owner)
|
106
|
-
|
107
|
-
url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
|
108
|
-
i_should_see "Authorization code:"
|
109
|
-
i_should_see Doorkeeper::AccessGrant.first.token
|
110
|
-
end
|
111
|
-
|
112
|
-
scenario "resource owner authorizes the client with state parameter set" do
|
113
|
-
visit authorization_endpoint_url(client: @client, state: "return-me")
|
114
|
-
click_on "Authorize"
|
115
|
-
url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
|
116
|
-
url_should_have_param("state", "return-me")
|
117
|
-
url_should_not_have_param("code_challenge_method")
|
118
|
-
end
|
119
|
-
|
120
|
-
scenario "resource owner requests an access token without authorization code" do
|
121
|
-
create_access_token "", @client
|
122
|
-
|
123
|
-
access_token_should_not_exist
|
124
|
-
|
125
|
-
expect(Doorkeeper::AccessToken.count).to be_zero
|
126
|
-
|
127
|
-
should_have_json "error", "invalid_request"
|
128
|
-
should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :code)
|
129
|
-
end
|
130
|
-
|
131
|
-
scenario "resource owner requests an access token with authorization code" do
|
132
|
-
visit authorization_endpoint_url(client: @client)
|
133
|
-
click_on "Authorize"
|
134
|
-
|
135
|
-
authorization_code = Doorkeeper::AccessGrant.first.token
|
136
|
-
create_access_token authorization_code, @client
|
137
|
-
|
138
|
-
access_token_should_exist_for(@client, @resource_owner)
|
139
|
-
|
140
|
-
should_not_have_json "error"
|
141
|
-
|
142
|
-
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
143
|
-
should_have_json "token_type", "Bearer"
|
144
|
-
should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
|
145
|
-
end
|
146
|
-
|
147
|
-
scenario "resource owner requests an access token with authorization code but without secret" do
|
148
|
-
visit authorization_endpoint_url(client: @client)
|
149
|
-
click_on "Authorize"
|
150
|
-
|
151
|
-
authorization_code = Doorkeeper::AccessGrant.first.token
|
152
|
-
page.driver.post token_endpoint_url(
|
153
|
-
code: authorization_code, client_id: @client.uid,
|
154
|
-
redirect_uri: @client.redirect_uri,
|
155
|
-
)
|
156
|
-
|
157
|
-
expect(Doorkeeper::AccessToken.count).to be_zero
|
158
|
-
|
159
|
-
should_have_json "error", "invalid_client"
|
160
|
-
should_have_json "error_description", translated_error_message(:invalid_client)
|
161
|
-
end
|
162
|
-
|
163
|
-
scenario "resource owner requests an access token with authorization code but without client id" do
|
164
|
-
visit authorization_endpoint_url(client: @client)
|
165
|
-
click_on "Authorize"
|
166
|
-
|
167
|
-
authorization_code = Doorkeeper::AccessGrant.first.token
|
168
|
-
page.driver.post token_endpoint_url(
|
169
|
-
code: authorization_code, client_secret: @client.secret,
|
170
|
-
redirect_uri: @client.redirect_uri,
|
171
|
-
)
|
172
|
-
|
173
|
-
expect(Doorkeeper::AccessToken.count).to be_zero
|
174
|
-
|
175
|
-
should_have_json "error", "invalid_client"
|
176
|
-
should_have_json "error_description", translated_error_message(:invalid_client)
|
177
|
-
end
|
178
|
-
|
179
|
-
scenario "silently authorizes if matching token exists" do
|
180
|
-
default_scopes_exist :public, :write
|
181
|
-
|
182
|
-
access_token_exists application: @client,
|
183
|
-
expires_in: -100, # even expired token
|
184
|
-
resource_owner_id: @resource_owner.id,
|
185
|
-
resource_owner_type: @resource_owner.class.name,
|
186
|
-
scopes: "public write"
|
187
|
-
|
188
|
-
visit authorization_endpoint_url(client: @client, scope: "public write")
|
189
|
-
|
190
|
-
response_status_should_be 200
|
191
|
-
i_should_not_see "Authorize"
|
192
|
-
end
|
193
|
-
|
194
|
-
context "with PKCE" do
|
195
|
-
context "plain" do
|
196
|
-
let(:code_challenge) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
|
197
|
-
let(:code_verifier) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
|
198
|
-
|
199
|
-
scenario "resource owner authorizes the client with code_challenge parameter set" do
|
200
|
-
visit authorization_endpoint_url(
|
201
|
-
client: @client,
|
202
|
-
code_challenge: code_challenge,
|
203
|
-
code_challenge_method: "plain",
|
204
|
-
)
|
205
|
-
click_on "Authorize"
|
206
|
-
|
207
|
-
url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
|
208
|
-
url_should_not_have_param("code_challenge_method")
|
209
|
-
url_should_not_have_param("code_challenge")
|
210
|
-
end
|
211
|
-
|
212
|
-
scenario "mobile app requests an access token with authorization code but not pkce token" do
|
213
|
-
visit authorization_endpoint_url(client: @client)
|
214
|
-
click_on "Authorize"
|
215
|
-
|
216
|
-
authorization_code = current_params["code"]
|
217
|
-
create_access_token authorization_code, @client, code_verifier
|
218
|
-
|
219
|
-
should_have_json "error", "invalid_grant"
|
220
|
-
should_have_json "error_description", translated_error_message(:invalid_grant)
|
221
|
-
end
|
222
|
-
|
223
|
-
scenario "mobile app requests an access token with authorization code and plain code challenge method" do
|
224
|
-
visit authorization_endpoint_url(
|
225
|
-
client: @client,
|
226
|
-
code_challenge: code_challenge,
|
227
|
-
code_challenge_method: "plain",
|
228
|
-
)
|
229
|
-
click_on "Authorize"
|
230
|
-
|
231
|
-
authorization_code = current_params["code"]
|
232
|
-
create_access_token authorization_code, @client, code_verifier
|
233
|
-
|
234
|
-
access_token_should_exist_for(@client, @resource_owner)
|
235
|
-
|
236
|
-
should_not_have_json "error"
|
237
|
-
|
238
|
-
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
239
|
-
should_have_json "token_type", "Bearer"
|
240
|
-
should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
|
241
|
-
end
|
242
|
-
|
243
|
-
scenario "mobile app requests an access token with authorization code but without code_verifier" do
|
244
|
-
visit authorization_endpoint_url(
|
245
|
-
client: @client,
|
246
|
-
code_challenge: code_challenge,
|
247
|
-
code_challenge_method: "plain",
|
248
|
-
)
|
249
|
-
click_on "Authorize"
|
250
|
-
|
251
|
-
authorization_code = current_params["code"]
|
252
|
-
create_access_token authorization_code, @client, nil
|
253
|
-
|
254
|
-
should_not_have_json "access_token"
|
255
|
-
should_have_json "error", "invalid_request"
|
256
|
-
should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :code_verifier)
|
257
|
-
end
|
258
|
-
|
259
|
-
scenario "mobile app requests an access token with authorization code with wrong code_verifier" do
|
260
|
-
visit authorization_endpoint_url(
|
261
|
-
client: @client,
|
262
|
-
code_challenge: code_challenge,
|
263
|
-
code_challenge_method: "plain",
|
264
|
-
)
|
265
|
-
click_on "Authorize"
|
266
|
-
|
267
|
-
authorization_code = current_params["code"]
|
268
|
-
create_access_token authorization_code, @client, "wrong_code_verifier"
|
269
|
-
|
270
|
-
should_not_have_json "access_token"
|
271
|
-
should_have_json "error", "invalid_grant"
|
272
|
-
should_have_json "error_description", translated_error_message(:invalid_grant)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
context "s256" do
|
277
|
-
let(:code_challenge) { "Oz733NtQ0rJP8b04fgZMJMwprn6Iw8sMCT_9bR1q4tA" }
|
278
|
-
let(:code_verifier) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
|
279
|
-
|
280
|
-
scenario "resource owner authorizes the client with code_challenge parameter set" do
|
281
|
-
visit authorization_endpoint_url(
|
282
|
-
client: @client,
|
283
|
-
code_challenge: code_challenge,
|
284
|
-
code_challenge_method: "S256",
|
285
|
-
)
|
286
|
-
click_on "Authorize"
|
287
|
-
|
288
|
-
url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
|
289
|
-
url_should_not_have_param("code_challenge_method")
|
290
|
-
url_should_not_have_param("code_challenge")
|
291
|
-
end
|
292
|
-
|
293
|
-
scenario "mobile app requests an access token with authorization code and S256 code challenge method" do
|
294
|
-
visit authorization_endpoint_url(
|
295
|
-
client: @client,
|
296
|
-
code_challenge: code_challenge,
|
297
|
-
code_challenge_method: "S256",
|
298
|
-
)
|
299
|
-
click_on "Authorize"
|
300
|
-
|
301
|
-
authorization_code = current_params["code"]
|
302
|
-
create_access_token authorization_code, @client, code_verifier
|
303
|
-
|
304
|
-
access_token_should_exist_for(@client, @resource_owner)
|
305
|
-
|
306
|
-
should_not_have_json "error"
|
307
|
-
|
308
|
-
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
309
|
-
should_have_json "token_type", "Bearer"
|
310
|
-
should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
|
311
|
-
end
|
312
|
-
|
313
|
-
scenario "mobile app requests an access token with authorization code and without secret" do
|
314
|
-
visit authorization_endpoint_url(
|
315
|
-
client: @client,
|
316
|
-
code_challenge: code_challenge,
|
317
|
-
code_challenge_method: "S256",
|
318
|
-
)
|
319
|
-
click_on "Authorize"
|
320
|
-
|
321
|
-
authorization_code = current_params["code"]
|
322
|
-
page.driver.post token_endpoint_url(
|
323
|
-
code: authorization_code,
|
324
|
-
client_id: @client.uid,
|
325
|
-
redirect_uri: @client.redirect_uri,
|
326
|
-
code_verifier: code_verifier,
|
327
|
-
)
|
328
|
-
should_not_have_json "access_token"
|
329
|
-
should_have_json "error", "invalid_client"
|
330
|
-
should_have_json "error_description", translated_error_message(:invalid_client)
|
331
|
-
end
|
332
|
-
|
333
|
-
scenario "mobile app requests an access token with authorization code and without secret but is marked as not confidential" do
|
334
|
-
@client.update_attribute :confidential, false
|
335
|
-
visit authorization_endpoint_url(client: @client, code_challenge: code_challenge, code_challenge_method: "S256")
|
336
|
-
click_on "Authorize"
|
337
|
-
|
338
|
-
authorization_code = current_params["code"]
|
339
|
-
page.driver.post token_endpoint_url(
|
340
|
-
code: authorization_code,
|
341
|
-
client_id: @client.uid,
|
342
|
-
redirect_uri: @client.redirect_uri,
|
343
|
-
code_verifier: code_verifier,
|
344
|
-
)
|
345
|
-
should_not_have_json "error"
|
346
|
-
|
347
|
-
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
348
|
-
should_have_json "token_type", "Bearer"
|
349
|
-
should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
|
350
|
-
end
|
351
|
-
|
352
|
-
scenario "mobile app requests an access token with authorization code but no code verifier" do
|
353
|
-
visit authorization_endpoint_url(
|
354
|
-
client: @client,
|
355
|
-
code_challenge: code_challenge,
|
356
|
-
code_challenge_method: "S256",
|
357
|
-
)
|
358
|
-
click_on "Authorize"
|
359
|
-
|
360
|
-
authorization_code = current_params["code"]
|
361
|
-
create_access_token authorization_code, @client
|
362
|
-
|
363
|
-
should_not_have_json "access_token"
|
364
|
-
should_have_json "error", "invalid_request"
|
365
|
-
should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :code_verifier)
|
366
|
-
end
|
367
|
-
|
368
|
-
scenario "mobile app requests an access token with authorization code with wrong verifier" do
|
369
|
-
visit authorization_endpoint_url(
|
370
|
-
client: @client,
|
371
|
-
code_challenge: code_challenge,
|
372
|
-
code_challenge_method: "S256",
|
373
|
-
)
|
374
|
-
click_on "Authorize"
|
375
|
-
|
376
|
-
authorization_code = current_params["code"]
|
377
|
-
create_access_token authorization_code, @client, "incorrect-code-verifier"
|
378
|
-
|
379
|
-
should_not_have_json "access_token"
|
380
|
-
should_have_json "error", "invalid_grant"
|
381
|
-
should_have_json "error_description", translated_error_message(:invalid_grant)
|
382
|
-
end
|
383
|
-
|
384
|
-
scenario "code_challenge_mehthod in token request is totally ignored" do
|
385
|
-
visit authorization_endpoint_url(
|
386
|
-
client: @client,
|
387
|
-
code_challenge: code_challenge,
|
388
|
-
code_challenge_method: "S256",
|
389
|
-
)
|
390
|
-
click_on "Authorize"
|
391
|
-
|
392
|
-
authorization_code = current_params["code"]
|
393
|
-
page.driver.post token_endpoint_url(
|
394
|
-
code: authorization_code,
|
395
|
-
client: @client,
|
396
|
-
code_verifier: code_challenge,
|
397
|
-
code_challenge_method: "plain",
|
398
|
-
)
|
399
|
-
|
400
|
-
should_not_have_json "access_token"
|
401
|
-
should_have_json "error", "invalid_grant"
|
402
|
-
should_have_json "error_description", translated_error_message(:invalid_grant)
|
403
|
-
end
|
404
|
-
|
405
|
-
scenario "expects to set code_challenge_method explicitely without fallback" do
|
406
|
-
visit authorization_endpoint_url(client: @client, code_challenge: code_challenge)
|
407
|
-
expect(page).to have_content("The code challenge method must be plain or S256.")
|
408
|
-
end
|
409
|
-
end
|
410
|
-
end
|
411
|
-
|
412
|
-
context "when application scopes are present and no scope is passed" do
|
413
|
-
background do
|
414
|
-
@client.update(scopes: "public write read default")
|
415
|
-
end
|
416
|
-
|
417
|
-
scenario "scope is invalid because default scope is different from application scope" do
|
418
|
-
default_scopes_exist :admin
|
419
|
-
visit authorization_endpoint_url(client: @client)
|
420
|
-
response_status_should_be 200
|
421
|
-
i_should_not_see "Authorize"
|
422
|
-
i_should_see_translated_error_message :invalid_scope
|
423
|
-
end
|
424
|
-
|
425
|
-
scenario "access grant have scopes which are common in application scopees and default scopes" do
|
426
|
-
default_scopes_exist :public, :write
|
427
|
-
visit authorization_endpoint_url(client: @client)
|
428
|
-
click_on "Authorize"
|
429
|
-
access_grant_should_exist_for(@client, @resource_owner)
|
430
|
-
access_grant_should_have_scopes :public, :write
|
431
|
-
end
|
432
|
-
end
|
433
|
-
|
434
|
-
context "with scopes" do
|
435
|
-
background do
|
436
|
-
default_scopes_exist :public
|
437
|
-
optional_scopes_exist :write
|
438
|
-
end
|
439
|
-
|
440
|
-
scenario "resource owner authorizes the client with default scopes" do
|
441
|
-
visit authorization_endpoint_url(client: @client)
|
442
|
-
click_on "Authorize"
|
443
|
-
access_grant_should_exist_for(@client, @resource_owner)
|
444
|
-
access_grant_should_have_scopes :public
|
445
|
-
end
|
446
|
-
|
447
|
-
scenario "resource owner authorizes the client with required scopes" do
|
448
|
-
visit authorization_endpoint_url(client: @client, scope: "public write")
|
449
|
-
click_on "Authorize"
|
450
|
-
access_grant_should_have_scopes :public, :write
|
451
|
-
end
|
452
|
-
|
453
|
-
scenario "resource owner authorizes the client with required scopes (without defaults)" do
|
454
|
-
visit authorization_endpoint_url(client: @client, scope: "write")
|
455
|
-
click_on "Authorize"
|
456
|
-
access_grant_should_have_scopes :write
|
457
|
-
end
|
458
|
-
|
459
|
-
scenario "new access token matches required scopes" do
|
460
|
-
visit authorization_endpoint_url(client: @client, scope: "public write")
|
461
|
-
click_on "Authorize"
|
462
|
-
|
463
|
-
authorization_code = Doorkeeper::AccessGrant.first.token
|
464
|
-
create_access_token authorization_code, @client
|
465
|
-
|
466
|
-
access_token_should_exist_for(@client, @resource_owner)
|
467
|
-
access_token_should_have_scopes :public, :write
|
468
|
-
end
|
469
|
-
|
470
|
-
scenario "returns new token if scopes have changed" do
|
471
|
-
client_is_authorized(@client, @resource_owner, scopes: "public write")
|
472
|
-
visit authorization_endpoint_url(client: @client, scope: "public")
|
473
|
-
click_on "Authorize"
|
474
|
-
|
475
|
-
authorization_code = Doorkeeper::AccessGrant.first.token
|
476
|
-
create_access_token authorization_code, @client
|
477
|
-
|
478
|
-
expect(Doorkeeper::AccessToken.count).to be(2)
|
479
|
-
|
480
|
-
should_have_json "access_token", Doorkeeper::AccessToken.last.token
|
481
|
-
end
|
482
|
-
|
483
|
-
scenario "resource owner authorizes the client with extra scopes" do
|
484
|
-
client_is_authorized(@client, @resource_owner, scopes: "public")
|
485
|
-
visit authorization_endpoint_url(client: @client, scope: "public write")
|
486
|
-
click_on "Authorize"
|
487
|
-
|
488
|
-
authorization_code = Doorkeeper::AccessGrant.first.token
|
489
|
-
create_access_token authorization_code, @client
|
490
|
-
|
491
|
-
expect(Doorkeeper::AccessToken.count).to be(2)
|
492
|
-
|
493
|
-
should_have_json "access_token", Doorkeeper::AccessToken.last.token
|
494
|
-
access_token_should_have_scopes :public, :write
|
495
|
-
end
|
496
|
-
end
|
497
|
-
end
|
498
|
-
|
499
|
-
describe "Authorization Code Flow" do
|
500
|
-
before do
|
501
|
-
Doorkeeper.configure do
|
502
|
-
orm DOORKEEPER_ORM
|
503
|
-
use_refresh_token
|
504
|
-
end
|
505
|
-
|
506
|
-
client_exists
|
507
|
-
end
|
508
|
-
|
509
|
-
context "issuing a refresh token" do
|
510
|
-
let(:resource_owner) { FactoryBot.create(:resource_owner) }
|
511
|
-
|
512
|
-
before do
|
513
|
-
authorization_code_exists application: @client,
|
514
|
-
resource_owner_id: resource_owner.id,
|
515
|
-
resource_owner_type: resource_owner.class.name
|
516
|
-
end
|
517
|
-
|
518
|
-
it "second of simultaneous client requests get an error for revoked acccess token" do
|
519
|
-
authorization_code = Doorkeeper::AccessGrant.first.token
|
520
|
-
allow_any_instance_of(Doorkeeper::AccessGrant)
|
521
|
-
.to receive(:revoked?).and_return(false, true)
|
522
|
-
|
523
|
-
post token_endpoint_url(code: authorization_code, client: @client)
|
524
|
-
|
525
|
-
should_not_have_json "access_token"
|
526
|
-
should_have_json "error", "invalid_grant"
|
527
|
-
should_have_json "error_description", translated_error_message(:invalid_grant)
|
528
|
-
end
|
529
|
-
end
|
530
|
-
end
|