doorkeeper 4.3.2 → 5.0.0.rc1

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.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +4 -0
  4. data/.travis.yml +2 -0
  5. data/Appraisals +2 -2
  6. data/Gemfile +1 -1
  7. data/NEWS.md +36 -0
  8. data/README.md +85 -3
  9. data/Rakefile +6 -0
  10. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  11. data/app/controllers/doorkeeper/application_controller.rb +4 -3
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -0
  13. data/app/controllers/doorkeeper/applications_controller.rb +43 -22
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +15 -1
  16. data/app/controllers/doorkeeper/tokens_controller.rb +2 -6
  17. data/app/helpers/doorkeeper/dashboard_helper.rb +7 -7
  18. data/app/validators/redirect_uri_validator.rb +3 -2
  19. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  20. data/app/views/doorkeeper/applications/_form.html.erb +31 -19
  21. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  22. data/app/views/doorkeeper/applications/index.html.erb +18 -6
  23. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  24. data/app/views/doorkeeper/applications/show.html.erb +8 -5
  25. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  26. data/app/views/doorkeeper/authorizations/new.html.erb +4 -0
  27. data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
  28. data/config/locales/en.yml +15 -1
  29. data/gemfiles/rails_5_2.gemfile +1 -1
  30. data/lib/doorkeeper/config.rb +60 -23
  31. data/lib/doorkeeper/engine.rb +4 -0
  32. data/lib/doorkeeper/errors.rb +2 -5
  33. data/lib/doorkeeper/grape/helpers.rb +1 -1
  34. data/lib/doorkeeper/helpers/controller.rb +7 -2
  35. data/lib/doorkeeper/models/access_grant_mixin.rb +56 -0
  36. data/lib/doorkeeper/models/access_token_mixin.rb +37 -20
  37. data/lib/doorkeeper/models/application_mixin.rb +8 -1
  38. data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
  39. data/lib/doorkeeper/oauth/authorization/code.rb +31 -8
  40. data/lib/doorkeeper/oauth/authorization/context.rb +15 -0
  41. data/lib/doorkeeper/oauth/authorization/token.rb +23 -6
  42. data/lib/doorkeeper/oauth/authorization_code_request.rb +27 -2
  43. data/lib/doorkeeper/oauth/base_request.rb +18 -8
  44. data/lib/doorkeeper/oauth/client/credentials.rb +4 -2
  45. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +6 -1
  46. data/lib/doorkeeper/oauth/client_credentials/validation.rb +4 -2
  47. data/lib/doorkeeper/oauth/error_response.rb +11 -3
  48. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +0 -8
  49. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -0
  50. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -4
  51. data/lib/doorkeeper/oauth/pre_authorization.rb +45 -13
  52. data/lib/doorkeeper/oauth/refresh_token_request.rb +6 -1
  53. data/lib/doorkeeper/oauth/scopes.rb +1 -1
  54. data/lib/doorkeeper/oauth/token.rb +5 -2
  55. data/lib/doorkeeper/oauth/token_introspection.rb +2 -2
  56. data/lib/doorkeeper/oauth/token_response.rb +4 -2
  57. data/lib/doorkeeper/oauth.rb +13 -0
  58. data/lib/doorkeeper/orm/active_record/application.rb +14 -0
  59. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
  60. data/lib/doorkeeper/orm/active_record.rb +2 -0
  61. data/lib/doorkeeper/rails/helpers.rb +2 -4
  62. data/lib/doorkeeper/rails/routes.rb +13 -1
  63. data/lib/doorkeeper/rake/db.rake +40 -0
  64. data/lib/doorkeeper/rake/setup.rake +6 -0
  65. data/lib/doorkeeper/rake.rb +14 -0
  66. data/lib/doorkeeper/request/password.rb +1 -11
  67. data/lib/doorkeeper/request.rb +28 -28
  68. data/lib/doorkeeper/version.rb +5 -4
  69. data/lib/doorkeeper.rb +4 -17
  70. data/lib/generators/doorkeeper/application_owner_generator.rb +23 -18
  71. data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
  72. data/lib/generators/doorkeeper/install_generator.rb +17 -9
  73. data/lib/generators/doorkeeper/migration_generator.rb +23 -18
  74. data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
  75. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -24
  76. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  77. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
  78. data/lib/generators/doorkeeper/templates/initializer.rb +60 -9
  79. data/lib/generators/doorkeeper/templates/migration.rb.erb +1 -0
  80. data/lib/generators/doorkeeper/views_generator.rb +3 -1
  81. data/spec/controllers/application_metal_controller_spec.rb +50 -0
  82. data/spec/controllers/applications_controller_spec.rb +126 -13
  83. data/spec/controllers/authorizations_controller_spec.rb +250 -15
  84. data/spec/controllers/protected_resources_controller_spec.rb +16 -16
  85. data/spec/controllers/token_info_controller_spec.rb +4 -12
  86. data/spec/controllers/tokens_controller_spec.rb +12 -14
  87. data/spec/dummy/app/assets/config/manifest.js +2 -0
  88. data/spec/dummy/config/environments/test.rb +4 -5
  89. data/spec/dummy/config/initializers/doorkeeper.rb +6 -0
  90. data/spec/dummy/config/initializers/new_framework_defaults.rb +4 -0
  91. data/spec/dummy/config/routes.rb +3 -42
  92. data/spec/dummy/db/migrate/20111122132257_create_users.rb +3 -1
  93. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +3 -1
  94. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -1
  95. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +3 -1
  96. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +3 -1
  97. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
  98. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +13 -0
  99. data/spec/dummy/db/schema.rb +38 -37
  100. data/spec/generators/application_owner_generator_spec.rb +1 -1
  101. data/spec/generators/confidential_applications_generator_spec.rb +45 -0
  102. data/spec/generators/install_generator_spec.rb +1 -1
  103. data/spec/generators/migration_generator_spec.rb +1 -1
  104. data/spec/generators/pkce_generator_spec.rb +43 -0
  105. data/spec/generators/previous_refresh_token_generator_spec.rb +1 -1
  106. data/spec/generators/views_generator_spec.rb +1 -1
  107. data/spec/grape/grape_integration_spec.rb +1 -1
  108. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  109. data/spec/lib/config_spec.rb +59 -14
  110. data/spec/lib/doorkeeper_spec.rb +1 -126
  111. data/spec/lib/models/expirable_spec.rb +0 -3
  112. data/spec/lib/models/revocable_spec.rb +0 -2
  113. data/spec/lib/models/scopes_spec.rb +0 -4
  114. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
  115. data/spec/lib/oauth/authorization_code_request_spec.rb +24 -2
  116. data/spec/lib/oauth/base_request_spec.rb +16 -2
  117. data/spec/lib/oauth/base_response_spec.rb +1 -1
  118. data/spec/lib/oauth/client/credentials_spec.rb +5 -5
  119. data/spec/lib/oauth/client_credentials/creator_spec.rb +5 -1
  120. data/spec/lib/oauth/client_credentials/issuer_spec.rb +26 -7
  121. data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -3
  122. data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
  123. data/spec/lib/oauth/client_credentials_request_spec.rb +3 -5
  124. data/spec/lib/oauth/client_spec.rb +0 -3
  125. data/spec/lib/oauth/code_request_spec.rb +4 -2
  126. data/spec/lib/oauth/error_response_spec.rb +0 -3
  127. data/spec/lib/oauth/error_spec.rb +0 -2
  128. data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
  129. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -3
  130. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
  131. data/spec/lib/oauth/helpers/uri_checker_spec.rb +5 -2
  132. data/spec/lib/oauth/invalid_token_response_spec.rb +1 -4
  133. data/spec/lib/oauth/password_access_token_request_spec.rb +37 -2
  134. data/spec/lib/oauth/pre_authorization_spec.rb +40 -6
  135. data/spec/lib/oauth/refresh_token_request_spec.rb +11 -7
  136. data/spec/lib/oauth/scopes_spec.rb +0 -3
  137. data/spec/lib/oauth/token_request_spec.rb +4 -5
  138. data/spec/lib/oauth/token_response_spec.rb +0 -1
  139. data/spec/lib/oauth/token_spec.rb +37 -14
  140. data/spec/lib/orm/active_record/stale_records_cleaner_spec.rb +79 -0
  141. data/spec/lib/request/strategy_spec.rb +0 -1
  142. data/spec/lib/server_spec.rb +1 -1
  143. data/spec/models/doorkeeper/access_grant_spec.rb +1 -1
  144. data/spec/models/doorkeeper/access_token_spec.rb +50 -16
  145. data/spec/models/doorkeeper/application_spec.rb +51 -6
  146. data/spec/requests/applications/applications_request_spec.rb +89 -1
  147. data/spec/requests/applications/authorized_applications_spec.rb +1 -1
  148. data/spec/requests/endpoints/authorization_spec.rb +1 -1
  149. data/spec/requests/endpoints/token_spec.rb +7 -5
  150. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -1
  151. data/spec/requests/flows/authorization_code_spec.rb +197 -1
  152. data/spec/requests/flows/client_credentials_spec.rb +46 -6
  153. data/spec/requests/flows/implicit_grant_errors_spec.rb +1 -1
  154. data/spec/requests/flows/implicit_grant_spec.rb +38 -11
  155. data/spec/requests/flows/password_spec.rb +120 -23
  156. data/spec/requests/flows/refresh_token_spec.rb +2 -2
  157. data/spec/requests/flows/revoke_token_spec.rb +11 -11
  158. data/spec/requests/flows/skip_authorization_spec.rb +16 -11
  159. data/spec/requests/protected_resources/metal_spec.rb +1 -1
  160. data/spec/requests/protected_resources/private_api_spec.rb +1 -1
  161. data/spec/routing/custom_controller_routes_spec.rb +59 -7
  162. data/spec/routing/default_routes_spec.rb +2 -2
  163. data/spec/routing/scoped_routes_spec.rb +16 -2
  164. data/spec/spec_helper.rb +54 -3
  165. data/spec/spec_helper_integration.rb +2 -74
  166. data/spec/support/doorkeeper_rspec.rb +19 -0
  167. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  168. data/spec/support/helpers/request_spec_helper.rb +2 -2
  169. data/spec/support/helpers/url_helper.rb +7 -3
  170. data/spec/support/http_method_shim.rb +12 -16
  171. data/spec/validators/redirect_uri_validator_spec.rb +7 -1
  172. data/spec/version/version_spec.rb +3 -3
  173. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  174. metadata +32 -8
  175. data/spec/controllers/application_metal_controller.rb +0 -10
  176. /data/spec/support/dependencies/{factory_girl.rb → factory_bot.rb} +0 -0
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Doorkeeper do
4
4
  describe "#authenticate" do
@@ -22,129 +22,4 @@ describe Doorkeeper do
22
22
  Doorkeeper.authenticate(request, token_strategies)
23
23
  end
24
24
  end
25
-
26
- describe "#configured?" do
27
- after do
28
- Doorkeeper.remove_instance_variable(:@config)
29
- end
30
-
31
- context "@config is set" do
32
- it "returns true" do
33
- Doorkeeper.instance_variable_set(:@config, "hi")
34
-
35
- expect(Doorkeeper.configured?).to eq(true)
36
- end
37
- end
38
-
39
- context "@config is not set" do
40
- it "returns false" do
41
- Doorkeeper.instance_variable_set(:@config, nil)
42
-
43
- expect(Doorkeeper.configured?).to eq(false)
44
- end
45
- end
46
-
47
- it "is deprecated" do
48
- expect(ActiveSupport::Deprecation).to receive(:warn).
49
- with("Method `Doorkeeper#configured?` has been deprecated without replacement.")
50
-
51
- Doorkeeper.configured?
52
- end
53
- end
54
-
55
- describe "#database_installed?" do
56
- before do
57
- ["AccessToken", "AccessGrant", "Application"].each do |klass|
58
- @original_classes ||= {}
59
- @original_classes[klass] = Doorkeeper.const_get(klass)
60
- Doorkeeper.send(:remove_const, klass)
61
- end
62
- end
63
-
64
- after do
65
- ["AccessToken", "AccessGrant", "Application"].each do |klass|
66
- Doorkeeper.send(:remove_const, klass)
67
- Doorkeeper.const_set(klass, @original_classes[klass])
68
- end
69
- end
70
-
71
- context "all tables exist" do
72
- before do
73
- klass = double table_exists?: true
74
-
75
- Doorkeeper.const_set(:AccessToken, klass)
76
- Doorkeeper.const_set(:AccessGrant, klass)
77
- Doorkeeper.const_set(:Application, klass)
78
- end
79
-
80
- it "returns true" do
81
- expect(Doorkeeper.database_installed?).to eq(true)
82
- end
83
-
84
- it "is deprecated" do
85
- expect(ActiveSupport::Deprecation).to receive(:warn).
86
- with("Method `Doorkeeper#database_installed?` has been deprecated without replacement.")
87
-
88
- Doorkeeper.database_installed?
89
- end
90
- end
91
-
92
- context "all tables do not exist" do
93
- before do
94
- klass = double table_exists?: false
95
-
96
- Doorkeeper.const_set(:AccessToken, klass)
97
- Doorkeeper.const_set(:AccessGrant, klass)
98
- Doorkeeper.const_set(:Application, klass)
99
- end
100
-
101
- it "returns false" do
102
- expect(Doorkeeper.database_installed?).to eq(false)
103
- end
104
-
105
- it "is deprecated" do
106
- expect(ActiveSupport::Deprecation).to receive(:warn).
107
- with("Method `Doorkeeper#database_installed?` has been deprecated without replacement.")
108
-
109
- Doorkeeper.database_installed?
110
- end
111
- end
112
- end
113
-
114
- describe "#installed?" do
115
- context "methods return true" do
116
- before do
117
- allow(Doorkeeper).to receive(:configured?).and_return(true).once
118
- allow(Doorkeeper).to receive(:database_installed?).and_return(true).once
119
- end
120
-
121
- it "returns true" do
122
- expect(Doorkeeper.installed?).to eq(true)
123
- end
124
- end
125
-
126
- context "methods return false" do
127
- before do
128
- allow(Doorkeeper).to receive(:configured?).and_return(false).once
129
- allow(Doorkeeper).to receive(:database_installed?).and_return(false).once
130
- end
131
-
132
- it "returns false" do
133
- expect(Doorkeeper.installed?).to eq(false)
134
- end
135
- end
136
-
137
- it "is deprecated" do
138
- expect(ActiveSupport::Deprecation).to receive(:warn).
139
- with("Method `Doorkeeper#configured?` has been deprecated without replacement.")
140
-
141
- expect(ActiveSupport::Deprecation).to receive(:warn).
142
- with("Method `Doorkeeper#database_installed?` has been deprecated without replacement.")
143
-
144
- expect(ActiveSupport::Deprecation).to receive(:warn).
145
- with("Method `Doorkeeper#installed?` has been deprecated without replacement.")
146
-
147
- Doorkeeper.installed?
148
- end
149
- end
150
25
  end
@@ -1,6 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/time'
3
- require 'doorkeeper/models/concerns/expirable'
4
2
 
5
3
  describe 'Expirable' do
6
4
  subject do
@@ -45,6 +43,5 @@ describe 'Expirable' do
45
43
  allow(subject).to receive(:expires_in).and_return(nil)
46
44
  expect(subject.expires_in_seconds).to be_nil
47
45
  end
48
-
49
46
  end
50
47
  end
@@ -1,6 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/core_ext/object/blank'
3
- require 'doorkeeper/models/concerns/revocable'
4
2
 
5
3
  describe 'Revocable' do
6
4
  subject do
@@ -1,8 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/core_ext/module/delegation'
3
- require 'active_support/core_ext/object/blank'
4
- require 'doorkeeper/oauth/scopes'
5
- require 'doorkeeper/models/concerns/scopes'
6
2
 
7
3
  describe 'Doorkeeper::Models::Scopes' do
8
4
  subject do
@@ -1,8 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/core_ext/string'
3
- require 'uri'
4
- require 'rack/utils'
5
- require 'doorkeeper/oauth/authorization/uri_builder'
6
2
 
7
3
  module Doorkeeper::OAuth::Authorization
8
4
  describe URIBuilder do
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe AuthorizationCodeRequest do
@@ -6,7 +6,9 @@ module Doorkeeper::OAuth
6
6
  double :server,
7
7
  access_token_expires_in: 2.days,
8
8
  refresh_token_enabled?: false,
9
- custom_access_token_expires_in: ->(_app) { nil }
9
+ custom_access_token_expires_in: lambda { |context|
10
+ context.grant_type == Doorkeeper::OAuth::AUTHORIZATION_CODE ? 1234 : nil
11
+ }
10
12
  end
11
13
 
12
14
  let(:grant) { FactoryBot.create :access_grant }
@@ -22,6 +24,8 @@ module Doorkeeper::OAuth
22
24
  expect do
23
25
  subject.authorize
24
26
  end.to change { client.reload.access_tokens.count }.by(1)
27
+
28
+ expect(client.reload.access_tokens.sort_by(&:created_at).last.expires_in).to eq(1234)
25
29
  end
26
30
 
27
31
  it "issues the token with same grant's scopes" do
@@ -70,9 +74,12 @@ module Doorkeeper::OAuth
70
74
  end
71
75
 
72
76
  it 'skips token creation if there is a matching one' do
77
+ scopes = grant.scopes
78
+
73
79
  Doorkeeper.configure do
74
80
  orm DOORKEEPER_ORM
75
81
  reuse_access_token
82
+ default_scopes(*scopes)
76
83
  end
77
84
 
78
85
  FactoryBot.create(:access_token, application_id: client.id,
@@ -104,5 +111,20 @@ module Doorkeeper::OAuth
104
111
  expect(subject.error).to eq(:invalid_grant)
105
112
  end
106
113
  end
114
+
115
+ context "when redirect_uri is the native one" do
116
+ let(:redirect_uri) { 'urn:ietf:wg:oauth:2.0:oob' }
117
+
118
+ it "invalidates when redirect_uri of the grant is not native" do
119
+ subject.validate
120
+ expect(subject.error).to eq(:invalid_grant)
121
+ end
122
+
123
+ it "validates when redirect_uri of the grant is also native" do
124
+ allow(grant).to receive(:redirect_uri) { redirect_uri }
125
+ subject.validate
126
+ expect(subject.error).to eq(nil)
127
+ end
128
+ end
107
129
  end
108
130
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe BaseRequest do
@@ -20,7 +20,7 @@ module Doorkeeper::OAuth
20
20
  let(:server) do
21
21
  double :server,
22
22
  access_token_expires_in: 100,
23
- custom_access_token_expires_in: ->(_) { nil },
23
+ custom_access_token_expires_in: ->(_context) { nil },
24
24
  refresh_token_enabled?: false
25
25
  end
26
26
 
@@ -105,6 +105,20 @@ module Doorkeeper::OAuth
105
105
 
106
106
  expect(result).to be_an_instance_of(Doorkeeper::AccessToken)
107
107
  end
108
+
109
+ it "respects custom_access_token_expires_in" do
110
+ server = double(:server,
111
+ access_token_expires_in: 100,
112
+ custom_access_token_expires_in: ->(context) { context.scopes == "public" ? 500 : nil },
113
+ refresh_token_enabled?: false)
114
+ result = subject.find_or_create_access_token(
115
+ client,
116
+ "1",
117
+ "public",
118
+ server
119
+ )
120
+ expect(result.expires_in).to eql(500)
121
+ end
108
122
  end
109
123
 
110
124
  describe "#scopes" do
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe BaseResponse do
@@ -1,22 +1,22 @@
1
1
  require 'spec_helper'
2
- require 'active_support/core_ext/string'
3
- require 'doorkeeper/oauth/client'
4
2
 
5
3
  class Doorkeeper::OAuth::Client
6
4
  describe Credentials do
7
5
  let(:client_id) { 'some-uid' }
8
6
  let(:client_secret) { 'some-secret' }
9
7
 
10
- it 'is blank when any of the credentials is blank' do
8
+ it 'is blank when the uid in credentials is blank' do
9
+ expect(Credentials.new(nil, nil)).to be_blank
11
10
  expect(Credentials.new(nil, 'something')).to be_blank
12
- expect(Credentials.new('something', nil)).to be_blank
11
+ expect(Credentials.new('something', nil)).to be_present
12
+ expect(Credentials.new('something', 'something')).to be_present
13
13
  end
14
14
 
15
15
  describe :from_request do
16
16
  let(:request) { double.as_null_object }
17
17
 
18
18
  let(:method) do
19
- ->(_request) { return 'uid', 'secret' }
19
+ ->(_request) { ['uid', 'secret'] }
20
20
  end
21
21
 
22
22
  it 'accepts anything that responds to #call' do
@@ -1,10 +1,14 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  class Doorkeeper::OAuth::ClientCredentialsRequest
4
4
  describe Creator do
5
5
  let(:client) { FactoryBot.create :application }
6
6
  let(:scopes) { Doorkeeper::OAuth::Scopes.from_string('public') }
7
7
 
8
+ before do
9
+ default_scopes_exist :public
10
+ end
11
+
8
12
  it 'creates a new token' do
9
13
  expect do
10
14
  subject.call(client, scopes)
@@ -1,6 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/all'
3
- require 'doorkeeper/oauth/client_credentials/issuer'
4
2
 
5
3
  class Doorkeeper::OAuth::ClientCredentialsRequest
6
4
  describe Issuer do
@@ -9,7 +7,7 @@ class Doorkeeper::OAuth::ClientCredentialsRequest
9
7
  double(
10
8
  :server,
11
9
  access_token_expires_in: 100,
12
- custom_access_token_expires_in: ->(_app) { nil }
10
+ custom_access_token_expires_in: ->(_context) { nil }
13
11
  )
14
12
  end
15
13
  let(:validation) { double :validation, valid?: true }
@@ -63,23 +61,44 @@ class Doorkeeper::OAuth::ClientCredentialsRequest
63
61
  end
64
62
 
65
63
  context 'with custom expirations' do
66
- let(:custom_ttl) { 1233 }
64
+ let(:custom_ttl_grant) { 1234 }
65
+ let(:custom_ttl_scope) { 1235 }
66
+ let(:custom_scope) { 'special' }
67
67
  let(:server) do
68
68
  double(
69
69
  :server,
70
- custom_access_token_expires_in: ->(_app) { custom_ttl }
70
+ custom_access_token_expires_in: lambda { |context|
71
+ # scopes is normally an object but is a string in this test
72
+ if context.scopes == custom_scope
73
+ custom_ttl_scope
74
+ elsif context.grant_type == Doorkeeper::OAuth::CLIENT_CREDENTIALS
75
+ custom_ttl_grant
76
+ else
77
+ nil
78
+ end
79
+ }
71
80
  )
72
81
  end
73
82
 
74
- it 'creates with correct token parameters' do
83
+ it 'respects grant based rules' do
75
84
  expect(creator).to receive(:call).with(
76
85
  client,
77
86
  scopes,
78
- expires_in: custom_ttl,
87
+ expires_in: custom_ttl_grant,
79
88
  use_refresh_token: false
80
89
  )
81
90
  subject.create client, scopes, creator
82
91
  end
92
+
93
+ it 'respects scope based rules' do
94
+ expect(creator).to receive(:call).with(
95
+ client,
96
+ custom_scope,
97
+ expires_in: custom_ttl_scope,
98
+ use_refresh_token: false
99
+ )
100
+ subject.create client, custom_scope, creator
101
+ end
83
102
  end
84
103
  end
85
104
  end
@@ -1,6 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/all'
3
- require 'doorkeeper/oauth/client_credentials/validation'
4
2
 
5
3
  class Doorkeeper::OAuth::ClientCredentialsRequest
6
4
  describe Validation do
@@ -45,7 +43,8 @@ class Doorkeeper::OAuth::ClientCredentialsRequest
45
43
  allow(application).to receive(:scopes).and_return(application_scopes)
46
44
  allow(server).to receive(:scopes).and_return(server_scopes)
47
45
  allow(request).to receive(:scopes).and_return(
48
- Doorkeeper::OAuth::Scopes.from_string 'email')
46
+ Doorkeeper::OAuth::Scopes.from_string('email')
47
+ )
49
48
  expect(subject).not_to be_valid
50
49
  end
51
50
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe ClientCredentialsRequest do
@@ -1,18 +1,16 @@
1
1
  require 'spec_helper'
2
- require 'active_support/all'
3
- require 'active_model'
4
- require 'doorkeeper/oauth/client_credentials_request'
5
2
 
6
3
  module Doorkeeper::OAuth
7
4
  describe ClientCredentialsRequest do
8
5
  let(:server) do
9
6
  double(
10
7
  default_scopes: nil,
11
- custom_access_token_expires_in: ->(_app) { nil }
8
+ access_token_expires_in: 2.hours,
9
+ custom_access_token_expires_in: ->(_context) { nil }
12
10
  )
13
11
  end
14
12
 
15
- let(:application) { double :application, scopes: Scopes.from_string('') }
13
+ let(:application) { FactoryBot.create(:application, scopes: '') }
16
14
  let(:client) { double :client, application: application }
17
15
  let(:token_creator) { double :issuer, create: true, token: double }
18
16
 
@@ -1,7 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/core_ext/module/delegation'
3
- require 'active_support/core_ext/string'
4
- require 'doorkeeper/oauth/client'
5
2
 
6
3
  module Doorkeeper::OAuth
7
4
  describe Client do
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe CodeRequest do
@@ -10,7 +10,9 @@ module Doorkeeper::OAuth
10
10
  scopes: nil,
11
11
  state: nil,
12
12
  error: nil,
13
- authorizable?: true
13
+ authorizable?: true,
14
+ code_challenge: nil,
15
+ code_challenge_method: nil,
14
16
  )
15
17
  end
16
18
 
@@ -1,7 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_model'
3
- require 'doorkeeper/oauth/error'
4
- require 'doorkeeper/oauth/error_response'
5
2
 
6
3
  module Doorkeeper::OAuth
7
4
  describe ErrorResponse do
@@ -1,6 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/i18n'
3
- require 'doorkeeper/oauth/error'
4
2
 
5
3
  module Doorkeeper::OAuth
6
4
  describe Error do
@@ -1,12 +1,9 @@
1
1
  require 'spec_helper'
2
- require 'active_model'
3
- require 'doorkeeper'
4
- require 'doorkeeper/oauth/forbidden_token_response'
5
2
 
6
3
  module Doorkeeper::OAuth
7
4
  describe ForbiddenTokenResponse do
8
5
  describe '#name' do
9
- it { expect(subject.name).to eq(:invalid_scope) }
6
+ it { expect(subject.name).to eq(:invalid_scope) }
10
7
  end
11
8
 
12
9
  describe '#status' do
@@ -1,7 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'active_support/core_ext/string'
3
- require 'doorkeeper/oauth/helpers/scope_checker'
4
- require 'doorkeeper/oauth/scopes'
5
2
 
6
3
  module Doorkeeper::OAuth::Helpers
7
4
  describe ScopeChecker, '.valid?' do
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'doorkeeper/oauth/helpers/unique_token'
3
2
 
4
3
  module Doorkeeper::OAuth::Helpers
5
4
  describe UniqueToken do
@@ -1,6 +1,4 @@
1
1
  require 'spec_helper'
2
- require 'uri'
3
- require 'doorkeeper/oauth/helpers/uri_checker'
4
2
 
5
3
  module Doorkeeper::OAuth::Helpers
6
4
  describe URIChecker do
@@ -44,6 +42,11 @@ module Doorkeeper::OAuth::Helpers
44
42
  uri = ' '
45
43
  expect(URIChecker.valid?(uri)).to be_falsey
46
44
  end
45
+
46
+ it 'is valid for native uris' do
47
+ uri = 'urn:ietf:wg:oauth:2.0:oob'
48
+ expect(URIChecker.valid?(uri)).to be_truthy
49
+ end
47
50
  end
48
51
 
49
52
  describe '.matches?' do
@@ -1,12 +1,9 @@
1
1
  require 'spec_helper'
2
- require 'active_model'
3
- require 'doorkeeper'
4
- require 'doorkeeper/oauth/invalid_token_response'
5
2
 
6
3
  module Doorkeeper::OAuth
7
4
  describe InvalidTokenResponse do
8
5
  describe "#name" do
9
- it { expect(subject.name).to eq(:invalid_token) }
6
+ it { expect(subject.name).to eq(:invalid_token) }
10
7
  end
11
8
 
12
9
  describe "#status" do
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe PasswordAccessTokenRequest do
@@ -8,7 +8,9 @@ module Doorkeeper::OAuth
8
8
  default_scopes: Doorkeeper::OAuth::Scopes.new,
9
9
  access_token_expires_in: 2.hours,
10
10
  refresh_token_enabled?: false,
11
- custom_access_token_expires_in: ->(_app) { nil }
11
+ custom_access_token_expires_in: lambda { |context|
12
+ context.grant_type == Doorkeeper::OAuth::PASSWORD ? 1234 : nil
13
+ }
12
14
  )
13
15
  end
14
16
  let(:client) { FactoryBot.create(:application) }
@@ -22,6 +24,7 @@ module Doorkeeper::OAuth
22
24
  expect do
23
25
  subject.authorize
24
26
  end.to change { client.reload.access_tokens.count }.by(1)
27
+ expect(client.reload.access_tokens.sort_by(&:created_at).last.expires_in).to eq(1234)
25
28
  end
26
29
 
27
30
  it 'issues a new token without a client' do
@@ -92,5 +95,37 @@ module Doorkeeper::OAuth
92
95
  expect(Doorkeeper::AccessToken.last.scopes).to include('public')
93
96
  end
94
97
  end
98
+
99
+ describe 'with custom expiry' do
100
+ let(:server) do
101
+ double(
102
+ :server,
103
+ default_scopes: Doorkeeper::OAuth::Scopes.new,
104
+ access_token_expires_in: 2.hours,
105
+ refresh_token_enabled?: false,
106
+ custom_access_token_expires_in: lambda { |context|
107
+ context.scopes.exists?('public') ? 222 : nil
108
+ }
109
+ )
110
+ end
111
+
112
+ it 'checks scopes' do
113
+ subject = PasswordAccessTokenRequest.new(server, client, owner, scope: 'public')
114
+ allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('public'))
115
+ expect do
116
+ subject.authorize
117
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
118
+ expect(Doorkeeper::AccessToken.last.expires_in).to eq(222)
119
+ end
120
+
121
+ it 'falls back to the default otherwise' do
122
+ subject = PasswordAccessTokenRequest.new(server, client, owner, scope: 'private')
123
+ allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('private'))
124
+ expect do
125
+ subject.authorize
126
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
127
+ expect(Doorkeeper::AccessToken.last.expires_in).to eq(2.hours)
128
+ end
129
+ end
95
130
  end
96
131
  end
@@ -1,13 +1,13 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper::OAuth
4
4
  describe PreAuthorization do
5
- let(:server) {
5
+ let(:server) do
6
6
  server = Doorkeeper.configuration
7
7
  allow(server).to receive(:default_scopes).and_return(Scopes.new)
8
8
  allow(server).to receive(:scopes).and_return(Scopes.from_string('public profile'))
9
9
  server
10
- }
10
+ end
11
11
 
12
12
  let(:application) do
13
13
  application = double :application
@@ -123,9 +123,19 @@ module Doorkeeper::OAuth
123
123
  expect(subject.scopes).to eq(Scopes.from_string('default'))
124
124
  end
125
125
 
126
- it 'accepts test uri' do
127
- subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
128
- expect(subject).to be_authorizable
126
+ context 'with native redirect uri' do
127
+ let(:native_redirect_uri) { 'urn:ietf:wg:oauth:2.0:oob' }
128
+
129
+ it 'accepts redirect_uri when it matches with the client' do
130
+ subject.redirect_uri = native_redirect_uri
131
+ allow(subject.client).to receive(:redirect_uri) { native_redirect_uri }
132
+ expect(subject).to be_authorizable
133
+ end
134
+
135
+ it 'invalidates redirect_uri when it does\'n match with the client' do
136
+ subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
137
+ expect(subject).not_to be_authorizable
138
+ end
129
139
  end
130
140
 
131
141
  it 'matches the redirect uri against client\'s one' do
@@ -151,5 +161,29 @@ module Doorkeeper::OAuth
151
161
  subject.redirect_uri = nil
152
162
  expect(subject).not_to be_authorizable
153
163
  end
164
+
165
+ describe "as_json" do
166
+ let(:client_id) { "client_uid_123" }
167
+ let(:client_name) { "Acme Co." }
168
+
169
+ before do
170
+ allow(client).to receive(:uid).and_return client_id
171
+ allow(client).to receive(:name).and_return client_name
172
+ end
173
+
174
+ let(:json) { subject.as_json({}) }
175
+
176
+ it { is_expected.to respond_to :as_json }
177
+
178
+ it "returns correct values" do
179
+ expect(json[:client_id]).to eq client_id
180
+ expect(json[:redirect_uri]).to eq subject.redirect_uri
181
+ expect(json[:state]).to eq subject.state
182
+ expect(json[:response_type]).to eq subject.response_type
183
+ expect(json[:scope]).to eq subject.scope
184
+ expect(json[:client_name]).to eq client_name
185
+ expect(json[:status]).to eq I18n.t('doorkeeper.pre_authorization.status')
186
+ end
187
+ end
154
188
  end
155
189
  end