doorkeeper 5.0.3 → 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 +4 -4
- data/.hound.yml +2 -1
- data/.rubocop.yml +37 -4
- data/.travis.yml +11 -21
- data/Appraisals +29 -7
- data/Dangerfile +5 -2
- data/Gemfile +19 -5
- data/NEWS.md +81 -21
- data/README.md +75 -485
- 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 +20 -8
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
- data/app/controllers/doorkeeper/token_info_controller.rb +2 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +11 -11
- 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/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 +24 -21
- 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 +191 -75
- 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 +3 -2
- data/lib/doorkeeper/models/access_grant_mixin.rb +20 -3
- data/lib/doorkeeper/models/access_token_mixin.rb +63 -19
- data/lib/doorkeeper/models/application_mixin.rb +43 -1
- data/lib/doorkeeper/models/concerns/expirable.rb +4 -2
- data/lib/doorkeeper/models/concerns/ownership.rb +1 -6
- data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +2 -1
- data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +108 -0
- data/lib/doorkeeper/oauth/authorization/code.rb +2 -2
- data/lib/doorkeeper/oauth/authorization/token.rb +12 -7
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +1 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +6 -4
- data/lib/doorkeeper/oauth/client.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +5 -4
- data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
- data/lib/doorkeeper/oauth/code_response.rb +2 -2
- data/lib/doorkeeper/oauth/error_response.rb +10 -6
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +1 -1
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +23 -8
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +13 -1
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +37 -1
- data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -1
- data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +11 -5
- data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -2
- data/lib/doorkeeper/oauth/scopes.rb +5 -3
- data/lib/doorkeeper/oauth/token.rb +2 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +74 -8
- data/lib/doorkeeper/oauth/token_response.rb +9 -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 +21 -57
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
- data/lib/doorkeeper/orm/active_record.rb +6 -6
- data/lib/doorkeeper/rails/helpers.rb +1 -1
- data/lib/doorkeeper/rails/routes/mapping.rb +7 -7
- data/lib/doorkeeper/rails/routes.rb +11 -11
- data/lib/doorkeeper/rake/db.rake +13 -13
- data/lib/doorkeeper/rake.rb +1 -1
- data/lib/doorkeeper/request.rb +1 -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/stale_records_cleaner.rb +1 -1
- data/lib/doorkeeper/version.rb +3 -3
- data/lib/doorkeeper.rb +69 -60
- 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 +120 -13
- 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 +24 -10
- data/spec/controllers/applications_controller_spec.rb +54 -52
- data/spec/controllers/authorizations_controller_spec.rb +139 -145
- data/spec/controllers/protected_resources_controller_spec.rb +78 -76
- data/spec/controllers/token_info_controller_spec.rb +14 -12
- data/spec/controllers/tokens_controller_spec.rb +167 -108
- 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 +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/application.rb +25 -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 +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/config.ru +3 -1
- 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 +8 -6
- 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 +268 -99
- data/spec/lib/doorkeeper_spec.rb +3 -1
- 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 +34 -11
- 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 +56 -10
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -18
- data/spec/lib/oauth/client_credentials/validation_spec.rb +20 -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 +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 +115 -95
- data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +79 -30
- data/spec/lib/oauth/pre_authorization_spec.rb +80 -54
- 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 +79 -24
- data/spec/lib/oauth/token_response_spec.rb +40 -38
- data/spec/lib/oauth/token_spec.rb +60 -44
- 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 +16 -14
- data/spec/lib/stale_records_cleaner_spec.rb +17 -17
- data/spec/models/doorkeeper/access_grant_spec.rb +80 -15
- data/spec/models/doorkeeper/access_token_spec.rb +198 -73
- data/spec/models/doorkeeper/application_spec.rb +280 -288
- 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 +193 -151
- data/spec/requests/flows/client_credentials_spec.rb +54 -52
- 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 +59 -55
- data/spec/requests/flows/refresh_token_spec.rb +45 -43
- data/spec/requests/flows/revoke_token_spec.rb +40 -54
- 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 +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 +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 +36 -0
- 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 +60 -26
- data/gemfiles/rails_4_2.gemfile +0 -13
- data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -8
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
feature "Adding applications" do
|
|
6
|
+
context "in application form" do
|
|
5
7
|
background do
|
|
6
8
|
i_am_logged_in
|
|
7
|
-
visit
|
|
9
|
+
visit "/oauth/applications/new"
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
scenario
|
|
11
|
-
fill_in
|
|
12
|
-
fill_in
|
|
13
|
-
with:
|
|
12
|
+
scenario "adding a valid app" do
|
|
13
|
+
fill_in "doorkeeper_application[name]", with: "My Application"
|
|
14
|
+
fill_in "doorkeeper_application[redirect_uri]",
|
|
15
|
+
with: "https://example.com"
|
|
14
16
|
|
|
15
|
-
click_button
|
|
16
|
-
i_should_see
|
|
17
|
-
i_should_see
|
|
17
|
+
click_button "Submit"
|
|
18
|
+
i_should_see "Application created"
|
|
19
|
+
i_should_see "My Application"
|
|
18
20
|
end
|
|
19
21
|
|
|
20
|
-
scenario
|
|
21
|
-
click_button
|
|
22
|
-
i_should_see
|
|
22
|
+
scenario "adding invalid app" do
|
|
23
|
+
click_button "Submit"
|
|
24
|
+
i_should_see "Whoops! Check your form for possible errors"
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
scenario "adding app ignoring bad scope" do
|
|
@@ -88,63 +90,93 @@ feature 'Adding applications' do
|
|
|
88
90
|
click_button "Submit"
|
|
89
91
|
i_should_see "Whoops! Check your form for possible errors"
|
|
90
92
|
i_should_see Regexp.new(
|
|
91
|
-
I18n.t(
|
|
93
|
+
I18n.t("activerecord.errors.models.doorkeeper/application.attributes.scopes.not_match_configured"),
|
|
92
94
|
true
|
|
93
95
|
)
|
|
94
96
|
end
|
|
97
|
+
|
|
98
|
+
context "redirect URI" do
|
|
99
|
+
scenario "adding app with blank redirect URI when configured flows requires redirect uri" do
|
|
100
|
+
config_is_set("grant_flows", %w[authorization_code implicit client_credentials])
|
|
101
|
+
|
|
102
|
+
fill_in "doorkeeper_application[name]", with: "My Application"
|
|
103
|
+
fill_in "doorkeeper_application[redirect_uri]",
|
|
104
|
+
with: ""
|
|
105
|
+
|
|
106
|
+
click_button "Submit"
|
|
107
|
+
i_should_see "Whoops! Check your form for possible errors"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
scenario "adding app with blank redirect URI when configured flows without redirect uri" do
|
|
111
|
+
config_is_set("grant_flows", %w[client_credentials password])
|
|
112
|
+
|
|
113
|
+
# Visit it once again to consider grant flows
|
|
114
|
+
visit "/oauth/applications/new"
|
|
115
|
+
|
|
116
|
+
i_should_see I18n.t("doorkeeper.applications.help.blank_redirect_uri")
|
|
117
|
+
|
|
118
|
+
fill_in "doorkeeper_application[name]", with: "My Application"
|
|
119
|
+
fill_in "doorkeeper_application[redirect_uri]",
|
|
120
|
+
with: ""
|
|
121
|
+
|
|
122
|
+
click_button "Submit"
|
|
123
|
+
i_should_see "Application created"
|
|
124
|
+
i_should_see "My Application"
|
|
125
|
+
end
|
|
126
|
+
end
|
|
95
127
|
end
|
|
96
128
|
end
|
|
97
129
|
|
|
98
|
-
feature
|
|
130
|
+
feature "Listing applications" do
|
|
99
131
|
background do
|
|
100
132
|
i_am_logged_in
|
|
101
133
|
|
|
102
|
-
FactoryBot.create :application, name:
|
|
103
|
-
FactoryBot.create :application, name:
|
|
134
|
+
FactoryBot.create :application, name: "Oauth Dude"
|
|
135
|
+
FactoryBot.create :application, name: "Awesome App"
|
|
104
136
|
end
|
|
105
137
|
|
|
106
|
-
scenario
|
|
107
|
-
visit
|
|
138
|
+
scenario "application list" do
|
|
139
|
+
visit "/oauth/applications"
|
|
108
140
|
|
|
109
|
-
i_should_see
|
|
110
|
-
i_should_see
|
|
141
|
+
i_should_see "Awesome App"
|
|
142
|
+
i_should_see "Oauth Dude"
|
|
111
143
|
end
|
|
112
144
|
end
|
|
113
145
|
|
|
114
|
-
feature
|
|
115
|
-
scenario
|
|
116
|
-
visit
|
|
146
|
+
feature "Renders assets" do
|
|
147
|
+
scenario "admin stylesheets" do
|
|
148
|
+
visit "/assets/doorkeeper/admin/application.css"
|
|
117
149
|
|
|
118
|
-
i_should_see
|
|
119
|
-
i_should_see
|
|
150
|
+
i_should_see "Bootstrap"
|
|
151
|
+
i_should_see ".doorkeeper-admin"
|
|
120
152
|
end
|
|
121
153
|
|
|
122
|
-
scenario
|
|
123
|
-
visit
|
|
154
|
+
scenario "application stylesheets" do
|
|
155
|
+
visit "/assets/doorkeeper/application.css"
|
|
124
156
|
|
|
125
|
-
i_should_see
|
|
126
|
-
i_should_see
|
|
127
|
-
i_should_see
|
|
157
|
+
i_should_see "Bootstrap"
|
|
158
|
+
i_should_see "#oauth-permissions"
|
|
159
|
+
i_should_see "#container"
|
|
128
160
|
end
|
|
129
161
|
end
|
|
130
162
|
|
|
131
|
-
feature
|
|
163
|
+
feature "Show application" do
|
|
132
164
|
given :app do
|
|
133
165
|
i_am_logged_in
|
|
134
166
|
|
|
135
|
-
FactoryBot.create :application, name:
|
|
167
|
+
FactoryBot.create :application, name: "Just another oauth app"
|
|
136
168
|
end
|
|
137
169
|
|
|
138
|
-
scenario
|
|
170
|
+
scenario "visiting application page" do
|
|
139
171
|
visit "/oauth/applications/#{app.id}"
|
|
140
172
|
|
|
141
|
-
i_should_see
|
|
173
|
+
i_should_see "Just another oauth app"
|
|
142
174
|
end
|
|
143
175
|
end
|
|
144
176
|
|
|
145
|
-
feature
|
|
177
|
+
feature "Edit application" do
|
|
146
178
|
let :app do
|
|
147
|
-
FactoryBot.create :application, name:
|
|
179
|
+
FactoryBot.create :application, name: "OMG my app"
|
|
148
180
|
end
|
|
149
181
|
|
|
150
182
|
background do
|
|
@@ -153,72 +185,72 @@ feature 'Edit application' do
|
|
|
153
185
|
visit "/oauth/applications/#{app.id}/edit"
|
|
154
186
|
end
|
|
155
187
|
|
|
156
|
-
scenario
|
|
157
|
-
fill_in
|
|
158
|
-
click_button
|
|
188
|
+
scenario "updating a valid app" do
|
|
189
|
+
fill_in "doorkeeper_application[name]", with: "Serious app"
|
|
190
|
+
click_button "Submit"
|
|
159
191
|
|
|
160
|
-
i_should_see
|
|
161
|
-
i_should_see
|
|
162
|
-
i_should_not_see
|
|
192
|
+
i_should_see "Application updated"
|
|
193
|
+
i_should_see "Serious app"
|
|
194
|
+
i_should_not_see "OMG my app"
|
|
163
195
|
end
|
|
164
196
|
|
|
165
|
-
scenario
|
|
166
|
-
fill_in
|
|
167
|
-
click_button
|
|
197
|
+
scenario "updating an invalid app" do
|
|
198
|
+
fill_in "doorkeeper_application[name]", with: ""
|
|
199
|
+
click_button "Submit"
|
|
168
200
|
|
|
169
|
-
i_should_see
|
|
201
|
+
i_should_see "Whoops! Check your form for possible errors"
|
|
170
202
|
end
|
|
171
203
|
end
|
|
172
204
|
|
|
173
|
-
feature
|
|
205
|
+
feature "Remove application" do
|
|
174
206
|
background do
|
|
175
207
|
i_am_logged_in
|
|
176
208
|
|
|
177
209
|
@app = FactoryBot.create :application
|
|
178
210
|
end
|
|
179
211
|
|
|
180
|
-
scenario
|
|
181
|
-
visit
|
|
212
|
+
scenario "deleting an application from list" do
|
|
213
|
+
visit "/oauth/applications"
|
|
182
214
|
|
|
183
215
|
i_should_see @app.name
|
|
184
216
|
|
|
185
217
|
within(:css, "tr#application_#{@app.id}") do
|
|
186
|
-
click_button
|
|
218
|
+
click_button "Destroy"
|
|
187
219
|
end
|
|
188
220
|
|
|
189
|
-
i_should_see
|
|
221
|
+
i_should_see "Application deleted"
|
|
190
222
|
i_should_not_see @app.name
|
|
191
223
|
end
|
|
192
224
|
|
|
193
|
-
scenario
|
|
225
|
+
scenario "deleting an application from show" do
|
|
194
226
|
visit "/oauth/applications/#{@app.id}"
|
|
195
|
-
click_button
|
|
227
|
+
click_button "Destroy"
|
|
196
228
|
|
|
197
|
-
i_should_see
|
|
229
|
+
i_should_see "Application deleted"
|
|
198
230
|
end
|
|
199
231
|
end
|
|
200
232
|
|
|
201
|
-
context
|
|
202
|
-
let(:app) { FactoryBot.create :application, name:
|
|
233
|
+
context "when admin authenticator block is default" do
|
|
234
|
+
let(:app) { FactoryBot.create :application, name: "app" }
|
|
203
235
|
|
|
204
|
-
feature
|
|
205
|
-
scenario
|
|
206
|
-
visit
|
|
236
|
+
feature "application list" do
|
|
237
|
+
scenario "fails with forbidden" do
|
|
238
|
+
visit "/oauth/applications"
|
|
207
239
|
|
|
208
240
|
should_have_status 403
|
|
209
241
|
end
|
|
210
242
|
end
|
|
211
243
|
|
|
212
|
-
feature
|
|
213
|
-
scenario
|
|
214
|
-
visit
|
|
244
|
+
feature "adding an app" do
|
|
245
|
+
scenario "fails with forbidden" do
|
|
246
|
+
visit "/oauth/applications/new"
|
|
215
247
|
|
|
216
248
|
should_have_status 403
|
|
217
249
|
end
|
|
218
250
|
end
|
|
219
251
|
|
|
220
|
-
feature
|
|
221
|
-
scenario
|
|
252
|
+
feature "editing an app" do
|
|
253
|
+
scenario "fails with forbidden" do
|
|
222
254
|
visit "/oauth/applications/#{app.id}/edit"
|
|
223
255
|
|
|
224
256
|
should_have_status 403
|
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
feature "Authorized applications" do
|
|
4
6
|
background do
|
|
5
|
-
@user = User.create!(name:
|
|
6
|
-
@client = client_exists(name:
|
|
7
|
+
@user = User.create!(name: "Joe", password: "sekret")
|
|
8
|
+
@client = client_exists(name: "Amazing Client App")
|
|
7
9
|
resource_owner_is_authenticated @user
|
|
8
10
|
client_is_authorized @client, @user
|
|
9
11
|
end
|
|
10
12
|
|
|
11
|
-
scenario
|
|
12
|
-
visit
|
|
13
|
-
i_should_see
|
|
13
|
+
scenario "display user's authorized applications" do
|
|
14
|
+
visit "/oauth/authorized_applications"
|
|
15
|
+
i_should_see "Amazing Client App"
|
|
14
16
|
end
|
|
15
17
|
|
|
16
|
-
scenario
|
|
17
|
-
client = client_exists(name:
|
|
18
|
-
client_is_authorized client, User.create!(name:
|
|
19
|
-
visit
|
|
20
|
-
i_should_not_see
|
|
18
|
+
scenario "do not display other user's authorized applications" do
|
|
19
|
+
client = client_exists(name: "Another Client App")
|
|
20
|
+
client_is_authorized client, User.create!(name: "Joe", password: "sekret")
|
|
21
|
+
visit "/oauth/authorized_applications"
|
|
22
|
+
i_should_not_see "Another Client App"
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
scenario
|
|
24
|
-
visit
|
|
25
|
-
i_should_see
|
|
26
|
-
click_on
|
|
27
|
-
i_should_see
|
|
28
|
-
i_should_not_see
|
|
25
|
+
scenario "user revoke access to application" do
|
|
26
|
+
visit "/oauth/authorized_applications"
|
|
27
|
+
i_should_see "Amazing Client App"
|
|
28
|
+
click_on "Revoke"
|
|
29
|
+
i_should_see "Application revoked"
|
|
30
|
+
i_should_not_see "Amazing Client App"
|
|
29
31
|
end
|
|
30
32
|
end
|
|
@@ -1,69 +1,71 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
feature "Authorization endpoint" do
|
|
4
6
|
background do
|
|
5
|
-
config_is_set(:authenticate_resource_owner) { User.first || redirect_to(
|
|
6
|
-
client_exists(name:
|
|
7
|
+
config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
|
|
8
|
+
client_exists(name: "MyApp")
|
|
7
9
|
end
|
|
8
10
|
|
|
9
|
-
scenario
|
|
11
|
+
scenario "requires resource owner to be authenticated" do
|
|
10
12
|
visit authorization_endpoint_url(client: @client)
|
|
11
|
-
i_should_see
|
|
12
|
-
i_should_be_on
|
|
13
|
+
i_should_see "Sign in"
|
|
14
|
+
i_should_be_on "/"
|
|
13
15
|
end
|
|
14
16
|
|
|
15
|
-
context
|
|
17
|
+
context "with authenticated resource owner" do
|
|
16
18
|
background do
|
|
17
19
|
create_resource_owner
|
|
18
20
|
sign_in
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
scenario
|
|
23
|
+
scenario "displays the authorization form" do
|
|
22
24
|
visit authorization_endpoint_url(client: @client)
|
|
23
|
-
i_should_see
|
|
25
|
+
i_should_see "Authorize MyApp to use your account?"
|
|
24
26
|
end
|
|
25
27
|
|
|
26
|
-
scenario
|
|
28
|
+
scenario "displays all requested scopes" do
|
|
27
29
|
default_scopes_exist :public
|
|
28
30
|
optional_scopes_exist :write
|
|
29
|
-
visit authorization_endpoint_url(client: @client, scope:
|
|
30
|
-
i_should_see
|
|
31
|
-
i_should_see
|
|
31
|
+
visit authorization_endpoint_url(client: @client, scope: "public write")
|
|
32
|
+
i_should_see "Access your public data"
|
|
33
|
+
i_should_see "Update your data"
|
|
32
34
|
end
|
|
33
35
|
end
|
|
34
36
|
|
|
35
|
-
context
|
|
37
|
+
context "with a invalid request" do
|
|
36
38
|
background do
|
|
37
39
|
create_resource_owner
|
|
38
40
|
sign_in
|
|
39
41
|
end
|
|
40
42
|
|
|
41
|
-
scenario
|
|
42
|
-
visit authorization_endpoint_url(client: @client, response_type:
|
|
43
|
-
i_should_not_see
|
|
43
|
+
scenario "displays the related error" do
|
|
44
|
+
visit authorization_endpoint_url(client: @client, response_type: "")
|
|
45
|
+
i_should_not_see "Authorize"
|
|
44
46
|
i_should_see_translated_error_message :unsupported_response_type
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
scenario "displays unsupported_response_type error when using a disabled response type" do
|
|
48
|
-
config_is_set(:grant_flows, [
|
|
49
|
-
visit authorization_endpoint_url(client: @client, response_type:
|
|
50
|
+
config_is_set(:grant_flows, ["implicit"])
|
|
51
|
+
visit authorization_endpoint_url(client: @client, response_type: "code")
|
|
50
52
|
i_should_not_see "Authorize"
|
|
51
53
|
i_should_see_translated_error_message :unsupported_response_type
|
|
52
54
|
end
|
|
53
55
|
end
|
|
54
56
|
|
|
55
|
-
context
|
|
57
|
+
context "forgery protection enabled" do
|
|
56
58
|
background do
|
|
57
59
|
create_resource_owner
|
|
58
60
|
sign_in
|
|
59
61
|
end
|
|
60
62
|
|
|
61
|
-
scenario
|
|
63
|
+
scenario "raises exception on forged requests" do
|
|
62
64
|
allowing_forgery_protection do
|
|
63
65
|
expect do
|
|
64
66
|
page.driver.post authorization_endpoint_url(client_id: @client.uid,
|
|
65
67
|
redirect_uri: @client.redirect_uri,
|
|
66
|
-
response_type:
|
|
68
|
+
response_type: "code")
|
|
67
69
|
end.to raise_error(ActionController::InvalidAuthenticityToken)
|
|
68
70
|
end
|
|
69
71
|
end
|
|
@@ -1,73 +1,75 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
describe "Token endpoint" do
|
|
4
6
|
before do
|
|
5
7
|
client_exists
|
|
6
|
-
authorization_code_exists application: @client, scopes:
|
|
8
|
+
authorization_code_exists application: @client, scopes: "public"
|
|
7
9
|
end
|
|
8
10
|
|
|
9
|
-
it
|
|
11
|
+
it "respond with correct headers" do
|
|
10
12
|
post token_endpoint_url(code: @authorization.token, client: @client)
|
|
11
|
-
should_have_header
|
|
13
|
+
should_have_header "Pragma", "no-cache"
|
|
12
14
|
|
|
13
15
|
# Rails 5.2 changed headers
|
|
14
16
|
if ::Rails::VERSION::MAJOR >= 5 && ::Rails::VERSION::MINOR >= 2 || ::Rails::VERSION::MAJOR >= 6
|
|
15
|
-
should_have_header
|
|
17
|
+
should_have_header "Cache-Control", "private, no-store"
|
|
16
18
|
else
|
|
17
|
-
should_have_header
|
|
19
|
+
should_have_header "Cache-Control", "no-store"
|
|
18
20
|
end
|
|
19
21
|
|
|
20
|
-
should_have_header
|
|
22
|
+
should_have_header "Content-Type", "application/json; charset=utf-8"
|
|
21
23
|
end
|
|
22
24
|
|
|
23
|
-
it
|
|
25
|
+
it "accepts client credentials with basic auth header" do
|
|
24
26
|
post token_endpoint_url,
|
|
25
27
|
params: {
|
|
26
28
|
code: @authorization.token,
|
|
27
|
-
redirect_uri: @client.redirect_uri
|
|
29
|
+
redirect_uri: @client.redirect_uri,
|
|
28
30
|
},
|
|
29
|
-
headers: {
|
|
31
|
+
headers: { "HTTP_AUTHORIZATION" => basic_auth_header_for_client(@client) }
|
|
30
32
|
|
|
31
|
-
should_have_json
|
|
33
|
+
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
it
|
|
36
|
+
it "returns null for expires_in when a permanent token is set" do
|
|
35
37
|
config_is_set(:access_token_expires_in, nil)
|
|
36
38
|
post token_endpoint_url(code: @authorization.token, client: @client)
|
|
37
|
-
should_have_json
|
|
38
|
-
should_not_have_json
|
|
39
|
+
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
|
40
|
+
should_not_have_json "expires_in"
|
|
39
41
|
end
|
|
40
42
|
|
|
41
|
-
it
|
|
42
|
-
post token_endpoint_url(code: @authorization.token, client: @client, grant_type:
|
|
43
|
+
it "returns unsupported_grant_type for invalid grant_type param" do
|
|
44
|
+
post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "nothing")
|
|
43
45
|
|
|
44
|
-
should_not_have_json
|
|
45
|
-
should_have_json
|
|
46
|
-
should_have_json
|
|
46
|
+
should_not_have_json "access_token"
|
|
47
|
+
should_have_json "error", "unsupported_grant_type"
|
|
48
|
+
should_have_json "error_description", translated_error_message("unsupported_grant_type")
|
|
47
49
|
end
|
|
48
50
|
|
|
49
|
-
it
|
|
50
|
-
config_is_set(:grant_flows, [
|
|
51
|
-
post token_endpoint_url(code: @authorization.token, client: @client, grant_type:
|
|
51
|
+
it "returns unsupported_grant_type for disabled grant flows" do
|
|
52
|
+
config_is_set(:grant_flows, ["implicit"])
|
|
53
|
+
post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "authorization_code")
|
|
52
54
|
|
|
53
|
-
should_not_have_json
|
|
54
|
-
should_have_json
|
|
55
|
-
should_have_json
|
|
55
|
+
should_not_have_json "access_token"
|
|
56
|
+
should_have_json "error", "unsupported_grant_type"
|
|
57
|
+
should_have_json "error_description", translated_error_message("unsupported_grant_type")
|
|
56
58
|
end
|
|
57
59
|
|
|
58
|
-
it
|
|
59
|
-
post token_endpoint_url(code: @authorization.token, client: @client, grant_type:
|
|
60
|
+
it "returns unsupported_grant_type when refresh_token is not in use" do
|
|
61
|
+
post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "refresh_token")
|
|
60
62
|
|
|
61
|
-
should_not_have_json
|
|
62
|
-
should_have_json
|
|
63
|
-
should_have_json
|
|
63
|
+
should_not_have_json "access_token"
|
|
64
|
+
should_have_json "error", "unsupported_grant_type"
|
|
65
|
+
should_have_json "error_description", translated_error_message("unsupported_grant_type")
|
|
64
66
|
end
|
|
65
67
|
|
|
66
|
-
it
|
|
67
|
-
post token_endpoint_url(code: @authorization.token, client: @client, grant_type:
|
|
68
|
+
it "returns invalid_request if grant_type is missing" do
|
|
69
|
+
post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "")
|
|
68
70
|
|
|
69
|
-
should_not_have_json
|
|
70
|
-
should_have_json
|
|
71
|
-
should_have_json
|
|
71
|
+
should_not_have_json "access_token"
|
|
72
|
+
should_have_json "error", "invalid_request"
|
|
73
|
+
should_have_json "error_description", translated_error_message("invalid_request")
|
|
72
74
|
end
|
|
73
75
|
end
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
feature "Authorization Code Flow Errors" do
|
|
4
6
|
let(:client_params) { {} }
|
|
5
7
|
background do
|
|
6
|
-
config_is_set(:authenticate_resource_owner) { User.first || redirect_to(
|
|
8
|
+
config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
|
|
7
9
|
client_exists client_params
|
|
8
10
|
create_resource_owner
|
|
9
11
|
sign_in
|
|
@@ -22,35 +24,35 @@ feature 'Authorization Code Flow Errors' do
|
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
context
|
|
26
|
-
scenario
|
|
27
|
+
context "when access was denied" do
|
|
28
|
+
scenario "redirects with error" do
|
|
27
29
|
visit authorization_endpoint_url(client: @client)
|
|
28
|
-
click_on
|
|
30
|
+
click_on "Deny"
|
|
29
31
|
|
|
30
32
|
i_should_be_on_client_callback @client
|
|
31
|
-
url_should_not_have_param
|
|
32
|
-
url_should_have_param
|
|
33
|
-
url_should_have_param
|
|
33
|
+
url_should_not_have_param "code"
|
|
34
|
+
url_should_have_param "error", "access_denied"
|
|
35
|
+
url_should_have_param "error_description", translated_error_message(:access_denied)
|
|
34
36
|
end
|
|
35
37
|
|
|
36
|
-
scenario
|
|
37
|
-
visit authorization_endpoint_url(client: @client, state:
|
|
38
|
-
click_on
|
|
38
|
+
scenario "redirects with state parameter" do
|
|
39
|
+
visit authorization_endpoint_url(client: @client, state: "return-this")
|
|
40
|
+
click_on "Deny"
|
|
39
41
|
|
|
40
42
|
i_should_be_on_client_callback @client
|
|
41
|
-
url_should_not_have_param
|
|
42
|
-
url_should_have_param
|
|
43
|
+
url_should_not_have_param "code"
|
|
44
|
+
url_should_have_param "state", "return-this"
|
|
43
45
|
end
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
describe
|
|
49
|
+
describe "Authorization Code Flow Errors", "after authorization" do
|
|
48
50
|
before do
|
|
49
51
|
client_exists
|
|
50
52
|
authorization_code_exists application: @client
|
|
51
53
|
end
|
|
52
54
|
|
|
53
|
-
it
|
|
55
|
+
it "returns :invalid_grant error when posting an already revoked grant code" do
|
|
54
56
|
# First successful request
|
|
55
57
|
post token_endpoint_url(code: @authorization.token, client: @client)
|
|
56
58
|
|
|
@@ -59,18 +61,18 @@ describe 'Authorization Code Flow Errors', 'after authorization' do
|
|
|
59
61
|
post token_endpoint_url(code: @authorization.token, client: @client)
|
|
60
62
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
|
61
63
|
|
|
62
|
-
should_not_have_json
|
|
63
|
-
should_have_json
|
|
64
|
-
should_have_json
|
|
64
|
+
should_not_have_json "access_token"
|
|
65
|
+
should_have_json "error", "invalid_grant"
|
|
66
|
+
should_have_json "error_description", translated_error_message("invalid_grant")
|
|
65
67
|
end
|
|
66
68
|
|
|
67
|
-
it
|
|
68
|
-
post token_endpoint_url(code:
|
|
69
|
+
it "returns :invalid_grant error for invalid grant code" do
|
|
70
|
+
post token_endpoint_url(code: "invalid", client: @client)
|
|
69
71
|
|
|
70
72
|
access_token_should_not_exist
|
|
71
73
|
|
|
72
|
-
should_not_have_json
|
|
73
|
-
should_have_json
|
|
74
|
-
should_have_json
|
|
74
|
+
should_not_have_json "access_token"
|
|
75
|
+
should_have_json "error", "invalid_grant"
|
|
76
|
+
should_have_json "error_description", translated_error_message("invalid_grant")
|
|
75
77
|
end
|
|
76
78
|
end
|