doorkeeper 5.0.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.hound.yml +2 -1
- data/.rubocop.yml +37 -4
- data/.travis.yml +16 -21
- data/Appraisals +29 -7
- data/Dangerfile +67 -0
- data/Gemfile +19 -5
- data/NEWS.md +107 -10
- data/README.md +75 -470
- data/Rakefile +10 -8
- data/app/controllers/doorkeeper/application_controller.rb +3 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +4 -13
- data/app/controllers/doorkeeper/applications_controller.rb +21 -7
- data/app/controllers/doorkeeper/authorizations_controller.rb +3 -3
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -0
- data/app/controllers/doorkeeper/token_info_controller.rb +4 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +13 -11
- data/app/helpers/doorkeeper/dashboard_helper.rb +3 -1
- data/app/validators/redirect_uri_validator.rb +7 -2
- data/app/views/doorkeeper/applications/_form.html.erb +6 -0
- data/app/views/doorkeeper/applications/show.html.erb +1 -1
- data/app/views/layouts/doorkeeper/admin.html.erb +5 -3
- data/bin/console +16 -0
- data/config/locales/en.yml +1 -0
- data/doorkeeper.gemspec +28 -24
- data/gemfiles/rails_5_0.gemfile +9 -4
- data/gemfiles/rails_5_1.gemfile +9 -4
- data/gemfiles/rails_5_2.gemfile +10 -5
- data/gemfiles/rails_6_0.gemfile +17 -0
- data/gemfiles/rails_master.gemfile +9 -9
- data/lib/doorkeeper/config/option.rb +64 -0
- data/lib/doorkeeper/config.rb +197 -76
- data/lib/doorkeeper/engine.rb +3 -1
- data/lib/doorkeeper/errors.rb +17 -0
- data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
- data/lib/doorkeeper/grape/helpers.rb +5 -3
- data/lib/doorkeeper/helpers/controller.rb +5 -2
- data/lib/doorkeeper/models/access_grant_mixin.rb +25 -6
- data/lib/doorkeeper/models/access_token_mixin.rb +68 -22
- data/lib/doorkeeper/models/application_mixin.rb +45 -1
- data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +6 -2
- data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +3 -6
- data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +4 -1
- data/lib/doorkeeper/models/concerns/scopes.rb +7 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +108 -0
- data/lib/doorkeeper/oauth/authorization/code.rb +4 -2
- data/lib/doorkeeper/oauth/authorization/context.rb +2 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +14 -7
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +3 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +8 -4
- data/lib/doorkeeper/oauth/base_request.rb +2 -0
- data/lib/doorkeeper/oauth/base_response.rb +2 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +2 -0
- data/lib/doorkeeper/oauth/client.rb +3 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -0
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +2 -0
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +7 -4
- data/lib/doorkeeper/oauth/client_credentials_request.rb +3 -1
- data/lib/doorkeeper/oauth/code_request.rb +2 -0
- data/lib/doorkeeper/oauth/code_response.rb +4 -2
- data/lib/doorkeeper/oauth/error.rb +2 -0
- data/lib/doorkeeper/oauth/error_response.rb +20 -6
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +10 -3
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +25 -8
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +15 -1
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +42 -3
- data/lib/doorkeeper/oauth/invalid_token_response.rb +22 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +13 -5
- data/lib/doorkeeper/oauth/refresh_token_request.rb +15 -4
- data/lib/doorkeeper/oauth/scopes.rb +7 -3
- data/lib/doorkeeper/oauth/token.rb +4 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +76 -8
- data/lib/doorkeeper/oauth/token_request.rb +2 -0
- data/lib/doorkeeper/oauth/token_response.rb +11 -9
- data/lib/doorkeeper/oauth.rb +5 -5
- data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -13
- data/lib/doorkeeper/orm/active_record/access_token.rb +6 -13
- data/lib/doorkeeper/orm/active_record/application.rb +26 -7
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
- data/lib/doorkeeper/orm/active_record.rb +8 -6
- data/lib/doorkeeper/rails/helpers.rb +5 -1
- data/lib/doorkeeper/rails/routes/mapper.rb +2 -0
- data/lib/doorkeeper/rails/routes/mapping.rb +9 -7
- data/lib/doorkeeper/rails/routes.rb +19 -12
- data/lib/doorkeeper/rake/db.rake +17 -17
- data/lib/doorkeeper/rake.rb +1 -1
- data/lib/doorkeeper/request/authorization_code.rb +2 -0
- data/lib/doorkeeper/request/client_credentials.rb +2 -0
- data/lib/doorkeeper/request/code.rb +2 -0
- data/lib/doorkeeper/request/password.rb +2 -0
- data/lib/doorkeeper/request/refresh_token.rb +2 -0
- data/lib/doorkeeper/request/strategy.rb +2 -0
- data/lib/doorkeeper/request/token.rb +2 -0
- data/lib/doorkeeper/request.rb +3 -1
- 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 +2 -0
- data/lib/doorkeeper/stale_records_cleaner.rb +20 -0
- data/lib/doorkeeper/validations.rb +2 -0
- data/lib/doorkeeper/version.rb +4 -2
- data/lib/doorkeeper.rb +69 -59
- data/lib/generators/doorkeeper/application_owner_generator.rb +10 -9
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +10 -9
- data/lib/generators/doorkeeper/install_generator.rb +11 -9
- data/lib/generators/doorkeeper/migration_generator.rb +9 -9
- data/lib/generators/doorkeeper/pkce_generator.rb +10 -9
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +10 -9
- data/lib/generators/doorkeeper/templates/initializer.rb +138 -13
- data/lib/generators/doorkeeper/templates/migration.rb.erb +17 -10
- data/lib/generators/doorkeeper/views_generator.rb +6 -4
- data/spec/controllers/application_metal_controller_spec.rb +24 -10
- data/spec/controllers/applications_controller_spec.rb +76 -78
- data/spec/controllers/authorizations_controller_spec.rb +189 -142
- data/spec/controllers/protected_resources_controller_spec.rb +111 -67
- data/spec/controllers/token_info_controller_spec.rb +14 -12
- data/spec/controllers/tokens_controller_spec.rb +170 -112
- data/spec/dummy/Rakefile +3 -1
- data/spec/dummy/app/controllers/application_controller.rb +3 -1
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +3 -1
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -2
- data/spec/dummy/app/controllers/home_controller.rb +6 -5
- data/spec/dummy/app/controllers/metal_controller.rb +2 -0
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +4 -2
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/user.rb +2 -0
- data/spec/dummy/config/application.rb +26 -2
- data/spec/dummy/config/boot.rb +2 -4
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/environments/development.rb +2 -0
- data/spec/dummy/config/environments/production.rb +2 -0
- data/spec/dummy/config/environments/test.rb +4 -2
- data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
- data/spec/dummy/config/initializers/doorkeeper.rb +7 -3
- data/spec/dummy/config/initializers/secret_token.rb +3 -1
- data/spec/dummy/config/initializers/session_store.rb +3 -1
- data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
- data/spec/dummy/config.ru +3 -1
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +20 -13
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +1 -1
- data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +2 -0
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/dummy/script/rails +7 -4
- data/spec/factories.rb +11 -9
- data/spec/generators/application_owner_generator_spec.rb +13 -26
- data/spec/generators/confidential_applications_generator_spec.rb +12 -28
- data/spec/generators/install_generator_spec.rb +19 -14
- data/spec/generators/migration_generator_spec.rb +13 -26
- data/spec/generators/pkce_generator_spec.rb +11 -26
- data/spec/generators/previous_refresh_token_generator_spec.rb +16 -29
- data/spec/generators/templates/routes.rb +2 -1
- data/spec/generators/views_generator_spec.rb +14 -12
- data/spec/grape/grape_integration_spec.rb +35 -33
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +9 -7
- data/spec/lib/config_spec.rb +290 -104
- data/spec/lib/doorkeeper_spec.rb +8 -6
- data/spec/lib/models/expirable_spec.rb +22 -8
- data/spec/lib/models/reusable_spec.rb +40 -0
- data/spec/lib/models/revocable_spec.rb +8 -6
- data/spec/lib/models/scopes_spec.rb +27 -13
- data/spec/lib/models/secret_storable_spec.rb +135 -0
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +17 -15
- data/spec/lib/oauth/authorization_code_request_spec.rb +43 -17
- data/spec/lib/oauth/base_request_spec.rb +24 -12
- data/spec/lib/oauth/base_response_spec.rb +3 -1
- data/spec/lib/oauth/client/credentials_spec.rb +26 -24
- data/spec/lib/oauth/client_credentials/creator_spec.rb +56 -10
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -20
- data/spec/lib/oauth/client_credentials/validation_spec.rb +21 -15
- data/spec/lib/oauth/client_credentials_integration_spec.rb +8 -6
- data/spec/lib/oauth/client_credentials_request_spec.rb +27 -21
- data/spec/lib/oauth/client_spec.rb +15 -13
- data/spec/lib/oauth/code_request_spec.rb +10 -8
- data/spec/lib/oauth/code_response_spec.rb +9 -7
- data/spec/lib/oauth/error_response_spec.rb +19 -11
- data/spec/lib/oauth/error_spec.rb +4 -2
- data/spec/lib/oauth/forbidden_token_response_spec.rb +7 -5
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +68 -31
- data/spec/lib/oauth/helpers/unique_token_spec.rb +8 -6
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +124 -93
- data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +95 -34
- data/spec/lib/oauth/pre_authorization_spec.rb +80 -54
- data/spec/lib/oauth/refresh_token_request_spec.rb +46 -39
- data/spec/lib/oauth/scopes_spec.rb +63 -61
- data/spec/lib/oauth/token_request_spec.rb +80 -25
- data/spec/lib/oauth/token_response_spec.rb +40 -38
- data/spec/lib/oauth/token_spec.rb +64 -45
- data/spec/lib/request/strategy_spec.rb +3 -1
- data/spec/lib/secret_storing/base_spec.rb +60 -0
- data/spec/lib/secret_storing/bcrypt_spec.rb +49 -0
- data/spec/lib/secret_storing/plain_spec.rb +44 -0
- data/spec/lib/secret_storing/sha256_hash_spec.rb +48 -0
- data/spec/lib/server_spec.rb +20 -18
- data/spec/lib/{orm/active_record/stale_records_cleaner_spec.rb → stale_records_cleaner_spec.rb} +28 -18
- data/spec/models/doorkeeper/access_grant_spec.rb +80 -15
- data/spec/models/doorkeeper/access_token_spec.rb +212 -83
- data/spec/models/doorkeeper/application_spec.rb +146 -49
- data/spec/requests/applications/applications_request_spec.rb +100 -68
- data/spec/requests/applications/authorized_applications_spec.rb +20 -18
- data/spec/requests/endpoints/authorization_spec.rb +27 -25
- data/spec/requests/endpoints/token_spec.rb +38 -36
- data/spec/requests/flows/authorization_code_errors_spec.rb +27 -25
- data/spec/requests/flows/authorization_code_spec.rb +260 -158
- data/spec/requests/flows/client_credentials_spec.rb +54 -52
- data/spec/requests/flows/implicit_grant_errors_spec.rb +11 -9
- data/spec/requests/flows/implicit_grant_spec.rb +27 -25
- data/spec/requests/flows/password_spec.rb +64 -56
- data/spec/requests/flows/refresh_token_spec.rb +91 -32
- data/spec/requests/flows/revoke_token_spec.rb +49 -63
- data/spec/requests/flows/skip_authorization_spec.rb +23 -21
- data/spec/requests/protected_resources/metal_spec.rb +7 -5
- data/spec/requests/protected_resources/private_api_spec.rb +37 -35
- data/spec/routing/custom_controller_routes_spec.rb +71 -65
- data/spec/routing/default_routes_spec.rb +22 -20
- data/spec/routing/scoped_routes_spec.rb +20 -18
- data/spec/spec_helper.rb +15 -13
- data/spec/spec_helper_integration.rb +3 -1
- data/spec/support/dependencies/factory_bot.rb +3 -1
- data/spec/support/doorkeeper_rspec.rb +5 -2
- data/spec/support/helpers/access_token_request_helper.rb +3 -1
- data/spec/support/helpers/authorization_request_helper.rb +4 -2
- data/spec/support/helpers/config_helper.rb +2 -0
- data/spec/support/helpers/model_helper.rb +11 -5
- data/spec/support/helpers/request_spec_helper.rb +5 -3
- data/spec/support/helpers/url_helper.rb +20 -18
- data/spec/support/http_method_shim.rb +4 -9
- data/spec/support/orm/active_record.rb +3 -1
- data/spec/support/shared/controllers_shared_context.rb +68 -10
- data/spec/support/shared/hashing_shared_context.rb +36 -0
- data/spec/support/shared/models_shared_examples.rb +12 -10
- data/spec/validators/redirect_uri_validator_spec.rb +76 -47
- data/spec/version/version_spec.rb +7 -5
- metadata +70 -21
- data/gemfiles/rails_4_2.gemfile +0 -13
- data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -10
|
@@ -1,24 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
4
6
|
include AuthorizationRequestHelper
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Rack::Utils.parse_query(fragment)
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
else
|
|
16
|
-
class ActionController::TestResponse
|
|
17
|
-
def query_params
|
|
18
|
-
@query_params ||= begin
|
|
19
|
-
fragment = URI.parse(location).fragment
|
|
20
|
-
Rack::Utils.parse_query(fragment)
|
|
21
|
-
end
|
|
8
|
+
class ActionDispatch::TestResponse
|
|
9
|
+
def query_params
|
|
10
|
+
@query_params ||= begin
|
|
11
|
+
fragment = URI.parse(location).fragment
|
|
12
|
+
Rack::Utils.parse_query(fragment)
|
|
22
13
|
end
|
|
23
14
|
end
|
|
24
15
|
end
|
|
@@ -28,47 +19,50 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
|
|
|
28
19
|
end
|
|
29
20
|
|
|
30
21
|
let(:client) { FactoryBot.create :application }
|
|
31
|
-
let(:user) { User.create!(name:
|
|
22
|
+
let(:user) { User.create!(name: "Joe", password: "sekret") }
|
|
32
23
|
let(:access_token) { FactoryBot.build :access_token, resource_owner_id: user.id, application_id: client.id }
|
|
33
24
|
|
|
34
25
|
before do
|
|
26
|
+
Doorkeeper.configure do
|
|
27
|
+
custom_access_token_expires_in(lambda do |context|
|
|
28
|
+
context.grant_type == Doorkeeper::OAuth::IMPLICIT ? 1234 : nil
|
|
29
|
+
end)
|
|
30
|
+
end
|
|
31
|
+
|
|
35
32
|
allow(Doorkeeper.configuration).to receive(:grant_flows).and_return(["implicit"])
|
|
36
33
|
allow(controller).to receive(:current_resource_owner).and_return(user)
|
|
37
|
-
allow(Doorkeeper.configuration).to receive(:custom_access_token_expires_in).and_return(proc { |context|
|
|
38
|
-
context.grant_type == Doorkeeper::OAuth::IMPLICIT ? 1234 : nil
|
|
39
|
-
})
|
|
40
34
|
end
|
|
41
35
|
|
|
42
|
-
describe
|
|
36
|
+
describe "POST #create" do
|
|
43
37
|
before do
|
|
44
|
-
post :create, params: { client_id: client.uid, response_type:
|
|
38
|
+
post :create, params: { client_id: client.uid, response_type: "token", redirect_uri: client.redirect_uri }
|
|
45
39
|
end
|
|
46
40
|
|
|
47
|
-
it
|
|
41
|
+
it "redirects after authorization" do
|
|
48
42
|
expect(response).to be_redirect
|
|
49
43
|
end
|
|
50
44
|
|
|
51
|
-
it
|
|
52
|
-
expect(response.location).to match(
|
|
45
|
+
it "redirects to client redirect uri" do
|
|
46
|
+
expect(response.location).to match(/^#{client.redirect_uri}/)
|
|
53
47
|
end
|
|
54
48
|
|
|
55
|
-
it
|
|
56
|
-
expect(response.query_params[
|
|
49
|
+
it "includes access token in fragment" do
|
|
50
|
+
expect(response.query_params["access_token"]).to eq(Doorkeeper::AccessToken.first.token)
|
|
57
51
|
end
|
|
58
52
|
|
|
59
|
-
it
|
|
60
|
-
expect(response.query_params[
|
|
53
|
+
it "includes token type in fragment" do
|
|
54
|
+
expect(response.query_params["token_type"]).to eq("Bearer")
|
|
61
55
|
end
|
|
62
56
|
|
|
63
|
-
it
|
|
64
|
-
expect(response.query_params[
|
|
57
|
+
it "includes token expiration in fragment" do
|
|
58
|
+
expect(response.query_params["expires_in"].to_i).to eq(1234)
|
|
65
59
|
end
|
|
66
60
|
|
|
67
|
-
it
|
|
61
|
+
it "issues the token for the current client" do
|
|
68
62
|
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
|
69
63
|
end
|
|
70
64
|
|
|
71
|
-
it
|
|
65
|
+
it "issues the token for the current resource owner" do
|
|
72
66
|
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
|
73
67
|
end
|
|
74
68
|
end
|
|
@@ -91,7 +85,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
|
|
|
91
85
|
end
|
|
92
86
|
|
|
93
87
|
it "includes access token in fragment" do
|
|
94
|
-
expect(redirect_uri.match(/access_token=([a-
|
|
88
|
+
expect(redirect_uri.match(/access_token=([a-zA-Z0-9\-_]+)&?/)[1]).to eq(Doorkeeper::AccessToken.first.token)
|
|
95
89
|
end
|
|
96
90
|
|
|
97
91
|
it "includes token type in fragment" do
|
|
@@ -111,240 +105,290 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
|
|
|
111
105
|
end
|
|
112
106
|
end
|
|
113
107
|
|
|
114
|
-
describe
|
|
108
|
+
describe "POST #create with errors" do
|
|
115
109
|
before do
|
|
116
110
|
default_scopes_exist :public
|
|
117
|
-
|
|
111
|
+
|
|
112
|
+
post :create, params: {
|
|
113
|
+
client_id: client.uid,
|
|
114
|
+
response_type: "token",
|
|
115
|
+
scope: "invalid",
|
|
116
|
+
redirect_uri: client.redirect_uri,
|
|
117
|
+
}
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
it
|
|
120
|
+
it "redirects after authorization" do
|
|
121
121
|
expect(response).to be_redirect
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
-
it
|
|
124
|
+
it "redirects to client redirect uri" do
|
|
125
125
|
expect(response.location).to match(/^#{client.redirect_uri}/)
|
|
126
126
|
end
|
|
127
127
|
|
|
128
|
-
it
|
|
129
|
-
expect(response.query_params[
|
|
128
|
+
it "does not include access token in fragment" do
|
|
129
|
+
expect(response.query_params["access_token"]).to be_nil
|
|
130
130
|
end
|
|
131
131
|
|
|
132
|
-
it
|
|
133
|
-
expect(response.query_params[
|
|
132
|
+
it "includes error in fragment" do
|
|
133
|
+
expect(response.query_params["error"]).to eq("invalid_scope")
|
|
134
134
|
end
|
|
135
135
|
|
|
136
|
-
it
|
|
137
|
-
expect(response.query_params[
|
|
136
|
+
it "includes error description in fragment" do
|
|
137
|
+
expect(response.query_params["error_description"]).to eq(translated_error_message(:invalid_scope))
|
|
138
138
|
end
|
|
139
139
|
|
|
140
|
-
it
|
|
140
|
+
it "does not issue any access token" do
|
|
141
141
|
expect(Doorkeeper::AccessToken.all).to be_empty
|
|
142
142
|
end
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
describe
|
|
145
|
+
describe "POST #create in API mode with errors" do
|
|
146
146
|
before do
|
|
147
147
|
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
|
148
148
|
default_scopes_exist :public
|
|
149
|
-
|
|
149
|
+
|
|
150
|
+
post :create, params: {
|
|
151
|
+
client_id: client.uid,
|
|
152
|
+
response_type: "token",
|
|
153
|
+
scope: "invalid",
|
|
154
|
+
redirect_uri: client.redirect_uri,
|
|
155
|
+
}
|
|
150
156
|
end
|
|
151
157
|
|
|
152
158
|
let(:response_json_body) { JSON.parse(response.body) }
|
|
153
|
-
let(:redirect_uri) { response_json_body[
|
|
159
|
+
let(:redirect_uri) { response_json_body["redirect_uri"] }
|
|
154
160
|
|
|
155
|
-
it
|
|
156
|
-
expect(response.status).to eq
|
|
161
|
+
it "renders 400 error" do
|
|
162
|
+
expect(response.status).to eq 400
|
|
157
163
|
end
|
|
158
164
|
|
|
159
|
-
it
|
|
165
|
+
it "includes correct redirect URI" do
|
|
160
166
|
expect(redirect_uri).to match(/^#{client.redirect_uri}/)
|
|
161
167
|
end
|
|
162
168
|
|
|
163
|
-
it
|
|
169
|
+
it "does not include access token in fragment" do
|
|
164
170
|
expect(redirect_uri.match(/access_token=([a-f0-9]+)&?/)).to be_nil
|
|
165
171
|
end
|
|
166
172
|
|
|
167
|
-
it
|
|
168
|
-
expect(redirect_uri.match(/error=([a-z_]+)&?/)[1]).to eq
|
|
173
|
+
it "includes error in redirect uri" do
|
|
174
|
+
expect(redirect_uri.match(/error=([a-z_]+)&?/)[1]).to eq "invalid_scope"
|
|
169
175
|
end
|
|
170
176
|
|
|
171
|
-
it
|
|
177
|
+
it "includes error description in redirect uri" do
|
|
172
178
|
expect(redirect_uri.match(/error_description=(.+)&?/)[1]).to_not be_nil
|
|
173
179
|
end
|
|
174
180
|
|
|
175
|
-
it
|
|
181
|
+
it "does not issue any access token" do
|
|
176
182
|
expect(Doorkeeper::AccessToken.all).to be_empty
|
|
177
183
|
end
|
|
178
184
|
end
|
|
179
185
|
|
|
180
|
-
describe
|
|
186
|
+
describe "POST #create with application already authorized" do
|
|
181
187
|
before do
|
|
182
188
|
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
|
183
189
|
|
|
184
190
|
access_token.save!
|
|
185
|
-
|
|
191
|
+
|
|
192
|
+
post :create, params: {
|
|
193
|
+
client_id: client.uid,
|
|
194
|
+
response_type: "token",
|
|
195
|
+
redirect_uri: client.redirect_uri,
|
|
196
|
+
}
|
|
186
197
|
end
|
|
187
198
|
|
|
188
|
-
it
|
|
189
|
-
expect(response.query_params[
|
|
199
|
+
it "returns the existing access token in a fragment" do
|
|
200
|
+
expect(response.query_params["access_token"]).to eq(access_token.token)
|
|
190
201
|
end
|
|
191
202
|
|
|
192
|
-
it
|
|
203
|
+
it "does not creates a new access token" do
|
|
193
204
|
expect(Doorkeeper::AccessToken.count).to eq(1)
|
|
194
205
|
end
|
|
195
206
|
end
|
|
196
207
|
|
|
197
|
-
describe
|
|
208
|
+
describe "POST #create with callbacks" do
|
|
198
209
|
after do
|
|
199
|
-
client.update_attribute :redirect_uri,
|
|
210
|
+
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
|
200
211
|
end
|
|
201
212
|
|
|
202
|
-
describe
|
|
213
|
+
describe "when successful" do
|
|
203
214
|
after do
|
|
204
|
-
post :create, params: {
|
|
215
|
+
post :create, params: {
|
|
216
|
+
client_id: client.uid,
|
|
217
|
+
response_type: "token",
|
|
218
|
+
redirect_uri: client.redirect_uri,
|
|
219
|
+
}
|
|
205
220
|
end
|
|
206
221
|
|
|
207
|
-
it
|
|
208
|
-
expect(Doorkeeper.configuration)
|
|
222
|
+
it "should call :before_successful_authorization callback" do
|
|
223
|
+
expect(Doorkeeper.configuration)
|
|
224
|
+
.to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
|
|
209
225
|
end
|
|
210
226
|
|
|
211
|
-
it
|
|
212
|
-
expect(Doorkeeper.configuration)
|
|
227
|
+
it "should call :after_successful_authorization callback" do
|
|
228
|
+
expect(Doorkeeper.configuration)
|
|
229
|
+
.to receive_message_chain(:after_successful_authorization, :call).with(instance_of(described_class))
|
|
213
230
|
end
|
|
214
231
|
end
|
|
215
232
|
|
|
216
|
-
describe
|
|
233
|
+
describe "with errors" do
|
|
217
234
|
after do
|
|
218
|
-
post :create, params: { client_id: client.uid, response_type:
|
|
235
|
+
post :create, params: { client_id: client.uid, response_type: "token", redirect_uri: "bad_uri" }
|
|
219
236
|
end
|
|
220
237
|
|
|
221
|
-
it
|
|
238
|
+
it "should not call :before_successful_authorization callback" do
|
|
222
239
|
expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
|
|
223
240
|
end
|
|
224
241
|
|
|
225
|
-
it
|
|
242
|
+
it "should not call :after_successful_authorization callback" do
|
|
226
243
|
expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
|
|
227
244
|
end
|
|
228
245
|
end
|
|
229
246
|
end
|
|
230
247
|
|
|
231
|
-
describe
|
|
248
|
+
describe "GET #new token request with native url and skip_authorization true" do
|
|
232
249
|
before do
|
|
233
250
|
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc do
|
|
234
251
|
true
|
|
235
252
|
end)
|
|
236
|
-
|
|
237
|
-
|
|
253
|
+
|
|
254
|
+
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
|
255
|
+
|
|
256
|
+
get :new, params: {
|
|
257
|
+
client_id: client.uid,
|
|
258
|
+
response_type: "token",
|
|
259
|
+
redirect_uri: client.redirect_uri,
|
|
260
|
+
}
|
|
238
261
|
end
|
|
239
262
|
|
|
240
|
-
it
|
|
263
|
+
it "should redirect immediately" do
|
|
241
264
|
expect(response).to be_redirect
|
|
242
|
-
expect(response.location).to match(/oauth
|
|
265
|
+
expect(response.location).to match(%r{/oauth/token/info\?access_token=})
|
|
243
266
|
end
|
|
244
267
|
|
|
245
|
-
it
|
|
268
|
+
it "should not issue a grant" do
|
|
246
269
|
expect(Doorkeeper::AccessGrant.count).to be 0
|
|
247
270
|
end
|
|
248
271
|
|
|
249
|
-
it
|
|
272
|
+
it "should issue a token" do
|
|
250
273
|
expect(Doorkeeper::AccessToken.count).to be 1
|
|
251
274
|
end
|
|
252
275
|
end
|
|
253
276
|
|
|
254
|
-
describe
|
|
277
|
+
describe "GET #new code request with native url and skip_authorization true" do
|
|
255
278
|
before do
|
|
256
279
|
allow(Doorkeeper.configuration).to receive(:grant_flows).and_return(%w[authorization_code])
|
|
257
280
|
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc do
|
|
258
281
|
true
|
|
259
282
|
end)
|
|
260
|
-
|
|
261
|
-
|
|
283
|
+
|
|
284
|
+
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
|
285
|
+
|
|
286
|
+
get :new, params: {
|
|
287
|
+
client_id: client.uid,
|
|
288
|
+
response_type: "code",
|
|
289
|
+
redirect_uri: client.redirect_uri,
|
|
290
|
+
}
|
|
262
291
|
end
|
|
263
292
|
|
|
264
|
-
it
|
|
293
|
+
it "should redirect immediately" do
|
|
265
294
|
expect(response).to be_redirect
|
|
266
|
-
expect(response.location)
|
|
295
|
+
expect(response.location)
|
|
296
|
+
.to match(%r{/oauth/authorize/native\?code=#{Doorkeeper::AccessGrant.first.token}})
|
|
267
297
|
end
|
|
268
298
|
|
|
269
|
-
it
|
|
299
|
+
it "should issue a grant" do
|
|
270
300
|
expect(Doorkeeper::AccessGrant.count).to be 1
|
|
271
301
|
end
|
|
272
302
|
|
|
273
|
-
it
|
|
303
|
+
it "should not issue a token" do
|
|
274
304
|
expect(Doorkeeper::AccessToken.count).to be 0
|
|
275
305
|
end
|
|
276
306
|
end
|
|
277
307
|
|
|
278
|
-
describe
|
|
308
|
+
describe "GET #new with skip_authorization true" do
|
|
279
309
|
before do
|
|
280
310
|
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc do
|
|
281
311
|
true
|
|
282
312
|
end)
|
|
283
|
-
|
|
313
|
+
|
|
314
|
+
get :new, params: {
|
|
315
|
+
client_id: client.uid,
|
|
316
|
+
response_type: "token",
|
|
317
|
+
redirect_uri: client.redirect_uri,
|
|
318
|
+
}
|
|
284
319
|
end
|
|
285
320
|
|
|
286
|
-
it
|
|
321
|
+
it "should redirect immediately" do
|
|
287
322
|
expect(response).to be_redirect
|
|
288
|
-
expect(response.location).to match(
|
|
323
|
+
expect(response.location).to match(/^#{client.redirect_uri}/)
|
|
289
324
|
end
|
|
290
325
|
|
|
291
|
-
it
|
|
326
|
+
it "should issue a token" do
|
|
292
327
|
expect(Doorkeeper::AccessToken.count).to be 1
|
|
293
328
|
end
|
|
294
329
|
|
|
295
|
-
it
|
|
296
|
-
expect(response.query_params[
|
|
330
|
+
it "includes token type in fragment" do
|
|
331
|
+
expect(response.query_params["token_type"]).to eq("Bearer")
|
|
297
332
|
end
|
|
298
333
|
|
|
299
|
-
it
|
|
300
|
-
expect(response.query_params[
|
|
334
|
+
it "includes token expiration in fragment" do
|
|
335
|
+
expect(response.query_params["expires_in"].to_i).to eq(1234)
|
|
301
336
|
end
|
|
302
337
|
|
|
303
|
-
it
|
|
338
|
+
it "issues the token for the current client" do
|
|
304
339
|
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
|
305
340
|
end
|
|
306
341
|
|
|
307
|
-
it
|
|
342
|
+
it "issues the token for the current resource owner" do
|
|
308
343
|
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
|
309
344
|
end
|
|
310
345
|
end
|
|
311
346
|
|
|
312
|
-
describe
|
|
347
|
+
describe "GET #new in API mode" do
|
|
313
348
|
before do
|
|
314
349
|
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
|
315
|
-
|
|
350
|
+
|
|
351
|
+
get :new, params: {
|
|
352
|
+
client_id: client.uid,
|
|
353
|
+
response_type: "token",
|
|
354
|
+
redirect_uri: client.redirect_uri,
|
|
355
|
+
}
|
|
316
356
|
end
|
|
317
357
|
|
|
318
|
-
it
|
|
358
|
+
it "should render success" do
|
|
319
359
|
expect(response).to be_successful
|
|
320
360
|
end
|
|
321
361
|
|
|
322
362
|
it "sets status to pre-authorization" do
|
|
323
|
-
expect(json_response["status"]).to eq(I18n.t(
|
|
363
|
+
expect(json_response["status"]).to eq(I18n.t("doorkeeper.pre_authorization.status"))
|
|
324
364
|
end
|
|
325
365
|
|
|
326
366
|
it "sets correct values" do
|
|
327
|
-
expect(json_response[
|
|
328
|
-
expect(json_response[
|
|
329
|
-
expect(json_response[
|
|
330
|
-
expect(json_response[
|
|
331
|
-
expect(json_response[
|
|
367
|
+
expect(json_response["client_id"]).to eq(client.uid)
|
|
368
|
+
expect(json_response["redirect_uri"]).to eq(client.redirect_uri)
|
|
369
|
+
expect(json_response["state"]).to be_nil
|
|
370
|
+
expect(json_response["response_type"]).to eq("token")
|
|
371
|
+
expect(json_response["scope"]).to eq("")
|
|
332
372
|
end
|
|
333
373
|
end
|
|
334
374
|
|
|
335
|
-
describe
|
|
375
|
+
describe "GET #new in API mode with skip_authorization true" do
|
|
336
376
|
before do
|
|
337
377
|
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { true })
|
|
338
378
|
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
|
339
379
|
|
|
340
|
-
get :new, params: {
|
|
380
|
+
get :new, params: {
|
|
381
|
+
client_id: client.uid,
|
|
382
|
+
response_type: "token",
|
|
383
|
+
redirect_uri: client.redirect_uri,
|
|
384
|
+
}
|
|
341
385
|
end
|
|
342
386
|
|
|
343
|
-
it
|
|
387
|
+
it "should render success" do
|
|
344
388
|
expect(response).to be_successful
|
|
345
389
|
end
|
|
346
390
|
|
|
347
|
-
it
|
|
391
|
+
it "should issue a token" do
|
|
348
392
|
expect(Doorkeeper::AccessToken.count).to be 1
|
|
349
393
|
end
|
|
350
394
|
|
|
@@ -358,7 +402,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
|
|
|
358
402
|
expect(redirect_uri.match(/token_type=(\w+)&?/)[1]).to eq "Bearer"
|
|
359
403
|
expect(redirect_uri.match(/expires_in=(\d+)&?/)[1].to_i).to eq 1234
|
|
360
404
|
expect(
|
|
361
|
-
redirect_uri.match(/access_token=([a-
|
|
405
|
+
redirect_uri.match(/access_token=([a-zA-Z0-9\-_]+)&?/)[1]
|
|
362
406
|
).to eq Doorkeeper::AccessToken.first.token
|
|
363
407
|
end
|
|
364
408
|
|
|
@@ -371,101 +415,104 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
|
|
|
371
415
|
end
|
|
372
416
|
end
|
|
373
417
|
|
|
374
|
-
describe
|
|
418
|
+
describe "GET #new with errors" do
|
|
375
419
|
before do
|
|
376
420
|
default_scopes_exist :public
|
|
377
|
-
get :new, params: { an_invalid:
|
|
421
|
+
get :new, params: { an_invalid: "request" }
|
|
378
422
|
end
|
|
379
423
|
|
|
380
|
-
it
|
|
424
|
+
it "does not redirect" do
|
|
381
425
|
expect(response).to_not be_redirect
|
|
382
426
|
end
|
|
383
427
|
|
|
384
|
-
it
|
|
428
|
+
it "does not issue any token" do
|
|
385
429
|
expect(Doorkeeper::AccessGrant.count).to eq 0
|
|
386
430
|
expect(Doorkeeper::AccessToken.count).to eq 0
|
|
387
431
|
end
|
|
388
432
|
end
|
|
389
433
|
|
|
390
|
-
describe
|
|
434
|
+
describe "GET #new in API mode with errors" do
|
|
391
435
|
let(:response_json_body) { JSON.parse(response.body) }
|
|
392
436
|
|
|
393
437
|
before do
|
|
394
438
|
default_scopes_exist :public
|
|
395
439
|
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
|
396
|
-
get :new, params: { an_invalid:
|
|
440
|
+
get :new, params: { an_invalid: "request" }
|
|
397
441
|
end
|
|
398
442
|
|
|
399
|
-
it
|
|
443
|
+
it "should render bad request" do
|
|
400
444
|
expect(response).to have_http_status(:bad_request)
|
|
401
445
|
end
|
|
402
446
|
|
|
403
|
-
it
|
|
404
|
-
expect(response_json_body[
|
|
447
|
+
it "includes error in body" do
|
|
448
|
+
expect(response_json_body["error"]).to eq("unsupported_response_type")
|
|
405
449
|
end
|
|
406
450
|
|
|
407
|
-
it
|
|
408
|
-
expect(response_json_body[
|
|
451
|
+
it "includes error description in body" do
|
|
452
|
+
expect(response_json_body["error_description"])
|
|
453
|
+
.to eq(translated_error_message(:unsupported_response_type))
|
|
409
454
|
end
|
|
410
455
|
|
|
411
|
-
it
|
|
456
|
+
it "does not issue any token" do
|
|
412
457
|
expect(Doorkeeper::AccessGrant.count).to eq 0
|
|
413
458
|
expect(Doorkeeper::AccessToken.count).to eq 0
|
|
414
459
|
end
|
|
415
460
|
end
|
|
416
461
|
|
|
417
|
-
describe
|
|
462
|
+
describe "GET #new with callbacks" do
|
|
418
463
|
after do
|
|
419
|
-
client.update_attribute :redirect_uri,
|
|
420
|
-
get :new, params: { client_id: client.uid, response_type:
|
|
464
|
+
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
|
465
|
+
get :new, params: { client_id: client.uid, response_type: "token", redirect_uri: client.redirect_uri }
|
|
421
466
|
end
|
|
422
467
|
|
|
423
|
-
describe
|
|
468
|
+
describe "when authorizing" do
|
|
424
469
|
before do
|
|
425
470
|
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { true })
|
|
426
471
|
end
|
|
427
472
|
|
|
428
|
-
it
|
|
429
|
-
expect(Doorkeeper.configuration)
|
|
473
|
+
it "should call :before_successful_authorization callback" do
|
|
474
|
+
expect(Doorkeeper.configuration)
|
|
475
|
+
.to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
|
|
430
476
|
end
|
|
431
477
|
|
|
432
|
-
it
|
|
433
|
-
expect(Doorkeeper.configuration)
|
|
478
|
+
it "should call :after_successful_authorization callback" do
|
|
479
|
+
expect(Doorkeeper.configuration)
|
|
480
|
+
.to receive_message_chain(:after_successful_authorization, :call).with(instance_of(described_class))
|
|
434
481
|
end
|
|
435
482
|
end
|
|
436
483
|
|
|
437
|
-
describe
|
|
484
|
+
describe "when not authorizing" do
|
|
438
485
|
before do
|
|
439
486
|
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { false })
|
|
440
487
|
end
|
|
441
488
|
|
|
442
|
-
it
|
|
489
|
+
it "should not call :before_successful_authorization callback" do
|
|
443
490
|
expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
|
|
444
491
|
end
|
|
445
492
|
|
|
446
|
-
it
|
|
493
|
+
it "should not call :after_successful_authorization callback" do
|
|
447
494
|
expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
|
|
448
495
|
end
|
|
449
496
|
end
|
|
450
497
|
|
|
451
|
-
describe
|
|
498
|
+
describe "when not authorizing in api mode" do
|
|
452
499
|
before do
|
|
453
500
|
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { false })
|
|
454
501
|
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
|
455
502
|
end
|
|
456
503
|
|
|
457
|
-
it
|
|
504
|
+
it "should not call :before_successful_authorization callback" do
|
|
458
505
|
expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
|
|
459
506
|
end
|
|
460
507
|
|
|
461
|
-
it
|
|
508
|
+
it "should not call :after_successful_authorization callback" do
|
|
462
509
|
expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
|
|
463
510
|
end
|
|
464
511
|
end
|
|
465
512
|
end
|
|
466
513
|
|
|
467
|
-
describe
|
|
468
|
-
it
|
|
514
|
+
describe "authorize response memoization" do
|
|
515
|
+
it "memoizes the result of the authorization" do
|
|
469
516
|
strategy = double(:strategy, authorize: true)
|
|
470
517
|
expect(strategy).to receive(:authorize).once
|
|
471
518
|
allow(controller).to receive(:strategy) { strategy }
|