doorkeeper 5.1.0.rc2 → 5.1.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/.hound.yml +2 -1
- data/.rubocop.yml +37 -4
- data/.travis.yml +4 -27
- data/Appraisals +8 -12
- data/Gemfile +6 -2
- data/NEWS.md +16 -0
- data/README.md +11 -2
- data/Rakefile +10 -8
- data/app/controllers/doorkeeper/application_controller.rb +1 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -13
- data/app/controllers/doorkeeper/applications_controller.rb +17 -5
- data/app/controllers/doorkeeper/token_info_controller.rb +1 -1
- data/app/controllers/doorkeeper/tokens_controller.rb +7 -7
- data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
- data/app/validators/redirect_uri_validator.rb +5 -2
- data/app/views/doorkeeper/applications/_form.html.erb +6 -0
- data/bin/console +5 -4
- data/config/locales/en.yml +1 -0
- data/doorkeeper.gemspec +24 -22
- data/gemfiles/rails_5_0.gemfile +2 -1
- data/gemfiles/rails_5_1.gemfile +2 -1
- data/gemfiles/rails_5_2.gemfile +2 -1
- data/gemfiles/rails_6_0.gemfile +1 -0
- data/gemfiles/rails_master.gemfile +1 -0
- data/lib/doorkeeper.rb +68 -66
- data/lib/doorkeeper/config.rb +53 -90
- data/lib/doorkeeper/config/option.rb +64 -0
- data/lib/doorkeeper/engine.rb +1 -1
- data/lib/doorkeeper/grape/authorization_decorator.rb +4 -4
- data/lib/doorkeeper/grape/helpers.rb +3 -3
- data/lib/doorkeeper/helpers/controller.rb +1 -1
- data/lib/doorkeeper/models/access_grant_mixin.rb +4 -2
- data/lib/doorkeeper/models/access_token_mixin.rb +10 -10
- data/lib/doorkeeper/models/application_mixin.rb +1 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +1 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +1 -6
- data/lib/doorkeeper/models/concerns/revocable.rb +2 -1
- data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +2 -0
- data/lib/doorkeeper/oauth.rb +5 -5
- data/lib/doorkeeper/oauth/authorization/code.rb +1 -1
- data/lib/doorkeeper/oauth/authorization/token.rb +9 -6
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +1 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +5 -3
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
- data/lib/doorkeeper/oauth/error_response.rb +5 -5
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +1 -1
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -1
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -1
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +6 -2
- data/lib/doorkeeper/oauth/invalid_token_response.rb +1 -1
- data/lib/doorkeeper/oauth/pre_authorization.rb +4 -3
- data/lib/doorkeeper/oauth/refresh_token_request.rb +1 -1
- data/lib/doorkeeper/oauth/scopes.rb +5 -3
- data/lib/doorkeeper/oauth/token.rb +2 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +4 -4
- data/lib/doorkeeper/oauth/token_response.rb +9 -9
- data/lib/doorkeeper/orm/active_record.rb +6 -6
- data/lib/doorkeeper/orm/active_record/access_grant.rb +5 -12
- data/lib/doorkeeper/orm/active_record/access_token.rb +6 -13
- data/lib/doorkeeper/orm/active_record/application.rb +6 -5
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
- data/lib/doorkeeper/rails/helpers.rb +1 -1
- data/lib/doorkeeper/rails/routes.rb +11 -11
- data/lib/doorkeeper/rails/routes/mapping.rb +7 -7
- data/lib/doorkeeper/rake.rb +1 -1
- data/lib/doorkeeper/rake/db.rake +13 -13
- data/lib/doorkeeper/request.rb +1 -1
- data/lib/doorkeeper/secret_storing/base.rb +7 -6
- data/lib/doorkeeper/secret_storing/bcrypt.rb +4 -3
- data/lib/doorkeeper/secret_storing/plain.rb +4 -4
- data/lib/doorkeeper/secret_storing/sha256_hash.rb +3 -2
- data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
- data/lib/doorkeeper/version.rb +2 -2
- 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 +30 -5
- data/lib/generators/doorkeeper/templates/migration.rb.erb +15 -7
- data/lib/generators/doorkeeper/views_generator.rb +6 -4
- data/spec/controllers/application_metal_controller_spec.rb +10 -10
- data/spec/controllers/applications_controller_spec.rb +54 -52
- data/spec/controllers/authorizations_controller_spec.rb +136 -142
- data/spec/controllers/protected_resources_controller_spec.rb +78 -76
- data/spec/controllers/token_info_controller_spec.rb +13 -11
- data/spec/controllers/tokens_controller_spec.rb +109 -94
- data/spec/dummy/Rakefile +3 -1
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +2 -0
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -2
- data/spec/dummy/app/controllers/home_controller.rb +5 -3
- 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.ru +3 -1
- data/spec/dummy/config/application.rb +13 -0
- 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 +3 -1
- data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
- data/spec/dummy/config/initializers/doorkeeper.rb +5 -2
- 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/db/migrate/20151223192035_create_doorkeeper_tables.rb +17 -10
- data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +2 -0
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/dummy/script/rails +5 -3
- data/spec/factories.rb +5 -3
- 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 +17 -15
- 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 -0
- data/spec/generators/views_generator_spec.rb +14 -12
- data/spec/grape/grape_integration_spec.rb +34 -32
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +9 -7
- data/spec/lib/config_spec.rb +137 -136
- data/spec/lib/doorkeeper_spec.rb +3 -1
- data/spec/lib/models/expirable_spec.rb +12 -10
- data/spec/lib/models/reusable_spec.rb +6 -6
- data/spec/lib/models/revocable_spec.rb +8 -6
- data/spec/lib/models/scopes_spec.rb +19 -17
- data/spec/lib/models/secret_storable_spec.rb +71 -49
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +17 -15
- data/spec/lib/oauth/authorization_code_request_spec.rb +18 -12
- data/spec/lib/oauth/base_request_spec.rb +20 -8
- data/spec/lib/oauth/base_response_spec.rb +3 -1
- data/spec/lib/oauth/client/credentials_spec.rb +24 -22
- data/spec/lib/oauth/client_credentials/creator_spec.rb +13 -11
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -18
- data/spec/lib/oauth/client_credentials/validation_spec.rb +17 -15
- data/spec/lib/oauth/client_credentials_integration_spec.rb +7 -5
- 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 +8 -6
- data/spec/lib/oauth/code_response_spec.rb +9 -7
- data/spec/lib/oauth/error_response_spec.rb +14 -12
- 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 +35 -33
- data/spec/lib/oauth/helpers/unique_token_spec.rb +8 -6
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +103 -101
- data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +52 -34
- data/spec/lib/oauth/pre_authorization_spec.rb +64 -62
- data/spec/lib/oauth/refresh_token_request_spec.rb +36 -33
- data/spec/lib/oauth/scopes_spec.rb +63 -61
- data/spec/lib/oauth/token_request_spec.rb +66 -26
- data/spec/lib/oauth/token_response_spec.rb +39 -37
- data/spec/lib/oauth/token_spec.rb +51 -49
- data/spec/lib/request/strategy_spec.rb +3 -1
- data/spec/lib/secret_storing/base_spec.rb +23 -23
- data/spec/lib/secret_storing/bcrypt_spec.rb +18 -18
- data/spec/lib/secret_storing/plain_spec.rb +17 -17
- data/spec/lib/secret_storing/sha256_hash_spec.rb +16 -16
- data/spec/lib/server_spec.rb +16 -14
- data/spec/lib/stale_records_cleaner_spec.rb +17 -17
- data/spec/models/doorkeeper/access_grant_spec.rb +30 -26
- data/spec/models/doorkeeper/access_token_spec.rb +97 -95
- data/spec/models/doorkeeper/application_spec.rb +98 -57
- data/spec/requests/applications/applications_request_spec.rb +98 -66
- data/spec/requests/applications/authorized_applications_spec.rb +20 -18
- data/spec/requests/endpoints/authorization_spec.rb +25 -23
- data/spec/requests/endpoints/token_spec.rb +38 -36
- data/spec/requests/flows/authorization_code_errors_spec.rb +26 -24
- data/spec/requests/flows/authorization_code_spec.rb +161 -159
- data/spec/requests/flows/client_credentials_spec.rb +53 -51
- data/spec/requests/flows/implicit_grant_errors_spec.rb +10 -8
- data/spec/requests/flows/implicit_grant_spec.rb +27 -25
- data/spec/requests/flows/password_spec.rb +56 -54
- data/spec/requests/flows/refresh_token_spec.rb +45 -43
- data/spec/requests/flows/revoke_token_spec.rb +29 -27
- 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 +35 -33
- data/spec/routing/custom_controller_routes_spec.rb +67 -65
- data/spec/routing/default_routes_spec.rb +22 -20
- data/spec/routing/scoped_routes_spec.rb +20 -18
- data/spec/spec_helper.rb +14 -13
- data/spec/spec_helper_integration.rb +3 -1
- data/spec/support/dependencies/factory_bot.rb +3 -1
- data/spec/support/doorkeeper_rspec.rb +3 -1
- 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 +3 -1
- data/spec/support/helpers/request_spec_helper.rb +5 -3
- data/spec/support/helpers/url_helper.rb +9 -7
- 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 +18 -16
- data/spec/support/shared/hashing_shared_context.rb +3 -3
- data/spec/support/shared/models_shared_examples.rb +12 -10
- data/spec/validators/redirect_uri_validator_spec.rb +74 -45
- data/spec/version/version_spec.rb +7 -5
- metadata +12 -16
- data/gemfiles/rails_4_2.gemfile +0 -17
- data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -8
- data/spec/support/ruby_2_6_rails_4_2_patch.rb +0 -14
@@ -1,12 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
module ControllerActions
|
4
6
|
def index
|
5
|
-
render plain:
|
7
|
+
render plain: "index"
|
6
8
|
end
|
7
9
|
|
8
10
|
def show
|
9
|
-
render plain:
|
11
|
+
render plain: "show"
|
10
12
|
end
|
11
13
|
|
12
14
|
def doorkeeper_unauthorized_render_options(*); end
|
@@ -14,98 +16,98 @@ module ControllerActions
|
|
14
16
|
def doorkeeper_forbidden_render_options(*); end
|
15
17
|
end
|
16
18
|
|
17
|
-
describe
|
18
|
-
context
|
19
|
+
describe "doorkeeper authorize filter" do
|
20
|
+
context "accepts token code specified as" do
|
19
21
|
controller do
|
20
22
|
before_action :doorkeeper_authorize!
|
21
23
|
|
22
24
|
def index
|
23
|
-
render plain:
|
25
|
+
render plain: "index"
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
27
|
-
let(:token_string) {
|
29
|
+
let(:token_string) { "1A2BC3" }
|
28
30
|
let(:token) do
|
29
31
|
double(Doorkeeper::AccessToken,
|
30
32
|
acceptable?: true, previous_refresh_token: "",
|
31
33
|
revoke_previous_refresh_token!: true)
|
32
34
|
end
|
33
35
|
|
34
|
-
it
|
36
|
+
it "access_token param" do
|
35
37
|
expect(Doorkeeper::AccessToken).to receive(:by_token).with(token_string).and_return(token)
|
36
38
|
get :index, params: { access_token: token_string }
|
37
39
|
end
|
38
40
|
|
39
|
-
it
|
41
|
+
it "bearer_token param" do
|
40
42
|
expect(Doorkeeper::AccessToken).to receive(:by_token).with(token_string).and_return(token)
|
41
43
|
get :index, params: { bearer_token: token_string }
|
42
44
|
end
|
43
45
|
|
44
|
-
it
|
46
|
+
it "Authorization header" do
|
45
47
|
expect(Doorkeeper::AccessToken).to receive(:by_token).with(token_string).and_return(token)
|
46
|
-
request.env[
|
48
|
+
request.env["HTTP_AUTHORIZATION"] = "Bearer #{token_string}"
|
47
49
|
get :index
|
48
50
|
end
|
49
51
|
|
50
|
-
it
|
52
|
+
it "different kind of Authorization header" do
|
51
53
|
expect(Doorkeeper::AccessToken).not_to receive(:by_token)
|
52
|
-
request.env[
|
54
|
+
request.env["HTTP_AUTHORIZATION"] = "MAC #{token_string}"
|
53
55
|
get :index
|
54
56
|
end
|
55
57
|
|
56
|
-
it
|
58
|
+
it "does not change Authorization header value" do
|
57
59
|
expect(Doorkeeper::AccessToken).to receive(:by_token).exactly(2).times.and_return(token)
|
58
|
-
request.env[
|
60
|
+
request.env["HTTP_AUTHORIZATION"] = "Bearer #{token_string}"
|
59
61
|
get :index
|
60
62
|
controller.send(:remove_instance_variable, :@doorkeeper_token)
|
61
63
|
get :index
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
|
-
context
|
67
|
+
context "defined for all actions" do
|
66
68
|
controller do
|
67
69
|
before_action :doorkeeper_authorize!
|
68
70
|
|
69
71
|
include ControllerActions
|
70
72
|
end
|
71
73
|
|
72
|
-
context
|
73
|
-
it
|
74
|
+
context "with valid token", token: :valid do
|
75
|
+
it "allows into index action" do
|
74
76
|
get :index, params: { access_token: token_string }
|
75
77
|
expect(response).to be_successful
|
76
78
|
end
|
77
79
|
|
78
|
-
it
|
79
|
-
get :show, params: { id:
|
80
|
+
it "allows into show action" do
|
81
|
+
get :show, params: { id: "4", access_token: token_string }
|
80
82
|
expect(response).to be_successful
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
84
|
-
context
|
85
|
-
it
|
86
|
+
context "with invalid token", token: :invalid do
|
87
|
+
it "does not allow into index action" do
|
86
88
|
get :index, params: { access_token: token_string }
|
87
89
|
expect(response.status).to eq 401
|
88
|
-
expect(response.header[
|
90
|
+
expect(response.header["WWW-Authenticate"]).to match(/^Bearer/)
|
89
91
|
end
|
90
92
|
|
91
|
-
it
|
92
|
-
get :show, params: { id:
|
93
|
+
it "does not allow into show action" do
|
94
|
+
get :show, params: { id: "4", access_token: token_string }
|
93
95
|
expect(response.status).to eq 401
|
94
|
-
expect(response.header[
|
96
|
+
expect(response.header["WWW-Authenticate"]).to match(/^Bearer/)
|
95
97
|
end
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
99
|
-
context
|
101
|
+
context "defined with scopes" do
|
100
102
|
controller do
|
101
103
|
before_action -> { doorkeeper_authorize! :write }
|
102
104
|
|
103
105
|
include ControllerActions
|
104
106
|
end
|
105
107
|
|
106
|
-
let(:token_string) {
|
108
|
+
let(:token_string) { "1A2DUWE" }
|
107
109
|
|
108
|
-
it
|
110
|
+
it "allows if the token has particular scopes" do
|
109
111
|
token = double(Doorkeeper::AccessToken,
|
110
112
|
accessible?: true, scopes: %w[write public],
|
111
113
|
previous_refresh_token: "",
|
@@ -119,9 +121,9 @@ describe 'doorkeeper authorize filter' do
|
|
119
121
|
expect(response).to be_successful
|
120
122
|
end
|
121
123
|
|
122
|
-
it
|
124
|
+
it "does not allow if the token does not include given scope" do
|
123
125
|
token = double(Doorkeeper::AccessToken,
|
124
|
-
accessible?: true, scopes: [
|
126
|
+
accessible?: true, scopes: ["public"], revoked?: false,
|
125
127
|
expired?: false, previous_refresh_token: "",
|
126
128
|
revoke_previous_refresh_token!: true)
|
127
129
|
expect(
|
@@ -131,18 +133,18 @@ describe 'doorkeeper authorize filter' do
|
|
131
133
|
|
132
134
|
get :index, params: { access_token: token_string }
|
133
135
|
expect(response.status).to eq 403
|
134
|
-
expect(response.header).to_not include(
|
136
|
+
expect(response.header).to_not include("WWW-Authenticate")
|
135
137
|
end
|
136
138
|
end
|
137
139
|
|
138
|
-
context
|
140
|
+
context "when custom unauthorized render options are configured" do
|
139
141
|
controller do
|
140
142
|
before_action :doorkeeper_authorize!
|
141
143
|
|
142
144
|
include ControllerActions
|
143
145
|
end
|
144
146
|
|
145
|
-
context
|
147
|
+
context "with a JSON custom render", token: :invalid do
|
146
148
|
before do
|
147
149
|
module ControllerActions
|
148
150
|
remove_method :doorkeeper_unauthorized_render_options
|
@@ -161,24 +163,24 @@ describe 'doorkeeper authorize filter' do
|
|
161
163
|
end
|
162
164
|
end
|
163
165
|
|
164
|
-
it
|
166
|
+
it "it renders a custom JSON response", token: :invalid do
|
165
167
|
get :index, params: { access_token: token_string }
|
166
168
|
expect(response.status).to eq 401
|
167
|
-
expect(response.content_type).to eq(
|
168
|
-
expect(response.header[
|
169
|
+
expect(response.content_type).to eq("application/json")
|
170
|
+
expect(response.header["WWW-Authenticate"]).to match(/^Bearer/)
|
169
171
|
|
170
172
|
expect(json_response).not_to be_nil
|
171
|
-
expect(json_response[
|
173
|
+
expect(json_response["error_message"]).to match("token is invalid")
|
172
174
|
end
|
173
175
|
end
|
174
176
|
|
175
|
-
context
|
177
|
+
context "with a text custom render", token: :invalid do
|
176
178
|
before do
|
177
179
|
module ControllerActions
|
178
180
|
remove_method :doorkeeper_unauthorized_render_options
|
179
181
|
|
180
182
|
def doorkeeper_unauthorized_render_options(**)
|
181
|
-
{ plain:
|
183
|
+
{ plain: "Unauthorized" }
|
182
184
|
end
|
183
185
|
end
|
184
186
|
end
|
@@ -191,17 +193,17 @@ describe 'doorkeeper authorize filter' do
|
|
191
193
|
end
|
192
194
|
end
|
193
195
|
|
194
|
-
it
|
196
|
+
it "it renders a custom text response", token: :invalid do
|
195
197
|
get :index, params: { access_token: token_string }
|
196
198
|
expect(response.status).to eq 401
|
197
|
-
expect(response.content_type).to eq(
|
198
|
-
expect(response.header[
|
199
|
-
expect(response.body).to eq(
|
199
|
+
expect(response.content_type).to eq("text/plain")
|
200
|
+
expect(response.header["WWW-Authenticate"]).to match(/^Bearer/)
|
201
|
+
expect(response.body).to eq("Unauthorized")
|
200
202
|
end
|
201
203
|
end
|
202
204
|
end
|
203
205
|
|
204
|
-
context
|
206
|
+
context "when custom forbidden render options are configured" do
|
205
207
|
before do
|
206
208
|
expect(Doorkeeper::AccessToken).to receive(:by_token).with(token_string).and_return(token)
|
207
209
|
expect(token).to receive(:acceptable?).with([:write]).and_return(false)
|
@@ -223,90 +225,90 @@ describe 'doorkeeper authorize filter' do
|
|
223
225
|
|
224
226
|
let(:token) do
|
225
227
|
double(Doorkeeper::AccessToken,
|
226
|
-
accessible?: true, scopes: [
|
228
|
+
accessible?: true, scopes: ["public"], revoked?: false,
|
227
229
|
expired?: false, previous_refresh_token: "",
|
228
230
|
revoke_previous_refresh_token!: true)
|
229
231
|
end
|
230
232
|
|
231
|
-
let(:token_string) {
|
233
|
+
let(:token_string) { "1A2DUWE" }
|
232
234
|
|
233
|
-
context
|
235
|
+
context "with a JSON custom render" do
|
234
236
|
before do
|
235
237
|
module ControllerActions
|
236
238
|
remove_method :doorkeeper_forbidden_render_options
|
237
239
|
|
238
240
|
def doorkeeper_forbidden_render_options(*)
|
239
|
-
{ json: { error_message:
|
241
|
+
{ json: { error_message: "Forbidden" } }
|
240
242
|
end
|
241
243
|
end
|
242
244
|
end
|
243
245
|
|
244
|
-
it
|
246
|
+
it "renders a custom JSON response" do
|
245
247
|
get :index, params: { access_token: token_string }
|
246
|
-
expect(response.header).to_not include(
|
247
|
-
expect(response.content_type).to eq(
|
248
|
+
expect(response.header).to_not include("WWW-Authenticate")
|
249
|
+
expect(response.content_type).to eq("application/json")
|
248
250
|
expect(response.status).to eq 403
|
249
251
|
|
250
252
|
expect(json_response).not_to be_nil
|
251
|
-
expect(json_response[
|
253
|
+
expect(json_response["error_message"]).to match("Forbidden")
|
252
254
|
end
|
253
255
|
end
|
254
256
|
|
255
|
-
context
|
257
|
+
context "with a status and JSON custom render" do
|
256
258
|
before do
|
257
259
|
module ControllerActions
|
258
260
|
remove_method :doorkeeper_forbidden_render_options
|
259
261
|
def doorkeeper_forbidden_render_options(*)
|
260
|
-
{ json: { error_message:
|
261
|
-
respond_not_found_when_forbidden: true }
|
262
|
+
{ json: { error_message: "Not Found" },
|
263
|
+
respond_not_found_when_forbidden: true, }
|
262
264
|
end
|
263
265
|
end
|
264
266
|
end
|
265
267
|
|
266
|
-
it
|
268
|
+
it "overrides the default status code" do
|
267
269
|
get :index, params: { access_token: token_string }
|
268
270
|
expect(response.status).to eq 404
|
269
271
|
end
|
270
272
|
end
|
271
273
|
|
272
|
-
context
|
274
|
+
context "with a text custom render" do
|
273
275
|
before do
|
274
276
|
module ControllerActions
|
275
277
|
remove_method :doorkeeper_forbidden_render_options
|
276
278
|
|
277
279
|
def doorkeeper_forbidden_render_options(*)
|
278
|
-
{ plain:
|
280
|
+
{ plain: "Forbidden" }
|
279
281
|
end
|
280
282
|
end
|
281
283
|
end
|
282
284
|
|
283
|
-
it
|
285
|
+
it "renders a custom status code and text response" do
|
284
286
|
get :index, params: { access_token: token_string }
|
285
|
-
expect(response.header).to_not include(
|
287
|
+
expect(response.header).to_not include("WWW-Authenticate")
|
286
288
|
expect(response.status).to eq 403
|
287
|
-
expect(response.body).to eq(
|
289
|
+
expect(response.body).to eq("Forbidden")
|
288
290
|
end
|
289
291
|
end
|
290
292
|
|
291
|
-
context
|
293
|
+
context "with a status and text custom render" do
|
292
294
|
before do
|
293
295
|
module ControllerActions
|
294
296
|
remove_method :doorkeeper_forbidden_render_options
|
295
297
|
|
296
298
|
def doorkeeper_forbidden_render_options(*)
|
297
|
-
{ respond_not_found_when_forbidden: true, plain:
|
299
|
+
{ respond_not_found_when_forbidden: true, plain: "Not Found" }
|
298
300
|
end
|
299
301
|
end
|
300
302
|
end
|
301
303
|
|
302
|
-
it
|
304
|
+
it "overrides the default status code" do
|
303
305
|
get :index, params: { access_token: token_string }
|
304
306
|
expect(response.status).to eq 404
|
305
307
|
end
|
306
308
|
end
|
307
309
|
end
|
308
310
|
|
309
|
-
context
|
311
|
+
context "when handle_auth_errors option is set to :raise" do
|
310
312
|
subject { get :index, params: { access_token: token_string } }
|
311
313
|
|
312
314
|
before do
|
@@ -318,32 +320,32 @@ describe 'doorkeeper authorize filter' do
|
|
318
320
|
include ControllerActions
|
319
321
|
end
|
320
322
|
|
321
|
-
context
|
322
|
-
it
|
323
|
+
context "when token is unknown" do
|
324
|
+
it "raises Doorkeeper::Errors::TokenUnknown exception", token: :invalid do
|
323
325
|
expect { subject }.to raise_error(Doorkeeper::Errors::TokenUnknown)
|
324
326
|
end
|
325
327
|
end
|
326
328
|
|
327
|
-
context
|
328
|
-
it
|
329
|
+
context "when token is expired" do
|
330
|
+
it "raises Doorkeeper::Errors::TokenExpired exception", token: :expired do
|
329
331
|
expect { subject }.to raise_error(Doorkeeper::Errors::TokenExpired)
|
330
332
|
end
|
331
333
|
end
|
332
334
|
|
333
|
-
context
|
334
|
-
it
|
335
|
+
context "when token is revoked" do
|
336
|
+
it "raises Doorkeeper::Errors::TokenRevoked exception", token: :revoked do
|
335
337
|
expect { subject }.to raise_error(Doorkeeper::Errors::TokenRevoked)
|
336
338
|
end
|
337
339
|
end
|
338
340
|
|
339
|
-
context
|
340
|
-
it
|
341
|
+
context "when token is forbidden" do
|
342
|
+
it "raises Doorkeeper::Errors::TokenForbidden exception", token: :forbidden do
|
341
343
|
expect { subject }.to raise_error(Doorkeeper::Errors::TokenForbidden)
|
342
344
|
end
|
343
345
|
end
|
344
346
|
|
345
|
-
context
|
346
|
-
it
|
347
|
+
context "when token is valid" do
|
348
|
+
it "allows into index action", token: :valid do
|
347
349
|
expect(response).to be_successful
|
348
350
|
end
|
349
351
|
end
|
@@ -1,42 +1,44 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
describe Doorkeeper::TokenInfoController do
|
4
|
-
describe
|
6
|
+
describe "when requesting token info with valid token" do
|
5
7
|
let(:doorkeeper_token) { FactoryBot.create(:access_token) }
|
6
8
|
|
7
|
-
describe
|
8
|
-
it
|
9
|
+
describe "successful request" do
|
10
|
+
it "responds with token info" do
|
9
11
|
get :show, params: { access_token: doorkeeper_token.token }
|
10
12
|
|
11
13
|
expect(response.body).to eq(doorkeeper_token.to_json)
|
12
14
|
end
|
13
15
|
|
14
|
-
it
|
16
|
+
it "responds with a 200 status" do
|
15
17
|
get :show, params: { access_token: doorkeeper_token.token }
|
16
18
|
|
17
19
|
expect(response.status).to eq 200
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
|
-
describe
|
22
|
-
it
|
23
|
+
describe "invalid token response" do
|
24
|
+
it "responds with 401 when doorkeeper_token is not valid" do
|
23
25
|
get :show
|
24
26
|
|
25
27
|
expect(response.status).to eq 401
|
26
|
-
expect(response.headers[
|
28
|
+
expect(response.headers["WWW-Authenticate"]).to match(/^Bearer/)
|
27
29
|
end
|
28
30
|
|
29
|
-
it
|
31
|
+
it "responds with 401 when doorkeeper_token is invalid, expired or revoked" do
|
30
32
|
allow(controller).to receive(:doorkeeper_token).and_return(doorkeeper_token)
|
31
33
|
allow(doorkeeper_token).to receive(:accessible?).and_return(false)
|
32
34
|
|
33
35
|
get :show
|
34
36
|
|
35
37
|
expect(response.status).to eq 401
|
36
|
-
expect(response.headers[
|
38
|
+
expect(response.headers["WWW-Authenticate"]).to match(/^Bearer/)
|
37
39
|
end
|
38
40
|
|
39
|
-
it
|
41
|
+
it "responds body message for error" do
|
40
42
|
get :show
|
41
43
|
|
42
44
|
expect(response.body).to eq(
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
describe Doorkeeper::TokensController do
|
4
|
-
describe
|
6
|
+
describe "when authorization has succeeded" do
|
5
7
|
let(:token) { double(:token, authorize: true) }
|
6
8
|
|
7
|
-
it
|
8
|
-
skip
|
9
|
+
it "returns the authorization" do
|
10
|
+
skip "verify need of these specs"
|
9
11
|
|
10
12
|
expect(token).to receive(:authorization)
|
11
13
|
|
@@ -13,28 +15,28 @@ describe Doorkeeper::TokensController do
|
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
describe
|
17
|
-
it
|
18
|
+
describe "when authorization has failed" do
|
19
|
+
it "returns the error response" do
|
18
20
|
token = double(:token, authorize: false)
|
19
21
|
allow(controller).to receive(:token) { token }
|
20
22
|
|
21
23
|
post :create
|
22
24
|
|
23
25
|
expect(response.status).to eq 400
|
24
|
-
expect(response.headers[
|
26
|
+
expect(response.headers["WWW-Authenticate"]).to match(/Bearer/)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
28
|
-
describe
|
29
|
-
it
|
30
|
+
describe "when there is a failure due to a custom error" do
|
31
|
+
it "returns the error response with a custom message" do
|
30
32
|
# I18n looks for `doorkeeper.errors.messages.custom_message` in locale files
|
31
|
-
custom_message =
|
33
|
+
custom_message = "my_message"
|
32
34
|
allow(I18n).to receive(:translate)
|
33
35
|
.with(
|
34
36
|
custom_message,
|
35
37
|
hash_including(scope: %i[doorkeeper errors messages])
|
36
38
|
)
|
37
|
-
.and_return(
|
39
|
+
.and_return("Authorization custom message")
|
38
40
|
|
39
41
|
doorkeeper_error = Doorkeeper::Errors::DoorkeeperError.new(custom_message)
|
40
42
|
|
@@ -46,37 +48,37 @@ describe Doorkeeper::TokensController do
|
|
46
48
|
post :create
|
47
49
|
|
48
50
|
expected_response_body = {
|
49
|
-
"error"
|
50
|
-
"error_description" => "Authorization custom message"
|
51
|
+
"error" => custom_message,
|
52
|
+
"error_description" => "Authorization custom message",
|
51
53
|
}
|
52
54
|
expect(response.status).to eq 400
|
53
|
-
expect(response.headers[
|
55
|
+
expect(response.headers["WWW-Authenticate"]).to match(/Bearer/)
|
54
56
|
expect(JSON.parse(response.body)).to eq expected_response_body
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
58
60
|
# http://tools.ietf.org/html/rfc7009#section-2.2
|
59
|
-
describe
|
61
|
+
describe "revoking tokens" do
|
60
62
|
let(:client) { FactoryBot.create(:application) }
|
61
63
|
let(:access_token) { FactoryBot.create(:access_token, application: client) }
|
62
64
|
|
63
|
-
context
|
65
|
+
context "when associated app is public" do
|
64
66
|
let(:client) { FactoryBot.create(:application, confidential: false) }
|
65
67
|
|
66
|
-
it
|
68
|
+
it "returns 200" do
|
67
69
|
post :revoke, params: { token: access_token.token }
|
68
70
|
|
69
71
|
expect(response.status).to eq 200
|
70
72
|
end
|
71
73
|
|
72
|
-
it
|
74
|
+
it "revokes the access token" do
|
73
75
|
post :revoke, params: { token: access_token.token }
|
74
76
|
|
75
77
|
expect(access_token.reload).to have_attributes(revoked?: true)
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
context
|
81
|
+
context "when associated app is confidential" do
|
80
82
|
let(:client) { FactoryBot.create(:application, confidential: true) }
|
81
83
|
let(:oauth_client) { Doorkeeper::OAuth::Client.new(client) }
|
82
84
|
|
@@ -84,29 +86,29 @@ describe Doorkeeper::TokensController do
|
|
84
86
|
allow_any_instance_of(Doorkeeper::Server).to receive(:client) { oauth_client }
|
85
87
|
end
|
86
88
|
|
87
|
-
it
|
89
|
+
it "returns 200" do
|
88
90
|
post :revoke, params: { token: access_token.token }
|
89
91
|
|
90
92
|
expect(response.status).to eq 200
|
91
93
|
end
|
92
94
|
|
93
|
-
it
|
95
|
+
it "revokes the access token" do
|
94
96
|
post :revoke, params: { token: access_token.token }
|
95
97
|
|
96
98
|
expect(access_token.reload).to have_attributes(revoked?: true)
|
97
99
|
end
|
98
100
|
|
99
|
-
context
|
101
|
+
context "when authorization fails" do
|
100
102
|
let(:some_other_client) { FactoryBot.create(:application, confidential: true) }
|
101
103
|
let(:oauth_client) { Doorkeeper::OAuth::Client.new(some_other_client) }
|
102
104
|
|
103
|
-
it
|
105
|
+
it "returns 200" do
|
104
106
|
post :revoke, params: { token: access_token.token }
|
105
107
|
|
106
108
|
expect(response.status).to eq 200
|
107
109
|
end
|
108
110
|
|
109
|
-
it
|
111
|
+
it "does not revoke the access token" do
|
110
112
|
post :revoke, params: { token: access_token.token }
|
111
113
|
|
112
114
|
expect(access_token.reload).to have_attributes(revoked?: false)
|
@@ -115,7 +117,7 @@ describe Doorkeeper::TokensController do
|
|
115
117
|
end
|
116
118
|
end
|
117
119
|
|
118
|
-
describe
|
120
|
+
describe "authorize response memoization" do
|
119
121
|
it "memoizes the result of the authorization" do
|
120
122
|
strategy = double(:strategy, authorize: true)
|
121
123
|
expect(strategy).to receive(:authorize).once
|
@@ -129,186 +131,199 @@ describe Doorkeeper::TokensController do
|
|
129
131
|
end
|
130
132
|
end
|
131
133
|
|
132
|
-
describe
|
134
|
+
describe "when requested token introspection" do
|
133
135
|
let(:client) { FactoryBot.create(:application) }
|
134
136
|
let(:access_token) { FactoryBot.create(:access_token, application: client) }
|
135
137
|
let(:token_for_introspection) { FactoryBot.create(:access_token, application: client) }
|
136
138
|
|
137
|
-
context
|
138
|
-
it
|
139
|
-
request.headers[
|
139
|
+
context "authorized using valid Bearer token" do
|
140
|
+
it "responds with full token introspection" do
|
141
|
+
request.headers["Authorization"] = "Bearer #{access_token.token}"
|
140
142
|
|
141
143
|
post :introspect, params: { token: token_for_introspection.token }
|
142
144
|
|
143
|
-
should_have_json
|
144
|
-
expect(json_response).to include(
|
145
|
+
should_have_json "active", true
|
146
|
+
expect(json_response).to include("client_id", "token_type", "exp", "iat")
|
145
147
|
end
|
146
148
|
end
|
147
149
|
|
148
|
-
context
|
149
|
-
it
|
150
|
-
request.headers[
|
150
|
+
context "authorized using valid Client Authentication" do
|
151
|
+
it "responds with full token introspection" do
|
152
|
+
request.headers["Authorization"] = basic_auth_header_for_client(client)
|
151
153
|
|
152
154
|
post :introspect, params: { token: token_for_introspection.token }
|
153
155
|
|
154
|
-
should_have_json
|
155
|
-
expect(json_response).to include(
|
156
|
-
should_have_json
|
156
|
+
should_have_json "active", true
|
157
|
+
expect(json_response).to include("client_id", "token_type", "exp", "iat")
|
158
|
+
should_have_json "client_id", client.uid
|
157
159
|
end
|
158
160
|
end
|
159
161
|
|
160
|
-
context
|
162
|
+
context "using custom introspection response" do
|
161
163
|
before do
|
162
164
|
Doorkeeper.configure do
|
163
165
|
orm DOORKEEPER_ORM
|
164
166
|
custom_introspection_response do |_token, _context|
|
165
167
|
{
|
166
|
-
sub:
|
167
|
-
aud:
|
168
|
+
sub: "Z5O3upPC88QrAjx00dis",
|
169
|
+
aud: "https://protected.example.net/resource",
|
168
170
|
}
|
169
171
|
end
|
170
172
|
end
|
171
173
|
end
|
172
174
|
|
173
|
-
it
|
174
|
-
request.headers[
|
175
|
+
it "responds with full token introspection" do
|
176
|
+
request.headers["Authorization"] = "Bearer #{access_token.token}"
|
175
177
|
|
176
178
|
post :introspect, params: { token: token_for_introspection.token }
|
177
179
|
|
178
|
-
expect(json_response).to include(
|
179
|
-
should_have_json
|
180
|
-
should_have_json
|
180
|
+
expect(json_response).to include("client_id", "token_type", "exp", "iat", "sub", "aud")
|
181
|
+
should_have_json "sub", "Z5O3upPC88QrAjx00dis"
|
182
|
+
should_have_json "aud", "https://protected.example.net/resource"
|
181
183
|
end
|
182
184
|
end
|
183
185
|
|
184
|
-
context
|
186
|
+
context "public access token" do
|
185
187
|
let(:token_for_introspection) { FactoryBot.create(:access_token, application: nil) }
|
186
188
|
|
187
|
-
it
|
188
|
-
request.headers[
|
189
|
+
it "responds with full token introspection" do
|
190
|
+
request.headers["Authorization"] = basic_auth_header_for_client(client)
|
189
191
|
|
190
192
|
post :introspect, params: { token: token_for_introspection.token }
|
191
193
|
|
192
|
-
should_have_json
|
193
|
-
expect(json_response).to include(
|
194
|
-
should_have_json
|
194
|
+
should_have_json "active", true
|
195
|
+
expect(json_response).to include("client_id", "token_type", "exp", "iat")
|
196
|
+
should_have_json "client_id", nil
|
195
197
|
end
|
196
198
|
end
|
197
199
|
|
198
|
-
context
|
200
|
+
context "token was issued to a different client than is making this request" do
|
199
201
|
let(:different_client) { FactoryBot.create(:application) }
|
200
202
|
|
201
|
-
it
|
202
|
-
request.headers[
|
203
|
+
it "responds with only active state" do
|
204
|
+
request.headers["Authorization"] = basic_auth_header_for_client(different_client)
|
203
205
|
|
204
206
|
post :introspect, params: { token: token_for_introspection.token }
|
205
207
|
|
206
208
|
expect(response).to be_successful
|
207
209
|
|
208
|
-
should_have_json
|
209
|
-
expect(json_response).not_to include(
|
210
|
+
should_have_json "active", false
|
211
|
+
expect(json_response).not_to include("client_id", "token_type", "exp", "iat")
|
210
212
|
end
|
211
213
|
end
|
212
214
|
|
213
|
-
context
|
214
|
-
let(:
|
215
|
+
context "authorized using invalid Bearer token" do
|
216
|
+
let(:access_token) do
|
215
217
|
FactoryBot.create(:access_token, application: client, revoked_at: 1.day.ago)
|
216
218
|
end
|
217
219
|
|
218
|
-
it
|
219
|
-
request.headers[
|
220
|
+
it "responds with invalid token error" do
|
221
|
+
request.headers["Authorization"] = "Bearer #{access_token.token}"
|
220
222
|
|
221
|
-
post :introspect, params: { token:
|
223
|
+
post :introspect, params: { token: token_for_introspection.token }
|
222
224
|
|
223
225
|
response_status_should_be 401
|
224
226
|
|
225
|
-
should_not_have_json
|
226
|
-
should_have_json
|
227
|
+
should_not_have_json "active"
|
228
|
+
should_have_json "error", "invalid_token"
|
227
229
|
end
|
228
230
|
end
|
229
231
|
|
230
|
-
context
|
231
|
-
it
|
232
|
-
request.headers[
|
232
|
+
context "authorized using the Bearer token that need to be introspected" do
|
233
|
+
it "responds with invalid token error" do
|
234
|
+
request.headers["Authorization"] = "Bearer #{access_token.token}"
|
233
235
|
|
234
236
|
post :introspect, params: { token: access_token.token }
|
235
237
|
|
236
238
|
response_status_should_be 401
|
237
239
|
|
238
|
-
should_not_have_json
|
239
|
-
should_have_json
|
240
|
+
should_not_have_json "active"
|
241
|
+
should_have_json "error", "invalid_token"
|
240
242
|
end
|
241
243
|
end
|
242
244
|
|
243
|
-
context
|
244
|
-
let(:client) { double(uid:
|
245
|
+
context "using invalid credentials to authorize" do
|
246
|
+
let(:client) { double(uid: "123123", secret: "666999") }
|
245
247
|
let(:access_token) { FactoryBot.create(:access_token) }
|
246
248
|
|
247
|
-
it
|
248
|
-
request.headers[
|
249
|
+
it "responds with invalid_client error" do
|
250
|
+
request.headers["Authorization"] = basic_auth_header_for_client(client)
|
249
251
|
|
250
252
|
post :introspect, params: { token: access_token.token }
|
251
253
|
|
252
254
|
expect(response).not_to be_successful
|
253
255
|
response_status_should_be 401
|
254
256
|
|
255
|
-
should_not_have_json
|
256
|
-
should_have_json
|
257
|
+
should_not_have_json "active"
|
258
|
+
should_have_json "error", "invalid_client"
|
257
259
|
end
|
258
260
|
end
|
259
261
|
|
260
|
-
context
|
261
|
-
|
262
|
-
|
262
|
+
context "using wrong token value" do
|
263
|
+
context "authorized using client credentials" do
|
264
|
+
it "responds with only active state" do
|
265
|
+
request.headers["Authorization"] = basic_auth_header_for_client(client)
|
266
|
+
|
267
|
+
post :introspect, params: { token: SecureRandom.hex(16) }
|
263
268
|
|
264
|
-
|
269
|
+
should_have_json "active", false
|
270
|
+
expect(json_response).not_to include("client_id", "token_type", "exp", "iat")
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
context "authorized using valid Bearer token" do
|
275
|
+
it "responds with only active state" do
|
276
|
+
request.headers["Authorization"] = "Bearer #{access_token.token}"
|
265
277
|
|
266
|
-
|
267
|
-
|
278
|
+
post :introspect, params: { token: SecureRandom.hex(16) }
|
279
|
+
|
280
|
+
should_have_json "active", false
|
281
|
+
expect(json_response).not_to include("client_id", "token_type", "exp", "iat")
|
282
|
+
end
|
268
283
|
end
|
269
284
|
end
|
270
285
|
|
271
|
-
context
|
286
|
+
context "when requested access token expired" do
|
272
287
|
let(:token_for_introspection) do
|
273
288
|
FactoryBot.create(:access_token, application: client, created_at: 1.year.ago)
|
274
289
|
end
|
275
290
|
|
276
|
-
it
|
277
|
-
request.headers[
|
291
|
+
it "responds with only active state" do
|
292
|
+
request.headers["Authorization"] = basic_auth_header_for_client(client)
|
278
293
|
|
279
294
|
post :introspect, params: { token: token_for_introspection.token }
|
280
295
|
|
281
|
-
should_have_json
|
282
|
-
expect(json_response).not_to include(
|
296
|
+
should_have_json "active", false
|
297
|
+
expect(json_response).not_to include("client_id", "token_type", "exp", "iat")
|
283
298
|
end
|
284
299
|
end
|
285
300
|
|
286
|
-
context
|
301
|
+
context "when requested Access Token revoked" do
|
287
302
|
let(:token_for_introspection) do
|
288
303
|
FactoryBot.create(:access_token, application: client, revoked_at: 1.year.ago)
|
289
304
|
end
|
290
305
|
|
291
|
-
it
|
292
|
-
request.headers[
|
306
|
+
it "responds with only active state" do
|
307
|
+
request.headers["Authorization"] = basic_auth_header_for_client(client)
|
293
308
|
|
294
309
|
post :introspect, params: { token: token_for_introspection.token }
|
295
310
|
|
296
|
-
should_have_json
|
297
|
-
expect(json_response).not_to include(
|
311
|
+
should_have_json "active", false
|
312
|
+
expect(json_response).not_to include("client_id", "token_type", "exp", "iat")
|
298
313
|
end
|
299
314
|
end
|
300
315
|
|
301
|
-
context
|
316
|
+
context "unauthorized (no bearer token or client credentials)" do
|
302
317
|
let(:token_for_introspection) { FactoryBot.create(:access_token) }
|
303
318
|
|
304
|
-
it
|
319
|
+
it "responds with invalid_request error" do
|
305
320
|
post :introspect, params: { token: token_for_introspection.token }
|
306
321
|
|
307
322
|
expect(response).not_to be_successful
|
308
323
|
response_status_should_be 400
|
309
324
|
|
310
|
-
should_not_have_json
|
311
|
-
should_have_json
|
325
|
+
should_not_have_json "active"
|
326
|
+
should_have_json "error", "invalid_request"
|
312
327
|
end
|
313
328
|
end
|
314
329
|
end
|