doorkeeper 3.1.0 → 4.4.3
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/.coveralls.yml +1 -0
- data/.github/ISSUE_TEMPLATE.md +25 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +17 -0
- data/.gitignore +6 -1
- data/.hound.yml +2 -13
- data/.rubocop.yml +17 -0
- data/.travis.yml +26 -10
- data/Appraisals +18 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/CONTRIBUTING.md +2 -0
- data/Gemfile +5 -5
- data/NEWS.md +141 -2
- data/README.md +149 -66
- data/RELEASING.md +5 -12
- data/Rakefile +1 -1
- data/SECURITY.md +15 -0
- data/app/controllers/doorkeeper/application_controller.rb +4 -6
- data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
- data/app/controllers/doorkeeper/applications_controller.rb +18 -8
- data/app/controllers/doorkeeper/authorizations_controller.rb +1 -1
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
- data/app/controllers/doorkeeper/tokens_controller.rb +62 -15
- data/app/helpers/doorkeeper/dashboard_helper.rb +14 -10
- data/app/validators/redirect_uri_validator.rb +12 -2
- data/app/views/doorkeeper/applications/_delete_form.html.erb +1 -2
- data/app/views/doorkeeper/applications/_form.html.erb +13 -2
- data/app/views/doorkeeper/applications/index.html.erb +2 -0
- data/app/views/doorkeeper/applications/show.html.erb +4 -1
- data/app/views/doorkeeper/authorizations/new.html.erb +1 -1
- data/app/views/doorkeeper/authorized_applications/_delete_form.html.erb +1 -2
- data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
- data/app/views/layouts/doorkeeper/admin.html.erb +1 -1
- data/config/locales/en.yml +12 -7
- data/doorkeeper.gemspec +16 -11
- data/gemfiles/rails_4_2.gemfile +13 -0
- data/gemfiles/rails_5_0.gemfile +12 -0
- data/gemfiles/rails_5_1.gemfile +12 -0
- data/gemfiles/rails_5_2.gemfile +12 -0
- data/gemfiles/rails_master.gemfile +14 -0
- data/lib/doorkeeper/config.rb +119 -46
- data/lib/doorkeeper/engine.rb +11 -7
- data/lib/doorkeeper/errors.rb +18 -0
- data/lib/doorkeeper/grape/helpers.rb +14 -8
- data/lib/doorkeeper/helpers/controller.rb +8 -19
- data/lib/doorkeeper/models/access_grant_mixin.rb +10 -21
- data/lib/doorkeeper/models/access_token_mixin.rb +147 -43
- data/lib/doorkeeper/models/application_mixin.rb +33 -35
- data/lib/doorkeeper/models/concerns/accessible.rb +4 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +15 -5
- data/lib/doorkeeper/models/concerns/orderable.rb +13 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +6 -1
- data/lib/doorkeeper/models/concerns/revocable.rb +37 -2
- data/lib/doorkeeper/oauth/authorization/token.rb +22 -18
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +20 -18
- data/lib/doorkeeper/oauth/authorization_code_request.rb +7 -5
- data/lib/doorkeeper/oauth/{request_concern.rb → base_request.rb} +9 -2
- data/lib/doorkeeper/oauth/base_response.rb +29 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +21 -8
- data/lib/doorkeeper/oauth/client.rb +2 -3
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -8
- data/lib/doorkeeper/oauth/code_response.rb +16 -16
- data/lib/doorkeeper/oauth/error.rb +2 -2
- data/lib/doorkeeper/oauth/error_response.rb +10 -10
- 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/uri_checker.rb +17 -1
- data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -4
- data/lib/doorkeeper/oauth/password_access_token_request.rb +8 -13
- data/lib/doorkeeper/oauth/pre_authorization.rb +5 -3
- data/lib/doorkeeper/oauth/refresh_token_request.rb +23 -14
- data/lib/doorkeeper/oauth/scopes.rb +18 -8
- data/lib/doorkeeper/oauth/token.rb +20 -21
- data/lib/doorkeeper/oauth/token_introspection.rb +128 -0
- data/lib/doorkeeper/oauth/token_request.rb +1 -2
- data/lib/doorkeeper/oauth/token_response.rb +1 -1
- data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -0
- data/lib/doorkeeper/orm/active_record/access_token.rb +34 -8
- data/lib/doorkeeper/orm/active_record/application.rb +48 -11
- data/lib/doorkeeper/orm/active_record.rb +17 -22
- data/lib/doorkeeper/rails/helpers.rb +6 -9
- data/lib/doorkeeper/rails/routes/mapper.rb +4 -4
- data/lib/doorkeeper/rails/routes/mapping.rb +1 -1
- data/lib/doorkeeper/rails/routes.rb +17 -11
- data/lib/doorkeeper/request/authorization_code.rb +7 -1
- data/lib/doorkeeper/request/password.rb +2 -2
- data/lib/doorkeeper/request/refresh_token.rb +1 -1
- data/lib/doorkeeper/request.rb +7 -1
- data/lib/doorkeeper/server.rb +0 -8
- data/lib/doorkeeper/validations.rb +3 -2
- data/lib/doorkeeper/version.rb +34 -1
- data/lib/doorkeeper.rb +10 -2
- data/lib/generators/doorkeeper/add_client_confidentiality_generator.rb +31 -0
- data/lib/generators/doorkeeper/application_owner_generator.rb +11 -2
- data/lib/generators/doorkeeper/migration_generator.rb +13 -1
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +35 -0
- data/lib/generators/doorkeeper/templates/add_confidential_to_application_migration.rb.erb +11 -0
- data/{spec/dummy/db/migrate/20130902175349_add_owner_to_application.rb → lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb} +1 -1
- data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +11 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +38 -6
- data/lib/generators/doorkeeper/templates/migration.rb.erb +69 -0
- data/spec/controllers/application_metal_controller.rb +10 -0
- data/spec/controllers/applications_controller_spec.rb +15 -4
- data/spec/controllers/authorizations_controller_spec.rb +74 -27
- data/spec/controllers/protected_resources_controller_spec.rb +70 -32
- data/spec/controllers/token_info_controller_spec.rb +17 -13
- data/spec/controllers/tokens_controller_spec.rb +198 -12
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -4
- data/spec/dummy/app/controllers/home_controller.rb +1 -1
- data/spec/dummy/app/controllers/metal_controller.rb +1 -1
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +3 -3
- data/spec/dummy/app/models/user.rb +0 -4
- data/spec/dummy/config/application.rb +2 -36
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/environments/test.rb +4 -15
- data/spec/dummy/config/initializers/doorkeeper.rb +19 -3
- data/spec/dummy/config/initializers/new_framework_defaults.rb +6 -0
- data/spec/dummy/config/initializers/secret_token.rb +0 -1
- data/spec/dummy/db/migrate/20111122132257_create_users.rb +3 -1
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +3 -1
- data/{lib/generators/doorkeeper/templates/migration.rb → spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb} +16 -4
- data/{lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb → spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb} +4 -2
- data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +13 -0
- data/spec/dummy/db/migrate/20180210183654_add_confidential_to_application.rb +13 -0
- data/spec/dummy/db/schema.rb +24 -22
- data/spec/factories.rb +4 -2
- data/spec/generators/application_owner_generator_spec.rb +24 -5
- data/spec/generators/migration_generator_spec.rb +24 -3
- data/spec/generators/previous_refresh_token_generator_spec.rb +57 -0
- data/spec/grape/grape_integration_spec.rb +135 -0
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
- data/spec/lib/config_spec.rb +159 -14
- data/spec/lib/doorkeeper_spec.rb +135 -13
- data/spec/lib/models/expirable_spec.rb +0 -1
- data/spec/lib/models/revocable_spec.rb +27 -4
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +1 -2
- data/spec/lib/oauth/authorization_code_request_spec.rb +55 -12
- data/spec/lib/oauth/base_request_spec.rb +155 -0
- data/spec/lib/oauth/base_response_spec.rb +45 -0
- data/spec/lib/oauth/client/credentials_spec.rb +45 -2
- data/spec/lib/oauth/client_credentials/creator_spec.rb +1 -1
- data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
- data/spec/lib/oauth/client_credentials_request_spec.rb +1 -0
- data/spec/lib/oauth/code_request_spec.rb +1 -3
- data/spec/lib/oauth/code_response_spec.rb +34 -0
- data/spec/lib/oauth/error_response_spec.rb +9 -9
- data/spec/lib/oauth/error_spec.rb +1 -1
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +115 -1
- data/spec/lib/oauth/invalid_token_response_spec.rb +36 -8
- data/spec/lib/oauth/password_access_token_request_spec.rb +14 -8
- data/spec/lib/oauth/pre_authorization_spec.rb +12 -7
- data/spec/lib/oauth/refresh_token_request_spec.rb +52 -9
- data/spec/lib/oauth/scopes_spec.rb +28 -2
- data/spec/lib/oauth/token_request_spec.rb +6 -8
- data/spec/lib/oauth/token_spec.rb +12 -5
- data/spec/lib/server_spec.rb +10 -3
- data/spec/models/doorkeeper/access_grant_spec.rb +1 -1
- data/spec/models/doorkeeper/access_token_spec.rb +116 -48
- data/spec/models/doorkeeper/application_spec.rb +145 -29
- data/spec/requests/applications/applications_request_spec.rb +5 -5
- data/spec/requests/endpoints/authorization_spec.rb +5 -6
- data/spec/requests/endpoints/token_spec.rb +8 -1
- data/spec/requests/flows/authorization_code_errors_spec.rb +11 -1
- data/spec/requests/flows/authorization_code_spec.rb +6 -13
- data/spec/requests/flows/client_credentials_spec.rb +29 -1
- data/spec/requests/flows/implicit_grant_errors_spec.rb +2 -2
- data/spec/requests/flows/password_spec.rb +118 -15
- data/spec/requests/flows/refresh_token_spec.rb +89 -19
- data/spec/requests/flows/revoke_token_spec.rb +105 -91
- data/spec/requests/protected_resources/metal_spec.rb +1 -1
- data/spec/requests/protected_resources/private_api_spec.rb +1 -1
- data/spec/routing/custom_controller_routes_spec.rb +4 -0
- data/spec/routing/default_routes_spec.rb +5 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/spec_helper_integration.rb +22 -4
- data/spec/support/dependencies/factory_girl.rb +2 -2
- data/spec/support/helpers/access_token_request_helper.rb +1 -1
- data/spec/support/helpers/model_helper.rb +34 -7
- data/spec/support/helpers/request_spec_helper.rb +17 -5
- data/spec/support/helpers/url_helper.rb +9 -8
- data/spec/support/http_method_shim.rb +38 -0
- data/spec/support/shared/controllers_shared_context.rb +15 -10
- data/spec/support/shared/models_shared_examples.rb +5 -5
- data/spec/validators/redirect_uri_validator_spec.rb +51 -6
- data/spec/version/version_spec.rb +15 -0
- metadata +128 -46
- data/lib/doorkeeper/oauth/client/methods.rb +0 -18
- data/lib/generators/doorkeeper/application_scopes_generator.rb +0 -34
- data/lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb +0 -5
- data/spec/dummy/db/migrate/20130902165751_create_doorkeeper_tables.rb +0 -41
- data/spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb +0 -5
- data/spec/lib/oauth/client/methods_spec.rb +0 -54
@@ -2,9 +2,7 @@ require 'spec_helper_integration'
|
|
2
2
|
|
3
3
|
describe Doorkeeper::TokensController do
|
4
4
|
describe 'when authorization has succeeded' do
|
5
|
-
let :token
|
6
|
-
double(:token, authorize: true)
|
7
|
-
end
|
5
|
+
let(:token) { double(:token, authorize: true) }
|
8
6
|
|
9
7
|
before do
|
10
8
|
allow(controller).to receive(:token) { token }
|
@@ -38,7 +36,7 @@ describe Doorkeeper::TokensController do
|
|
38
36
|
allow(I18n).to receive(:translate).
|
39
37
|
with(
|
40
38
|
custom_message,
|
41
|
-
hash_including(scope: [
|
39
|
+
hash_including(scope: %i[doorkeeper errors messages]),
|
42
40
|
).
|
43
41
|
and_return('Authorization custom message')
|
44
42
|
|
@@ -57,19 +55,71 @@ describe Doorkeeper::TokensController do
|
|
57
55
|
}
|
58
56
|
expect(response.status).to eq 401
|
59
57
|
expect(response.headers['WWW-Authenticate']).to match(/Bearer/)
|
60
|
-
expect(JSON.
|
58
|
+
expect(JSON.parse(response.body)).to eq expected_response_body
|
61
59
|
end
|
62
60
|
end
|
63
61
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
62
|
+
# http://tools.ietf.org/html/rfc7009#section-2.2
|
63
|
+
describe 'revoking tokens' do
|
64
|
+
let(:client) { FactoryBot.create(:application) }
|
65
|
+
let(:access_token) { FactoryBot.create(:access_token, application: client) }
|
66
|
+
|
67
|
+
before(:each) do
|
68
|
+
allow(controller).to receive(:token) { access_token }
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when associated app is public' do
|
72
|
+
let(:client) { FactoryBot.create(:application, confidential: false) }
|
73
|
+
|
74
|
+
it 'returns 200' do
|
75
|
+
post :revoke
|
76
|
+
|
77
|
+
expect(response.status).to eq 200
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'revokes the access token' do
|
81
|
+
post :revoke
|
82
|
+
|
83
|
+
expect(access_token.reload).to have_attributes(revoked?: true)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when associated app is confidential' do
|
88
|
+
let(:client) { FactoryBot.create(:application, confidential: true) }
|
89
|
+
let(:oauth_client) { Doorkeeper::OAuth::Client.new(client) }
|
90
|
+
|
91
|
+
before(:each) do
|
92
|
+
allow_any_instance_of(Doorkeeper::Server).to receive(:client) { oauth_client }
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'returns 200' do
|
96
|
+
post :revoke
|
97
|
+
|
98
|
+
expect(response.status).to eq 200
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'revokes the access token' do
|
102
|
+
post :revoke
|
103
|
+
|
104
|
+
expect(access_token.reload).to have_attributes(revoked?: true)
|
105
|
+
end
|
106
|
+
|
107
|
+
context 'when authorization fails' do
|
108
|
+
let(:some_other_client) { FactoryBot.create(:application, confidential: true) }
|
109
|
+
let(:oauth_client) { Doorkeeper::OAuth::Client.new(some_other_client) }
|
110
|
+
|
111
|
+
it 'returns 200' do
|
112
|
+
post :revoke
|
69
113
|
|
70
|
-
|
114
|
+
expect(response.status).to eq 200
|
115
|
+
end
|
71
116
|
|
72
|
-
|
117
|
+
it 'does not revoke the access token' do
|
118
|
+
post :revoke
|
119
|
+
|
120
|
+
expect(access_token.reload).to have_attributes(revoked?: false)
|
121
|
+
end
|
122
|
+
end
|
73
123
|
end
|
74
124
|
end
|
75
125
|
|
@@ -85,4 +135,140 @@ describe Doorkeeper::TokensController do
|
|
85
135
|
post :create
|
86
136
|
end
|
87
137
|
end
|
138
|
+
|
139
|
+
describe 'when requested token introspection' do
|
140
|
+
context 'authorized using Bearer token' do
|
141
|
+
let(:client) { FactoryBot.create(:application) }
|
142
|
+
let(:access_token) { FactoryBot.create(:access_token, application: client) }
|
143
|
+
|
144
|
+
it 'responds with full token introspection' do
|
145
|
+
request.headers['Authorization'] = "Bearer #{access_token.token}"
|
146
|
+
|
147
|
+
post :introspect, token: access_token.token
|
148
|
+
|
149
|
+
should_have_json 'active', true
|
150
|
+
expect(json_response).to include('client_id', 'token_type', 'exp', 'iat')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context 'authorized using Client Authentication' do
|
155
|
+
let(:client) { FactoryBot.create(:application) }
|
156
|
+
let(:access_token) { FactoryBot.create(:access_token, application: client) }
|
157
|
+
|
158
|
+
it 'responds with full token introspection' do
|
159
|
+
request.headers['Authorization'] = basic_auth_header_for_client(client)
|
160
|
+
|
161
|
+
post :introspect, token: access_token.token
|
162
|
+
|
163
|
+
should_have_json 'active', true
|
164
|
+
expect(json_response).to include('client_id', 'token_type', 'exp', 'iat')
|
165
|
+
should_have_json 'client_id', client.uid
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'public access token' do
|
170
|
+
let(:client) { FactoryBot.create(:application) }
|
171
|
+
let(:access_token) { FactoryBot.create(:access_token, application: nil) }
|
172
|
+
|
173
|
+
it 'responds with full token introspection' do
|
174
|
+
request.headers['Authorization'] = basic_auth_header_for_client(client)
|
175
|
+
|
176
|
+
post :introspect, token: access_token.token
|
177
|
+
|
178
|
+
should_have_json 'active', true
|
179
|
+
expect(json_response).to include('client_id', 'token_type', 'exp', 'iat')
|
180
|
+
should_have_json 'client_id', nil
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'token was issued to a different client than is making this request' do
|
185
|
+
let(:client) { FactoryBot.create(:application) }
|
186
|
+
let(:different_client) { FactoryBot.create(:application) }
|
187
|
+
let(:access_token) { FactoryBot.create(:access_token, application: client) }
|
188
|
+
|
189
|
+
it 'responds with only active state' do
|
190
|
+
request.headers['Authorization'] = basic_auth_header_for_client(different_client)
|
191
|
+
|
192
|
+
post :introspect, token: access_token.token
|
193
|
+
|
194
|
+
expect(response).to be_successful
|
195
|
+
|
196
|
+
should_have_json 'active', false
|
197
|
+
expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'using invalid credentials to authorize' do
|
202
|
+
let(:client) { double(uid: '123123', secret: '666999') }
|
203
|
+
let(:access_token) { FactoryBot.create(:access_token) }
|
204
|
+
|
205
|
+
it 'responds with invalid_client error' do
|
206
|
+
request.headers['Authorization'] = basic_auth_header_for_client(client)
|
207
|
+
|
208
|
+
post :introspect, token: access_token.token
|
209
|
+
|
210
|
+
expect(response).not_to be_successful
|
211
|
+
response_status_should_be 401
|
212
|
+
|
213
|
+
should_not_have_json 'active'
|
214
|
+
should_have_json 'error', 'invalid_client'
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'using wrong token value' do
|
219
|
+
let(:client) { FactoryBot.create(:application) }
|
220
|
+
let(:access_token) { FactoryBot.create(:access_token, application: client) }
|
221
|
+
|
222
|
+
it 'responds with only active state' do
|
223
|
+
request.headers['Authorization'] = basic_auth_header_for_client(client)
|
224
|
+
|
225
|
+
post :introspect, token: SecureRandom.hex(16)
|
226
|
+
|
227
|
+
should_have_json 'active', false
|
228
|
+
expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'when requested Access Token expired' do
|
233
|
+
let(:client) { FactoryBot.create(:application) }
|
234
|
+
let(:access_token) { FactoryBot.create(:access_token, application: client, created_at: 1.year.ago) }
|
235
|
+
|
236
|
+
it 'responds with only active state' do
|
237
|
+
request.headers['Authorization'] = basic_auth_header_for_client(client)
|
238
|
+
|
239
|
+
post :introspect, token: access_token.token
|
240
|
+
|
241
|
+
should_have_json 'active', false
|
242
|
+
expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context 'when requested Access Token revoked' do
|
247
|
+
let(:client) { FactoryBot.create(:application) }
|
248
|
+
let(:access_token) { FactoryBot.create(:access_token, application: client, revoked_at: 1.year.ago) }
|
249
|
+
|
250
|
+
it 'responds with only active state' do
|
251
|
+
request.headers['Authorization'] = basic_auth_header_for_client(client)
|
252
|
+
|
253
|
+
post :introspect, token: access_token.token
|
254
|
+
|
255
|
+
should_have_json 'active', false
|
256
|
+
expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context 'unauthorized (no bearer token or client credentials)' do
|
261
|
+
let(:access_token) { FactoryBot.create(:access_token) }
|
262
|
+
|
263
|
+
it 'responds with invalid_request error' do
|
264
|
+
post :introspect, token: access_token.token
|
265
|
+
|
266
|
+
expect(response).not_to be_successful
|
267
|
+
response_status_should_be 401
|
268
|
+
|
269
|
+
should_not_have_json 'active'
|
270
|
+
should_have_json 'error', 'invalid_request'
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
88
274
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
class FullProtectedResourcesController < ApplicationController
|
2
|
-
|
3
|
-
|
2
|
+
before_action -> { doorkeeper_authorize! :write, :admin }, only: :show
|
3
|
+
before_action :doorkeeper_authorize!, only: :index
|
4
4
|
|
5
5
|
def index
|
6
|
-
render
|
6
|
+
render plain: 'index'
|
7
7
|
end
|
8
8
|
|
9
9
|
def show
|
10
|
-
render
|
10
|
+
render plain: 'show'
|
11
11
|
end
|
12
12
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
class SemiProtectedResourcesController < ApplicationController
|
2
|
-
|
2
|
+
before_action :doorkeeper_authorize!, only: :index
|
3
3
|
|
4
4
|
def index
|
5
|
-
render
|
5
|
+
render plain: 'protected index'
|
6
6
|
end
|
7
7
|
|
8
8
|
def show
|
9
|
-
render
|
9
|
+
render plain: 'non protected show'
|
10
10
|
end
|
11
11
|
end
|
@@ -1,9 +1,8 @@
|
|
1
1
|
require File.expand_path('../boot', __FILE__)
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'sprockets/railtie'
|
3
|
+
require 'rails/all'
|
5
4
|
|
6
|
-
Bundler.require
|
5
|
+
Bundler.require(*Rails.groups)
|
7
6
|
|
8
7
|
require 'yaml'
|
9
8
|
|
@@ -20,38 +19,5 @@ module Dummy
|
|
20
19
|
# Settings in config/environments/* take precedence over those specified here.
|
21
20
|
# Application configuration should go into files in config/initializers
|
22
21
|
# -- all .rb files in that directory are automatically loaded.
|
23
|
-
|
24
|
-
# Only load the plugins named here, in the order given (default is alphabetical).
|
25
|
-
# :all can be used as a placeholder for all plugins not explicitly named.
|
26
|
-
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
27
|
-
|
28
|
-
# Activate observers that should always be running.
|
29
|
-
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
30
|
-
|
31
|
-
if defined?(ActiveRecord) && Rails.version.to_i < 4
|
32
|
-
config.active_record.whitelist_attributes = true
|
33
|
-
end
|
34
|
-
|
35
|
-
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
36
|
-
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
37
|
-
# config.time_zone = 'Central Time (US & Canada)'
|
38
|
-
|
39
|
-
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
40
|
-
config.i18n.load_path += Dir[Rails.root.join('../../', 'config/locales', '*.{rb,yml}').to_s]
|
41
|
-
# config.i18n.default_locale = :en
|
42
|
-
|
43
|
-
# Configure the default encoding used in templates for Ruby 1.9.
|
44
|
-
config.encoding = 'utf-8'
|
45
|
-
|
46
|
-
# Configure sensitive parameters which will be filtered from the log file.
|
47
|
-
config.filter_parameters += [:password]
|
48
|
-
|
49
|
-
# Enable the asset pipeline
|
50
|
-
config.assets.enabled = true
|
51
|
-
|
52
|
-
# Version of your assets, change this if you want to expire all your assets
|
53
|
-
config.assets.version = '1.0'
|
54
|
-
|
55
|
-
I18n.enforce_available_locales = false
|
56
22
|
end
|
57
23
|
end
|
@@ -7,21 +7,10 @@ Dummy::Application.configure do
|
|
7
7
|
# and recreated between test runs. Don't rely on the data there!
|
8
8
|
config.cache_classes = true
|
9
9
|
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
# Log error messages when you accidentally call methods on nil
|
15
|
-
config.whiny_nils = true
|
16
|
-
end
|
17
|
-
|
18
|
-
if Rails.version.to_i >= 4
|
19
|
-
# Do not eager load code on boot. This avoids loading your whole application
|
20
|
-
# just for the purpose of running a single test. If you are using a tool that
|
21
|
-
# preloads Rails for running tests, you may have to set it to true.
|
22
|
-
config.eager_load = false
|
23
|
-
config.i18n.enforce_available_locales = true
|
24
|
-
end
|
10
|
+
# Do not eager load code on boot. This avoids loading your whole application
|
11
|
+
# just for the purpose of running a single test. If you are using a tool that
|
12
|
+
# preloads Rails for running tests, you may have to set it to true.
|
13
|
+
config.eager_load = false
|
25
14
|
|
26
15
|
# Show full error reports and disable caching
|
27
16
|
config.consider_all_requests_local = true
|
@@ -29,11 +29,16 @@ Doorkeeper.configure do
|
|
29
29
|
# Issue access tokens with refresh token (disabled by default)
|
30
30
|
use_refresh_token
|
31
31
|
|
32
|
+
# Opt out of breaking api change to the native authorization code flow. Opting out sets the authorization
|
33
|
+
# code response route for native redirect uris to oauth/authorize/<code>. The default is oauth/authorize/native?code=<code>.
|
34
|
+
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1143
|
35
|
+
# opt_out_native_route_change
|
36
|
+
|
32
37
|
# Provide support for an owner to be assigned to each registered application (disabled by default)
|
33
|
-
# Optional parameter :
|
38
|
+
# Optional parameter confirmation: true (default false) if you want to enforce ownership of
|
34
39
|
# a registered application
|
35
40
|
# Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
|
36
|
-
# enable_application_owner :
|
41
|
+
# enable_application_owner confirmation: false
|
37
42
|
|
38
43
|
# Define access token scopes for your provider
|
39
44
|
# For more information go to
|
@@ -82,7 +87,18 @@ Doorkeeper.configure do
|
|
82
87
|
# http://tools.ietf.org/html/rfc6819#section-4.4.2
|
83
88
|
# http://tools.ietf.org/html/rfc6819#section-4.4.3
|
84
89
|
#
|
85
|
-
# grant_flows %w
|
90
|
+
# grant_flows %w[authorization_code client_credentials]
|
91
|
+
|
92
|
+
# Hook into the strategies' request & response life-cycle in case your
|
93
|
+
# application needs advanced customization or logging:
|
94
|
+
#
|
95
|
+
# before_successful_strategy_response do |request|
|
96
|
+
# puts "BEFORE HOOK FIRED! #{request}"
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# after_successful_strategy_response do |request, response|
|
100
|
+
# puts "AFTER HOOK FIRED! #{request}, #{response}"
|
101
|
+
# end
|
86
102
|
|
87
103
|
# Under some circumstances you might want to have applications auto-approved,
|
88
104
|
# so that the user skips the authorization step.
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# Require `belongs_to` associations by default. This is a new Rails 5.0
|
2
|
+
# default, so it is introduced as a configuration option to ensure that apps
|
3
|
+
# made on earlier versions of Rails are not affected when upgrading.
|
4
|
+
if Rails::VERSION::MAJOR >= 5
|
5
|
+
Rails.application.config.active_record.belongs_to_required_by_default = true
|
6
|
+
end
|
@@ -5,5 +5,4 @@
|
|
5
5
|
# Make sure the secret is at least 30 characters and all random,
|
6
6
|
# no regular words or you'll be exposed to dictionary attacks.
|
7
7
|
Dummy::Application.config.secret_key_base =
|
8
|
-
Dummy::Application.config.secret_token =
|
9
8
|
'c00157b5a1bb6181792f0f4a8a080485de7bab9987e6cf159dc74c4f0573345c1bfa713b5d756e1491fc0b098567e8a619e2f8d268eda86a20a720d05d633780'
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateDoorkeeperTables < ActiveRecord::Migration[4.2]
|
2
4
|
def change
|
3
5
|
create_table :oauth_applications do |t|
|
4
6
|
t.string :name, null: false
|
@@ -6,14 +8,14 @@ class CreateDoorkeeperTables < ActiveRecord::Migration
|
|
6
8
|
t.string :secret, null: false
|
7
9
|
t.text :redirect_uri, null: false
|
8
10
|
t.string :scopes, null: false, default: ''
|
9
|
-
t.timestamps
|
11
|
+
t.timestamps null: false
|
10
12
|
end
|
11
13
|
|
12
14
|
add_index :oauth_applications, :uid, unique: true
|
13
15
|
|
14
16
|
create_table :oauth_access_grants do |t|
|
15
17
|
t.integer :resource_owner_id, null: false
|
16
|
-
t.
|
18
|
+
t.references :application, null: false
|
17
19
|
t.string :token, null: false
|
18
20
|
t.integer :expires_in, null: false
|
19
21
|
t.text :redirect_uri, null: false
|
@@ -23,10 +25,15 @@ class CreateDoorkeeperTables < ActiveRecord::Migration
|
|
23
25
|
end
|
24
26
|
|
25
27
|
add_index :oauth_access_grants, :token, unique: true
|
28
|
+
add_foreign_key(
|
29
|
+
:oauth_access_grants,
|
30
|
+
:oauth_applications,
|
31
|
+
column: :application_id,
|
32
|
+
)
|
26
33
|
|
27
34
|
create_table :oauth_access_tokens do |t|
|
28
35
|
t.integer :resource_owner_id
|
29
|
-
t.
|
36
|
+
t.references :application
|
30
37
|
|
31
38
|
# If you use a custom token generator you may need to change this column
|
32
39
|
# from string to text, so that it accepts tokens larger than 255
|
@@ -46,5 +53,10 @@ class CreateDoorkeeperTables < ActiveRecord::Migration
|
|
46
53
|
add_index :oauth_access_tokens, :token, unique: true
|
47
54
|
add_index :oauth_access_tokens, :resource_owner_id
|
48
55
|
add_index :oauth_access_tokens, :refresh_token, unique: true
|
56
|
+
add_foreign_key(
|
57
|
+
:oauth_access_tokens,
|
58
|
+
:oauth_applications,
|
59
|
+
column: :application_id,
|
60
|
+
)
|
49
61
|
end
|
50
62
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddOwnerToApplication < ActiveRecord::Migration[4.2]
|
2
4
|
def change
|
3
5
|
add_column :oauth_applications, :owner_id, :integer, null: true
|
4
6
|
add_column :oauth_applications, :owner_type, :string, null: true
|
5
7
|
add_index :oauth_applications, [:owner_id, :owner_type]
|
6
8
|
end
|
7
|
-
end
|
9
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class AddConfidentialToApplication < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
add_column(
|
6
|
+
:oauth_applications,
|
7
|
+
:confidential,
|
8
|
+
:boolean,
|
9
|
+
null: false,
|
10
|
+
default: true # maintaining backwards compatibility: require secrets
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -11,55 +11,57 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(version:
|
14
|
+
ActiveRecord::Schema.define(version: 20180210183654) do
|
15
15
|
|
16
|
-
create_table "oauth_access_grants", force:
|
17
|
-
t.integer "resource_owner_id",
|
18
|
-
t.integer "application_id",
|
19
|
-
t.string "token",
|
20
|
-
t.integer "expires_in",
|
21
|
-
t.
|
22
|
-
t.datetime "created_at",
|
16
|
+
create_table "oauth_access_grants", force: :cascade do |t|
|
17
|
+
t.integer "resource_owner_id", null: false
|
18
|
+
t.integer "application_id", null: false
|
19
|
+
t.string "token", null: false
|
20
|
+
t.integer "expires_in", null: false
|
21
|
+
t.text "redirect_uri", null: false
|
22
|
+
t.datetime "created_at", null: false
|
23
23
|
t.datetime "revoked_at"
|
24
24
|
t.string "scopes"
|
25
25
|
end
|
26
26
|
|
27
27
|
add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true
|
28
28
|
|
29
|
-
create_table "oauth_access_tokens", force:
|
29
|
+
create_table "oauth_access_tokens", force: :cascade do |t|
|
30
30
|
t.integer "resource_owner_id"
|
31
31
|
t.integer "application_id"
|
32
|
-
t.string "token",
|
32
|
+
t.string "token", null: false
|
33
33
|
t.string "refresh_token"
|
34
34
|
t.integer "expires_in"
|
35
35
|
t.datetime "revoked_at"
|
36
|
-
t.datetime "created_at",
|
36
|
+
t.datetime "created_at", null: false
|
37
37
|
t.string "scopes"
|
38
|
+
t.string "previous_refresh_token", default: "", null: false
|
38
39
|
end
|
39
40
|
|
40
41
|
add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true
|
41
42
|
add_index "oauth_access_tokens", ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id"
|
42
43
|
add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true
|
43
44
|
|
44
|
-
create_table "oauth_applications", force:
|
45
|
-
t.string "name",
|
46
|
-
t.string "uid",
|
47
|
-
t.string "secret",
|
48
|
-
t.
|
49
|
-
t.
|
50
|
-
t.datetime "
|
45
|
+
create_table "oauth_applications", force: :cascade do |t|
|
46
|
+
t.string "name", null: false
|
47
|
+
t.string "uid", null: false
|
48
|
+
t.string "secret", null: false
|
49
|
+
t.text "redirect_uri", null: false
|
50
|
+
t.string "scopes", default: "", null: false
|
51
|
+
t.datetime "created_at"
|
52
|
+
t.datetime "updated_at"
|
51
53
|
t.integer "owner_id"
|
52
54
|
t.string "owner_type"
|
53
|
-
t.
|
55
|
+
t.boolean "confidential", default: true, null: false
|
54
56
|
end
|
55
57
|
|
56
58
|
add_index "oauth_applications", ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type"
|
57
59
|
add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true
|
58
60
|
|
59
|
-
create_table "users", force:
|
61
|
+
create_table "users", force: :cascade do |t|
|
60
62
|
t.string "name"
|
61
|
-
t.datetime "created_at"
|
62
|
-
t.datetime "updated_at"
|
63
|
+
t.datetime "created_at"
|
64
|
+
t.datetime "updated_at"
|
63
65
|
t.string "password"
|
64
66
|
end
|
65
67
|
|
data/spec/factories.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
FactoryBot.define do
|
2
2
|
factory :access_grant, class: Doorkeeper::AccessGrant do
|
3
3
|
sequence(:resource_owner_id) { |n| n }
|
4
4
|
application
|
@@ -22,5 +22,7 @@ FactoryGirl.define do
|
|
22
22
|
redirect_uri 'https://app.com/callback'
|
23
23
|
end
|
24
24
|
|
25
|
-
factory :user
|
25
|
+
# do not name this factory :user, otherwise it will conflict with factories
|
26
|
+
# from applications that use doorkeeper factories in their own tests
|
27
|
+
factory :doorkeeper_testing_user, class: :user
|
26
28
|
end
|