doorkeeper-mongodb 4.1.0 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -4
- data/lib/doorkeeper-mongodb/mixins/mongo_mapper/access_token_mixin.rb +1 -1
- data/lib/doorkeeper-mongodb/mixins/mongo_mapper/application_mixin.rb +28 -1
- data/lib/doorkeeper-mongodb/mixins/mongoid/access_token_mixin.rb +1 -1
- data/lib/doorkeeper-mongodb/mixins/mongoid/application_mixin.rb +28 -1
- data/lib/doorkeeper-mongodb/version.rb +1 -1
- data/lib/doorkeeper/orm/mongo_mapper/application.rb +1 -0
- data/lib/doorkeeper/orm/mongoid4/application.rb +1 -0
- data/lib/doorkeeper/orm/mongoid5/application.rb +1 -0
- data/lib/doorkeeper/orm/mongoid6/application.rb +1 -0
- data/lib/doorkeeper/orm/mongoid7/application.rb +1 -0
- data/spec/controllers/authorizations_controller_spec.rb +34 -2
- data/spec/controllers/tokens_controller_spec.rb +59 -7
- data/spec/dummy/config/initializers/doorkeeper.rb +16 -0
- 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/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -1
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +3 -1
- data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +3 -1
- data/spec/dummy/db/migrate/20180210183654_add_confidential_to_application.rb +13 -0
- data/spec/dummy/db/schema.rb +2 -1
- data/spec/dummy/log/test.log +42919 -1155
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{D9/D9fEdDvxWhngpnQPHr1FTwQHL604FuHmaWxQlh7nok4.cache → -4/-4b6k9VbovmXpob9TEreMNbQqIq2frgEkXbJmaLpXXo.cache} +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{ta/taYouTiRnSIHwA3iNj6mcoN57fxG6-AcZRBxXnoZA6A.cache → 3R/3R0IlALSataFe0QXquFlLgPkS12rgPAHsrnaCNZcP5E.cache} +1 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{Wq/WqR0oz-DxQxVQZ9WeV8Ey01S8-hmMym-alX1ZIeGcyw.cache → 45/45HM8KBWEUkiP_490juLH2Z8mPYNvM0SWJEsbZSf-S0.cache} +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{fe/feHuxmxsfeyr6pDo0Hsq-ToOVXAjCZnZl9Vt5bvFLYg.cache → 7C/7C_H6iKWpfJDii1YogQrSSaPEK7vd4Yfuqhd3QloNjI.cache} +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{b2/b2BfYDhSV9fWL8fEi5lO_H--gisMJqwzT0gmWDyEseo.cache → EJ/EJEkZ1VTObngEDZDbY6RBWwvY8bZfUlUSccPwFdQstU.cache} +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{x3/x3quJr1-zURZiHgn1fyavoPEcZ6Gz-F-ZTGHLMCq8F4.cache → Gc/GcCh3Q_ZFDDRrSCrGY-akIqT_d5smO_RcJ7BTDxDx9M.cache} +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{Wz/WzU5ImvcBYPRRo1bDcUoMBnYvMHElmP1WmpSoWFGrIA.cache → IZ/IZF3X64f5MivAUq6IkvkQkPKxa06jCGI94vN_imFwv8.cache} +1 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Vw/Vw7y8QAO4DQwNaWGwLo7_3NKa_pdX0vCYAzk7CVykfw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{Gd/Gd13CrC_hyFXI6YkLDcl76UZb5vYjlYqFBmF0_aY2UA.cache → Y7/Y772A7TJ6-gpe-9AmRmcRZpJK6g92kS1nWduuGFPfOM.cache} +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/iZ/iZxru9bhjMYVAmekcMRoFdZiEnpEj55tS7566aoOE_Q.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jj/jjeDmVIyET494Gq15Sob1rbi_KO8D1-vwo4vwVIjYWg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{T9/T9SRvIirztZ2z-NS27p6uDCnS-SfsrqePihCkC7Z0bo.cache → r2/r2BLffvW211dRKmFTSEtrrxY9mgSpAbJvAMYgffd0Wo.cache} +1 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{7B/7BQrqCAX5USU9CPwXaBgC9o5N8slSgZi8nbDPdXZWy4.cache → rO/rOJ5Qletb3Q5P_zAPve6Pb0AZLvUfqhr8eTmIMHhTjE.cache} +1 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/{Mc/Mc82fixkCIrNkzovtrFyWVaxz_YMs_0nB0z2aUfm1k4.cache → wy/wy1q9jo24sJvPLH8a36mvtxEc8mWcEevN1zuAo-AJHg.cache} +1 -1
- data/spec/lib/config_spec.rb +25 -0
- data/spec/lib/oauth/authorization_code_request_spec.rb +18 -3
- data/spec/lib/oauth/client/credentials_spec.rb +4 -2
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +110 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +3 -3
- data/spec/lib/oauth/pre_authorization_spec.rb +12 -7
- data/spec/lib/oauth/refresh_token_request_spec.rb +3 -3
- data/spec/models/doorkeeper/application_spec.rb +96 -5
- data/spec/requests/flows/authorization_code_spec.rb +1 -1
- data/spec/requests/flows/password_spec.rb +64 -21
- metadata +36 -34
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cR/cRfgFbJ7Ssu1jWEBQejbIXjvNXL4NcrEwyow92EhVYI.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wi/wiNoTKijy4NStsMmmG4tY5xuViXEiGgA944y09eeqH4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/x0/x0P5YVye0-UGqw0Ogxkk3qBPNTjQ9ehoc5Kf58zrttk.cache +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a558006d5a226503b88524ec1c356bcdbad72f0d
|
4
|
+
data.tar.gz: beb6f775648e48fe6bf29b4e36113a2ffca80be0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05274c1bf97ca17ee906633a123e225a4530ff7700e8c75db33fd75cc725bec4e3964fe6bda687a071cfb98f4997cb193a8bef7e992c72812552e138929e7801
|
7
|
+
data.tar.gz: d7d7d2943fd868850d2cdd15d26002f4fa9c07aad461652fab739b233612fb95c91db80f8333dc2b7e3480bdfdeb2172b13a67a45d4ed763e3dae4cdc8b42374
|
data/README.md
CHANGED
@@ -6,12 +6,21 @@
|
|
6
6
|
|
7
7
|
`doorkeeper-mongodb` provides [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper) support to
|
8
8
|
[MongoMapper](https://github.com/mongomapper/mongomapper) and [Mongoid](https://github.com/mongodb/mongoid)
|
9
|
-
(2, 3, 4 and 5 for doorkeeper-mongodb `3.0` and 4, 5, 6 and
|
9
|
+
(2, 3, 4 and 5 for doorkeeper-mongodb `3.0` and 4, 5, 6 and 7 for version `4.0` and higher). To start using it, add
|
10
10
|
to your Gemfile:
|
11
11
|
|
12
12
|
``` ruby
|
13
|
-
|
14
|
-
gem 'doorkeeper
|
13
|
+
# For Doorkeeper < 4.4
|
14
|
+
gem 'doorkeeper', '~> 4.3'
|
15
|
+
gem 'doorkeeper-mongodb', '~> 4.1.0'
|
16
|
+
|
17
|
+
# For Doorkeeper >= 4.4 && < 5.0
|
18
|
+
gem 'doorkeeper', '~> 4.4'
|
19
|
+
gem 'doorkeeper-mongodb', '~> 4.2'
|
20
|
+
|
21
|
+
# For Doorkeeper >= 5.0
|
22
|
+
gem 'doorkeeper', '~> 5.0'
|
23
|
+
gem 'doorkeeper-mongodb', '~> 5.0'
|
15
24
|
|
16
25
|
# or if you want to use cutting edge version:
|
17
26
|
# gem 'doorkeeper-mongodb', github: 'doorkeeper-gem/doorkeeper-mongodb'
|
@@ -30,7 +39,7 @@ Set the ORM configuration:
|
|
30
39
|
|
31
40
|
``` ruby
|
32
41
|
Doorkeeper.configure do
|
33
|
-
orm :mongoid6 # or :mongoid7
|
42
|
+
orm :mongoid6 # or :mongoid7, :mongoid4, :mongoid5, :mongo_mapper
|
34
43
|
end
|
35
44
|
```
|
36
45
|
|
@@ -72,6 +81,7 @@ variables defined in `.travis.yml` file.
|
|
72
81
|
To run locally, you need to choose a gemfile, with a command similar to:
|
73
82
|
|
74
83
|
```
|
84
|
+
$ export RAILS=5.1
|
75
85
|
$ export BUNDLE_GEMFILE=$PWD/gemfiles/Gemfile.mongoid6.rb
|
76
86
|
```
|
77
87
|
|
@@ -15,6 +15,7 @@ module DoorkeeperMongodb
|
|
15
15
|
validates :name, :secret, :uid, presence: true
|
16
16
|
validates :uid, uniqueness: true
|
17
17
|
validates :redirect_uri, redirect_uri: true
|
18
|
+
validates :confidential, inclusion: { in: [true, false] }
|
18
19
|
|
19
20
|
before_validation :generate_uid, :generate_secret, on: :create
|
20
21
|
|
@@ -34,7 +35,11 @@ module DoorkeeperMongodb
|
|
34
35
|
# if there is no record with such credentials
|
35
36
|
#
|
36
37
|
def by_uid_and_secret(uid, secret)
|
37
|
-
|
38
|
+
app = by_uid(uid)
|
39
|
+
return unless app
|
40
|
+
return app if secret.blank? && !app.confidential
|
41
|
+
return unless app.secret == secret
|
42
|
+
app
|
38
43
|
end
|
39
44
|
|
40
45
|
# Returns an instance of the Doorkeeper::Application with specific UID.
|
@@ -47,8 +52,30 @@ module DoorkeeperMongodb
|
|
47
52
|
def by_uid(uid)
|
48
53
|
where(uid: uid.to_s).first
|
49
54
|
end
|
55
|
+
|
56
|
+
def supports_confidentiality?
|
57
|
+
if respond_to?(:column_names)
|
58
|
+
column_names.include?("confidential")
|
59
|
+
else
|
60
|
+
fields.include?("confidential")
|
61
|
+
end
|
62
|
+
end
|
50
63
|
end
|
51
64
|
|
65
|
+
# Fallback to existing, default behaviour of assuming all apps to be
|
66
|
+
# confidential if the migration hasn't been run
|
67
|
+
def confidential
|
68
|
+
return super if self.class.supports_confidentiality?
|
69
|
+
|
70
|
+
ActiveSupport::Deprecation.warn 'You are susceptible to security bug ' \
|
71
|
+
'CVE-2018-1000211. Please follow instructions outlined in ' \
|
72
|
+
'Doorkeeper::CVE_2018_1000211_WARNING'
|
73
|
+
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
77
|
+
alias_method :confidential?, :confidential
|
78
|
+
|
52
79
|
private
|
53
80
|
|
54
81
|
def has_scopes?
|
@@ -24,6 +24,7 @@ module DoorkeeperMongodb
|
|
24
24
|
validates :name, :secret, :uid, presence: true
|
25
25
|
validates :uid, uniqueness: true
|
26
26
|
validates :redirect_uri, redirect_uri: true
|
27
|
+
validates :confidential, inclusion: { in: [true, false] }
|
27
28
|
|
28
29
|
before_validation :generate_uid, :generate_secret, on: :create
|
29
30
|
|
@@ -43,7 +44,11 @@ module DoorkeeperMongodb
|
|
43
44
|
# if there is no record with such credentials
|
44
45
|
#
|
45
46
|
def by_uid_and_secret(uid, secret)
|
46
|
-
|
47
|
+
app = by_uid(uid)
|
48
|
+
return unless app
|
49
|
+
return app if secret.blank? && !app.confidential?
|
50
|
+
return unless app.secret == secret
|
51
|
+
app
|
47
52
|
end
|
48
53
|
|
49
54
|
# Returns an instance of the Doorkeeper::Application with specific UID.
|
@@ -56,8 +61,30 @@ module DoorkeeperMongodb
|
|
56
61
|
def by_uid(uid)
|
57
62
|
where(uid: uid.to_s).first
|
58
63
|
end
|
64
|
+
|
65
|
+
def supports_confidentiality?
|
66
|
+
if respond_to?(:column_names)
|
67
|
+
column_names.include?("confidential")
|
68
|
+
else
|
69
|
+
fields.include?("confidential")
|
70
|
+
end
|
71
|
+
end
|
59
72
|
end
|
60
73
|
|
74
|
+
# Fallback to existing, default behaviour of assuming all apps to be
|
75
|
+
# confidential if the migration hasn't been run
|
76
|
+
def confidential
|
77
|
+
return super if self.class.supports_confidentiality?
|
78
|
+
|
79
|
+
ActiveSupport::Deprecation.warn 'You are susceptible to security bug ' \
|
80
|
+
'CVE-2018-1000211. Please follow instructions outlined in ' \
|
81
|
+
'Doorkeeper::CVE_2018_1000211_WARNING'
|
82
|
+
|
83
|
+
true
|
84
|
+
end
|
85
|
+
|
86
|
+
alias_method :confidential?, :confidential
|
87
|
+
|
61
88
|
private
|
62
89
|
|
63
90
|
def has_scopes?
|
@@ -54,7 +54,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'includes token type in fragment' do
|
57
|
-
expect(response.query_params['token_type']).to eq('
|
57
|
+
expect(response.query_params['token_type']).to eq('Bearer')
|
58
58
|
end
|
59
59
|
|
60
60
|
it 'includes token expiration in fragment' do
|
@@ -164,6 +164,38 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
|
|
164
164
|
it 'should not issue a token' do
|
165
165
|
expect(Doorkeeper::AccessToken.count).to be 0
|
166
166
|
end
|
167
|
+
|
168
|
+
context 'with opt_out_native_route_change' do
|
169
|
+
around(:each) do |example|
|
170
|
+
Doorkeeper.configure do
|
171
|
+
orm DOORKEEPER_ORM
|
172
|
+
opt_out_native_route_change
|
173
|
+
end
|
174
|
+
|
175
|
+
Rails.application.reload_routes!
|
176
|
+
|
177
|
+
example.run
|
178
|
+
|
179
|
+
Doorkeeper.configure do
|
180
|
+
orm DOORKEEPER_ORM
|
181
|
+
end
|
182
|
+
|
183
|
+
Rails.application.reload_routes!
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'should redirect immediately' do
|
187
|
+
expect(response).to be_redirect
|
188
|
+
expect(response.location).to match(/oauth\/authorize\/#{Doorkeeper::AccessGrant.first.token}/)
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'should issue a grant' do
|
192
|
+
expect(Doorkeeper::AccessGrant.count).to be 1
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should not issue a token' do
|
196
|
+
expect(Doorkeeper::AccessToken.count).to be 0
|
197
|
+
end
|
198
|
+
end
|
167
199
|
end
|
168
200
|
|
169
201
|
describe 'GET #new with skip_authorization true' do
|
@@ -184,7 +216,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
|
|
184
216
|
end
|
185
217
|
|
186
218
|
it 'includes token type in fragment' do
|
187
|
-
expect(response.query_params['token_type']).to eq('
|
219
|
+
expect(response.query_params['token_type']).to eq('Bearer')
|
188
220
|
end
|
189
221
|
|
190
222
|
it 'includes token expiration in fragment' do
|
@@ -59,15 +59,67 @@ describe Doorkeeper::TokensController do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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) }
|
67
90
|
|
68
|
-
|
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
|
116
|
+
|
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
|
71
123
|
end
|
72
124
|
end
|
73
125
|
|
@@ -29,6 +29,11 @@ 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
38
|
# Optional parameter confirmation: true (default false) if you want to enforce ownership of
|
34
39
|
# a registered application
|
@@ -84,6 +89,17 @@ Doorkeeper.configure do
|
|
84
89
|
#
|
85
90
|
# grant_flows %w[authorization_code client_credentials]
|
86
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
|
102
|
+
|
87
103
|
# Under some circumstances you might want to have applications auto-approved,
|
88
104
|
# so that the user skips the authorization step.
|
89
105
|
# For example if dealing with a trusted application.
|
@@ -1,4 +1,6 @@
|
|
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
|
@@ -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
|