doorkeeper 5.2.2 → 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 +4 -4
- data/CHANGELOG.md +198 -3
- data/README.md +28 -20
- data/app/controllers/doorkeeper/application_controller.rb +3 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
- data/app/controllers/doorkeeper/applications_controller.rb +7 -8
- data/app/controllers/doorkeeper/authorizations_controller.rb +48 -18
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +6 -6
- data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +70 -25
- data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
- data/app/views/doorkeeper/applications/_form.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +35 -14
- data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
- data/app/views/doorkeeper/authorizations/new.html.erb +2 -0
- data/config/locales/en.yml +9 -2
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +26 -14
- data/lib/doorkeeper/config/validations.rb +53 -0
- data/lib/doorkeeper/config.rb +214 -122
- data/lib/doorkeeper/engine.rb +1 -1
- 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/helpers.rb +2 -2
- data/lib/doorkeeper/helpers/controller.rb +18 -12
- data/lib/doorkeeper/models/access_grant_mixin.rb +23 -19
- data/lib/doorkeeper/models/access_token_mixin.rb +157 -55
- data/lib/doorkeeper/models/application_mixin.rb +8 -7
- data/lib/doorkeeper/models/concerns/expirable.rb +1 -1
- data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
- data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
- data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
- data/lib/doorkeeper/models/concerns/revocable.rb +1 -28
- data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
- data/lib/doorkeeper/oauth/authorization/code.rb +22 -9
- data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
- data/lib/doorkeeper/oauth/authorization/token.rb +23 -18
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
- data/lib/doorkeeper/oauth/authorization_code_request.rb +30 -20
- data/lib/doorkeeper/oauth/base_request.rb +19 -23
- data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
- data/lib/doorkeeper/oauth/client.rb +8 -9
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +38 -12
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +10 -8
- data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +7 -5
- data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
- data/lib/doorkeeper/oauth/code_request.rb +4 -4
- data/lib/doorkeeper/oauth/code_response.rb +24 -14
- data/lib/doorkeeper/oauth/error.rb +1 -1
- data/lib/doorkeeper/oauth/error_response.rb +10 -11
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +2 -1
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +8 -12
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +10 -7
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -19
- data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
- data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
- data/lib/doorkeeper/oauth/invalid_token_response.rb +7 -4
- data/lib/doorkeeper/oauth/password_access_token_request.rb +28 -10
- data/lib/doorkeeper/oauth/pre_authorization.rb +73 -37
- data/lib/doorkeeper/oauth/refresh_token_request.rb +35 -26
- data/lib/doorkeeper/oauth/token.rb +6 -7
- data/lib/doorkeeper/oauth/token_introspection.rb +12 -16
- data/lib/doorkeeper/oauth/token_request.rb +3 -3
- data/lib/doorkeeper/oauth/token_response.rb +1 -1
- data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
- data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
- data/lib/doorkeeper/orm/active_record/application.rb +5 -95
- 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 +8 -3
- data/lib/doorkeeper/orm/active_record.rb +5 -7
- data/lib/doorkeeper/rails/helpers.rb +4 -4
- data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
- data/lib/doorkeeper/rails/routes/registry.rb +45 -0
- data/lib/doorkeeper/rails/routes.rb +17 -25
- data/lib/doorkeeper/rake/db.rake +6 -6
- data/lib/doorkeeper/rake/setup.rake +5 -0
- data/lib/doorkeeper/request/authorization_code.rb +3 -3
- data/lib/doorkeeper/request/client_credentials.rb +2 -2
- data/lib/doorkeeper/request/password.rb +3 -2
- data/lib/doorkeeper/request/refresh_token.rb +5 -4
- data/lib/doorkeeper/request/strategy.rb +2 -2
- data/lib/doorkeeper/request.rb +49 -12
- data/lib/doorkeeper/server.rb +5 -5
- data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
- data/lib/doorkeeper/version.rb +2 -6
- data/lib/doorkeeper.rb +112 -81
- data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +2 -2
- data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
- data/lib/generators/doorkeeper/migration_generator.rb +1 -1
- data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
- data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +99 -14
- data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
- metadata +37 -306
- data/Appraisals +0 -40
- 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 -16
- data/doorkeeper.gemspec +0 -42
- data/gemfiles/rails_5_0.gemfile +0 -18
- data/gemfiles/rails_5_1.gemfile +0 -18
- data/gemfiles/rails_5_2.gemfile +0 -18
- data/gemfiles/rails_6_0.gemfile +0 -18
- data/gemfiles/rails_master.gemfile +0 -18
- data/spec/controllers/application_metal_controller_spec.rb +0 -64
- data/spec/controllers/applications_controller_spec.rb +0 -273
- data/spec/controllers/authorizations_controller_spec.rb +0 -608
- data/spec/controllers/protected_resources_controller_spec.rb +0 -353
- data/spec/controllers/token_info_controller_spec.rb +0 -50
- data/spec/controllers/tokens_controller_spec.rb +0 -498
- 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 -7
- 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 -49
- 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/config.ru +0 -6
- 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 -68
- 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/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 -739
- 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 -59
- data/spec/lib/models/scopes_spec.rb +0 -53
- 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 -168
- data/spec/lib/oauth/base_request_spec.rb +0 -222
- data/spec/lib/oauth/base_response_spec.rb +0 -47
- data/spec/lib/oauth/client/credentials_spec.rb +0 -90
- data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -97
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
- data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
- data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -29
- data/spec/lib/oauth/client_credentials_request_spec.rb +0 -109
- 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 -66
- data/spec/lib/oauth/error_spec.rb +0 -23
- data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -22
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -98
- 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 -75
- data/spec/lib/oauth/invalid_token_response_spec.rb +0 -55
- data/spec/lib/oauth/password_access_token_request_spec.rb +0 -192
- data/spec/lib/oauth/pre_authorization_spec.rb +0 -225
- data/spec/lib/oauth/refresh_token_request_spec.rb +0 -178
- data/spec/lib/oauth/scopes_spec.rb +0 -148
- data/spec/lib/oauth/token_request_spec.rb +0 -153
- data/spec/lib/oauth/token_response_spec.rb +0 -86
- data/spec/lib/oauth/token_spec.rb +0 -158
- 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 -89
- data/spec/models/doorkeeper/access_grant_spec.rb +0 -163
- data/spec/models/doorkeeper/access_token_spec.rb +0 -622
- data/spec/models/doorkeeper/application_spec.rb +0 -377
- 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 -89
- data/spec/requests/endpoints/token_spec.rb +0 -75
- data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
- data/spec/requests/flows/authorization_code_spec.rb +0 -513
- data/spec/requests/flows/client_credentials_spec.rb +0 -166
- 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 -296
- data/spec/requests/flows/refresh_token_spec.rb +0 -233
- data/spec/requests/flows/revoke_token_spec.rb +0 -151
- 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 -57
- 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 -13
- 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/http_method_shim.rb +0 -29
- data/spec/support/orm/active_record.rb +0 -5
- data/spec/support/shared/controllers_shared_context.rb +0 -123
- data/spec/support/shared/hashing_shared_context.rb +0 -36
- data/spec/support/shared/models_shared_examples.rb +0 -54
- data/spec/validators/redirect_uri_validator_spec.rb +0 -183
- data/spec/version/version_spec.rb +0 -17
@@ -1,608 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
6
|
-
include AuthorizationRequestHelper
|
7
|
-
|
8
|
-
class ActionDispatch::TestResponse
|
9
|
-
def query_params
|
10
|
-
@query_params ||= begin
|
11
|
-
fragment = URI.parse(location).fragment
|
12
|
-
Rack::Utils.parse_query(fragment)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
let(:client) { FactoryBot.create :application }
|
18
|
-
let(:user) { User.create!(name: "Joe", password: "sekret") }
|
19
|
-
let(:access_token) { FactoryBot.build :access_token, resource_owner_id: user.id, application_id: client.id, scopes: "default" }
|
20
|
-
|
21
|
-
before do
|
22
|
-
Doorkeeper.configure do
|
23
|
-
default_scopes :default
|
24
|
-
|
25
|
-
custom_access_token_expires_in(lambda do |context|
|
26
|
-
context.grant_type == Doorkeeper::OAuth::IMPLICIT ? 1234 : nil
|
27
|
-
end)
|
28
|
-
end
|
29
|
-
|
30
|
-
allow(Doorkeeper.configuration).to receive(:grant_flows).and_return(["implicit"])
|
31
|
-
allow(Doorkeeper.configuration).to receive(:authenticate_resource_owner).and_return(->(_) { authenticator_method })
|
32
|
-
allow(controller).to receive(:authenticator_method).and_return(user)
|
33
|
-
expect(controller).to receive(:authenticator_method).at_most(:once)
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "POST #create" do
|
37
|
-
before do
|
38
|
-
post :create, params: { client_id: client.uid, response_type: "token", redirect_uri: client.redirect_uri }
|
39
|
-
end
|
40
|
-
|
41
|
-
it "redirects after authorization" do
|
42
|
-
expect(response).to be_redirect
|
43
|
-
end
|
44
|
-
|
45
|
-
it "redirects to client redirect uri" do
|
46
|
-
expect(response.location).to match(/^#{client.redirect_uri}/)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "includes access token in fragment" do
|
50
|
-
expect(response.query_params["access_token"]).to eq(Doorkeeper::AccessToken.first.token)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "includes token type in fragment" do
|
54
|
-
expect(response.query_params["token_type"]).to eq("Bearer")
|
55
|
-
end
|
56
|
-
|
57
|
-
it "includes token expiration in fragment" do
|
58
|
-
expect(response.query_params["expires_in"].to_i).to eq(1234)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "issues the token for the current client" do
|
62
|
-
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "issues the token for the current resource owner" do
|
66
|
-
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe "POST #create in API mode" do
|
71
|
-
before do
|
72
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
73
|
-
post :create, params: { client_id: client.uid, response_type: "token", redirect_uri: client.redirect_uri }
|
74
|
-
end
|
75
|
-
|
76
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
77
|
-
let(:redirect_uri) { response_json_body["redirect_uri"] }
|
78
|
-
|
79
|
-
it "renders success after authorization" do
|
80
|
-
expect(response).to be_successful
|
81
|
-
end
|
82
|
-
|
83
|
-
it "renders correct redirect uri" do
|
84
|
-
expect(redirect_uri).to match(/^#{client.redirect_uri}/)
|
85
|
-
end
|
86
|
-
|
87
|
-
it "includes access token in fragment" do
|
88
|
-
expect(redirect_uri.match(/access_token=([a-zA-Z0-9\-_]+)&?/)[1]).to eq(Doorkeeper::AccessToken.first.token)
|
89
|
-
end
|
90
|
-
|
91
|
-
it "includes token type in fragment" do
|
92
|
-
expect(redirect_uri.match(/token_type=(\w+)&?/)[1]).to eq "Bearer"
|
93
|
-
end
|
94
|
-
|
95
|
-
it "includes token expiration in fragment" do
|
96
|
-
expect(redirect_uri.match(/expires_in=(\d+)&?/)[1].to_i).to eq 1234
|
97
|
-
end
|
98
|
-
|
99
|
-
it "issues the token for the current client" do
|
100
|
-
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
101
|
-
end
|
102
|
-
|
103
|
-
it "issues the token for the current resource owner" do
|
104
|
-
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe "POST #create with errors" do
|
109
|
-
context "when missing client_id" do
|
110
|
-
before do
|
111
|
-
post :create, params: {
|
112
|
-
client_id: "",
|
113
|
-
response_type: "token",
|
114
|
-
redirect_uri: client.redirect_uri,
|
115
|
-
}
|
116
|
-
end
|
117
|
-
|
118
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
119
|
-
|
120
|
-
it "renders 400 error" do
|
121
|
-
expect(response.status).to eq 400
|
122
|
-
end
|
123
|
-
|
124
|
-
it "includes error name" do
|
125
|
-
expect(response_json_body["error"]).to eq("invalid_request")
|
126
|
-
end
|
127
|
-
|
128
|
-
it "includes error description" do
|
129
|
-
expect(response_json_body["error_description"]).to eq(
|
130
|
-
translated_invalid_request_error_message(:missing_param, :client_id)
|
131
|
-
)
|
132
|
-
end
|
133
|
-
|
134
|
-
it "does not issue any access token" do
|
135
|
-
expect(Doorkeeper::AccessToken.all).to be_empty
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
context "when other error happens" do
|
140
|
-
before do
|
141
|
-
default_scopes_exist :public
|
142
|
-
|
143
|
-
post :create, params: {
|
144
|
-
client_id: client.uid,
|
145
|
-
response_type: "token",
|
146
|
-
scope: "invalid",
|
147
|
-
redirect_uri: client.redirect_uri,
|
148
|
-
}
|
149
|
-
end
|
150
|
-
|
151
|
-
it "redirects after authorization" do
|
152
|
-
expect(response).to be_redirect
|
153
|
-
end
|
154
|
-
|
155
|
-
it "redirects to client redirect uri" do
|
156
|
-
expect(response.location).to match(/^#{client.redirect_uri}/)
|
157
|
-
end
|
158
|
-
|
159
|
-
it "does not include access token in fragment" do
|
160
|
-
expect(response.query_params["access_token"]).to be_nil
|
161
|
-
end
|
162
|
-
|
163
|
-
it "includes error in fragment" do
|
164
|
-
expect(response.query_params["error"]).to eq("invalid_scope")
|
165
|
-
end
|
166
|
-
|
167
|
-
it "includes error description in fragment" do
|
168
|
-
expect(response.query_params["error_description"]).to eq(translated_error_message(:invalid_scope))
|
169
|
-
end
|
170
|
-
|
171
|
-
it "does not issue any access token" do
|
172
|
-
expect(Doorkeeper::AccessToken.all).to be_empty
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe "POST #create in API mode with errors" do
|
178
|
-
context "when missing client_id" do
|
179
|
-
before do
|
180
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
181
|
-
|
182
|
-
post :create, params: {
|
183
|
-
client_id: "",
|
184
|
-
response_type: "token",
|
185
|
-
redirect_uri: client.redirect_uri,
|
186
|
-
}
|
187
|
-
end
|
188
|
-
|
189
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
190
|
-
|
191
|
-
it "renders 400 error" do
|
192
|
-
expect(response.status).to eq 400
|
193
|
-
end
|
194
|
-
|
195
|
-
it "includes error name" do
|
196
|
-
expect(response_json_body["error"]).to eq("invalid_request")
|
197
|
-
end
|
198
|
-
|
199
|
-
it "includes error description" do
|
200
|
-
expect(response_json_body["error_description"]).to eq(
|
201
|
-
translated_invalid_request_error_message(:missing_param, :client_id)
|
202
|
-
)
|
203
|
-
end
|
204
|
-
|
205
|
-
it "does not issue any access token" do
|
206
|
-
expect(Doorkeeper::AccessToken.all).to be_empty
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
context "when other error happens" do
|
211
|
-
before do
|
212
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
213
|
-
default_scopes_exist :public
|
214
|
-
|
215
|
-
post :create, params: {
|
216
|
-
client_id: client.uid,
|
217
|
-
response_type: "token",
|
218
|
-
scope: "invalid",
|
219
|
-
redirect_uri: client.redirect_uri,
|
220
|
-
}
|
221
|
-
end
|
222
|
-
|
223
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
224
|
-
let(:redirect_uri) { response_json_body["redirect_uri"] }
|
225
|
-
|
226
|
-
it "renders 400 error" do
|
227
|
-
expect(response.status).to eq 400
|
228
|
-
end
|
229
|
-
|
230
|
-
it "includes correct redirect URI" do
|
231
|
-
expect(redirect_uri).to match(/^#{client.redirect_uri}/)
|
232
|
-
end
|
233
|
-
|
234
|
-
it "does not include access token in fragment" do
|
235
|
-
expect(redirect_uri.match(/access_token=([a-f0-9]+)&?/)).to be_nil
|
236
|
-
end
|
237
|
-
|
238
|
-
it "includes error in redirect uri" do
|
239
|
-
expect(redirect_uri.match(/error=([a-z_]+)&?/)[1]).to eq "invalid_scope"
|
240
|
-
end
|
241
|
-
|
242
|
-
it "includes error description in redirect uri" do
|
243
|
-
expect(redirect_uri.match(/error_description=(.+)&?/)[1]).to_not be_nil
|
244
|
-
end
|
245
|
-
|
246
|
-
it "does not issue any access token" do
|
247
|
-
expect(Doorkeeper::AccessToken.all).to be_empty
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
describe "POST #create with application already authorized" do
|
253
|
-
before do
|
254
|
-
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
255
|
-
|
256
|
-
access_token.save!
|
257
|
-
|
258
|
-
post :create, params: {
|
259
|
-
client_id: client.uid,
|
260
|
-
response_type: "token",
|
261
|
-
redirect_uri: client.redirect_uri,
|
262
|
-
}
|
263
|
-
end
|
264
|
-
|
265
|
-
it "returns the existing access token in a fragment" do
|
266
|
-
expect(response.query_params["access_token"]).to eq(access_token.token)
|
267
|
-
end
|
268
|
-
|
269
|
-
it "does not creates a new access token" do
|
270
|
-
expect(Doorkeeper::AccessToken.count).to eq(1)
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
describe "POST #create with callbacks" do
|
275
|
-
after do
|
276
|
-
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
277
|
-
end
|
278
|
-
|
279
|
-
describe "when successful" do
|
280
|
-
after do
|
281
|
-
post :create, params: {
|
282
|
-
client_id: client.uid,
|
283
|
-
response_type: "token",
|
284
|
-
redirect_uri: client.redirect_uri,
|
285
|
-
}
|
286
|
-
end
|
287
|
-
|
288
|
-
it "should call :before_successful_authorization callback" do
|
289
|
-
expect(Doorkeeper.configuration)
|
290
|
-
.to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
|
291
|
-
end
|
292
|
-
|
293
|
-
it "should call :after_successful_authorization callback" do
|
294
|
-
expect(Doorkeeper.configuration)
|
295
|
-
.to receive_message_chain(:after_successful_authorization, :call).with(instance_of(described_class))
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
describe "with errors" do
|
300
|
-
after do
|
301
|
-
post :create, params: { client_id: client.uid, response_type: "token", redirect_uri: "bad_uri" }
|
302
|
-
end
|
303
|
-
|
304
|
-
it "should not call :before_successful_authorization callback" do
|
305
|
-
expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
|
306
|
-
end
|
307
|
-
|
308
|
-
it "should not call :after_successful_authorization callback" do
|
309
|
-
expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
describe "GET #new token request with native url and skip_authorization true" do
|
315
|
-
before do
|
316
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc do
|
317
|
-
true
|
318
|
-
end)
|
319
|
-
|
320
|
-
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
321
|
-
|
322
|
-
get :new, params: {
|
323
|
-
client_id: client.uid,
|
324
|
-
response_type: "token",
|
325
|
-
redirect_uri: client.redirect_uri,
|
326
|
-
}
|
327
|
-
end
|
328
|
-
|
329
|
-
it "should redirect immediately" do
|
330
|
-
expect(response).to be_redirect
|
331
|
-
expect(response.location).to match(%r{/oauth/token/info\?access_token=})
|
332
|
-
end
|
333
|
-
|
334
|
-
it "should not issue a grant" do
|
335
|
-
expect(Doorkeeper::AccessGrant.count).to be 0
|
336
|
-
end
|
337
|
-
|
338
|
-
it "should issue a token" do
|
339
|
-
expect(Doorkeeper::AccessToken.count).to be 1
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
describe "GET #new code request with native url and skip_authorization true" do
|
344
|
-
before do
|
345
|
-
allow(Doorkeeper.configuration).to receive(:grant_flows).and_return(%w[authorization_code])
|
346
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc do
|
347
|
-
true
|
348
|
-
end)
|
349
|
-
|
350
|
-
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
351
|
-
|
352
|
-
get :new, params: {
|
353
|
-
client_id: client.uid,
|
354
|
-
response_type: "code",
|
355
|
-
redirect_uri: client.redirect_uri,
|
356
|
-
}
|
357
|
-
end
|
358
|
-
|
359
|
-
it "should redirect immediately" do
|
360
|
-
expect(response).to be_redirect
|
361
|
-
expect(response.location)
|
362
|
-
.to match(%r{/oauth/authorize/native\?code=#{Doorkeeper::AccessGrant.first.token}})
|
363
|
-
end
|
364
|
-
|
365
|
-
it "should issue a grant" do
|
366
|
-
expect(Doorkeeper::AccessGrant.count).to be 1
|
367
|
-
end
|
368
|
-
|
369
|
-
it "should not issue a token" do
|
370
|
-
expect(Doorkeeper::AccessToken.count).to be 0
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
describe "GET #new with skip_authorization true" do
|
375
|
-
before do
|
376
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc do
|
377
|
-
true
|
378
|
-
end)
|
379
|
-
|
380
|
-
get :new, params: {
|
381
|
-
client_id: client.uid,
|
382
|
-
response_type: "token",
|
383
|
-
redirect_uri: client.redirect_uri,
|
384
|
-
}
|
385
|
-
end
|
386
|
-
|
387
|
-
it "should redirect immediately" do
|
388
|
-
expect(response).to be_redirect
|
389
|
-
expect(response.location).to match(/^#{client.redirect_uri}/)
|
390
|
-
end
|
391
|
-
|
392
|
-
it "should issue a token" do
|
393
|
-
expect(Doorkeeper::AccessToken.count).to be 1
|
394
|
-
end
|
395
|
-
|
396
|
-
it "includes token type in fragment" do
|
397
|
-
expect(response.query_params["token_type"]).to eq("Bearer")
|
398
|
-
end
|
399
|
-
|
400
|
-
it "includes token expiration in fragment" do
|
401
|
-
expect(response.query_params["expires_in"].to_i).to eq(1234)
|
402
|
-
end
|
403
|
-
|
404
|
-
it "issues the token for the current client" do
|
405
|
-
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
406
|
-
end
|
407
|
-
|
408
|
-
it "issues the token for the current resource owner" do
|
409
|
-
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
describe "GET #new in API mode" do
|
414
|
-
before do
|
415
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
416
|
-
|
417
|
-
get :new, params: {
|
418
|
-
client_id: client.uid,
|
419
|
-
response_type: "token",
|
420
|
-
redirect_uri: client.redirect_uri,
|
421
|
-
}
|
422
|
-
end
|
423
|
-
|
424
|
-
it "should render success" do
|
425
|
-
expect(response).to be_successful
|
426
|
-
end
|
427
|
-
|
428
|
-
it "sets status to pre-authorization" do
|
429
|
-
expect(json_response["status"]).to eq(I18n.t("doorkeeper.pre_authorization.status"))
|
430
|
-
end
|
431
|
-
|
432
|
-
it "sets correct values" do
|
433
|
-
expect(json_response["client_id"]).to eq(client.uid)
|
434
|
-
expect(json_response["redirect_uri"]).to eq(client.redirect_uri)
|
435
|
-
expect(json_response["state"]).to be_nil
|
436
|
-
expect(json_response["response_type"]).to eq("token")
|
437
|
-
expect(json_response["scope"]).to eq("default")
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
describe "GET #new in API mode with skip_authorization true" do
|
442
|
-
before do
|
443
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { true })
|
444
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
445
|
-
|
446
|
-
get :new, params: {
|
447
|
-
client_id: client.uid,
|
448
|
-
response_type: "token",
|
449
|
-
redirect_uri: client.redirect_uri,
|
450
|
-
}
|
451
|
-
end
|
452
|
-
|
453
|
-
it "should render success" do
|
454
|
-
expect(response).to be_successful
|
455
|
-
end
|
456
|
-
|
457
|
-
it "should issue a token" do
|
458
|
-
expect(Doorkeeper::AccessToken.count).to be 1
|
459
|
-
end
|
460
|
-
|
461
|
-
it "sets status to redirect" do
|
462
|
-
expect(JSON.parse(response.body)["status"]).to eq("redirect")
|
463
|
-
end
|
464
|
-
|
465
|
-
it "sets redirect_uri to correct value" do
|
466
|
-
redirect_uri = JSON.parse(response.body)["redirect_uri"]
|
467
|
-
expect(redirect_uri).to_not be_nil
|
468
|
-
expect(redirect_uri.match(/token_type=(\w+)&?/)[1]).to eq "Bearer"
|
469
|
-
expect(redirect_uri.match(/expires_in=(\d+)&?/)[1].to_i).to eq 1234
|
470
|
-
expect(
|
471
|
-
redirect_uri.match(/access_token=([a-zA-Z0-9\-_]+)&?/)[1]
|
472
|
-
).to eq Doorkeeper::AccessToken.first.token
|
473
|
-
end
|
474
|
-
|
475
|
-
it "issues the token for the current client" do
|
476
|
-
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
477
|
-
end
|
478
|
-
|
479
|
-
it "issues the token for the current resource owner" do
|
480
|
-
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
describe "GET #new with errors" do
|
485
|
-
before do
|
486
|
-
default_scopes_exist :public
|
487
|
-
get :new, params: { an_invalid: "request" }
|
488
|
-
end
|
489
|
-
|
490
|
-
it "does not redirect" do
|
491
|
-
expect(response).to_not be_redirect
|
492
|
-
end
|
493
|
-
|
494
|
-
it "does not issue any token" do
|
495
|
-
expect(Doorkeeper::AccessGrant.count).to eq 0
|
496
|
-
expect(Doorkeeper::AccessToken.count).to eq 0
|
497
|
-
end
|
498
|
-
end
|
499
|
-
|
500
|
-
describe "GET #new in API mode with errors" do
|
501
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
502
|
-
|
503
|
-
before do
|
504
|
-
default_scopes_exist :public
|
505
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
506
|
-
get :new, params: { an_invalid: "request" }
|
507
|
-
end
|
508
|
-
|
509
|
-
it "should render bad request" do
|
510
|
-
expect(response).to have_http_status(:bad_request)
|
511
|
-
end
|
512
|
-
|
513
|
-
it "includes error in body" do
|
514
|
-
expect(response_json_body["error"]).to eq("invalid_request")
|
515
|
-
end
|
516
|
-
|
517
|
-
it "includes error description in body" do
|
518
|
-
expect(response_json_body["error_description"])
|
519
|
-
.to eq(translated_invalid_request_error_message(:missing_param, :client_id))
|
520
|
-
end
|
521
|
-
|
522
|
-
it "does not issue any token" do
|
523
|
-
expect(Doorkeeper::AccessGrant.count).to eq 0
|
524
|
-
expect(Doorkeeper::AccessToken.count).to eq 0
|
525
|
-
end
|
526
|
-
end
|
527
|
-
|
528
|
-
describe "GET #new with callbacks" do
|
529
|
-
after do
|
530
|
-
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
531
|
-
get :new, params: { client_id: client.uid, response_type: "token", redirect_uri: client.redirect_uri }
|
532
|
-
end
|
533
|
-
|
534
|
-
describe "when authorizing" do
|
535
|
-
before do
|
536
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { true })
|
537
|
-
end
|
538
|
-
|
539
|
-
it "should call :before_successful_authorization callback" do
|
540
|
-
expect(Doorkeeper.configuration)
|
541
|
-
.to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
|
542
|
-
end
|
543
|
-
|
544
|
-
it "should call :after_successful_authorization callback" do
|
545
|
-
expect(Doorkeeper.configuration)
|
546
|
-
.to receive_message_chain(:after_successful_authorization, :call).with(instance_of(described_class))
|
547
|
-
end
|
548
|
-
end
|
549
|
-
|
550
|
-
describe "when not authorizing" do
|
551
|
-
before do
|
552
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { false })
|
553
|
-
end
|
554
|
-
|
555
|
-
it "should not call :before_successful_authorization callback" do
|
556
|
-
expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
|
557
|
-
end
|
558
|
-
|
559
|
-
it "should not call :after_successful_authorization callback" do
|
560
|
-
expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
|
561
|
-
end
|
562
|
-
end
|
563
|
-
|
564
|
-
describe "when not authorizing in api mode" do
|
565
|
-
before do
|
566
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { false })
|
567
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
568
|
-
end
|
569
|
-
|
570
|
-
it "should not call :before_successful_authorization callback" do
|
571
|
-
expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
|
572
|
-
end
|
573
|
-
|
574
|
-
it "should not call :after_successful_authorization callback" do
|
575
|
-
expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
|
576
|
-
end
|
577
|
-
end
|
578
|
-
end
|
579
|
-
|
580
|
-
describe "authorize response memoization" do
|
581
|
-
it "memoizes the result of the authorization" do
|
582
|
-
pre_auth = double(:pre_auth, authorizable?: true)
|
583
|
-
allow(controller).to receive(:pre_auth) { pre_auth }
|
584
|
-
strategy = double(:strategy, authorize: true)
|
585
|
-
expect(strategy).to receive(:authorize).once
|
586
|
-
allow(controller).to receive(:strategy) { strategy }
|
587
|
-
allow(controller).to receive(:create) do
|
588
|
-
2.times { controller.send :authorize_response }
|
589
|
-
controller.render json: {}, status: :ok
|
590
|
-
end
|
591
|
-
|
592
|
-
post :create
|
593
|
-
end
|
594
|
-
end
|
595
|
-
|
596
|
-
describe "strong parameters" do
|
597
|
-
it "ignores non-scalar scope parameter" do
|
598
|
-
get :new, params: {
|
599
|
-
client_id: client.uid,
|
600
|
-
response_type: "token",
|
601
|
-
redirect_uri: client.redirect_uri,
|
602
|
-
scope: { "0" => "profile" },
|
603
|
-
}
|
604
|
-
|
605
|
-
expect(response).to be_successful
|
606
|
-
end
|
607
|
-
end
|
608
|
-
end
|