doorkeeper 5.1.0 → 5.3.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.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +3 -3
  3. data/CHANGELOG.md +881 -0
  4. data/CONTRIBUTING.md +11 -9
  5. data/Dangerfile +2 -2
  6. data/Dockerfile +29 -0
  7. data/Gemfile +4 -3
  8. data/NEWS.md +1 -814
  9. data/README.md +11 -3
  10. data/RELEASING.md +6 -5
  11. data/app/controllers/doorkeeper/application_controller.rb +2 -2
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
  13. data/app/controllers/doorkeeper/applications_controller.rb +1 -0
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +16 -9
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  16. data/app/controllers/doorkeeper/tokens_controller.rb +32 -9
  17. data/app/views/doorkeeper/applications/_form.html.erb +0 -6
  18. data/app/views/doorkeeper/applications/show.html.erb +1 -1
  19. data/config/locales/en.yml +8 -2
  20. data/doorkeeper.gemspec +9 -1
  21. data/gemfiles/rails_5_0.gemfile +3 -2
  22. data/gemfiles/rails_5_1.gemfile +3 -2
  23. data/gemfiles/rails_5_2.gemfile +3 -2
  24. data/gemfiles/rails_6_0.gemfile +4 -3
  25. data/gemfiles/rails_master.gemfile +3 -2
  26. data/lib/doorkeeper/config/option.rb +13 -7
  27. data/lib/doorkeeper/config.rb +157 -42
  28. data/lib/doorkeeper/errors.rb +13 -18
  29. data/lib/doorkeeper/grape/helpers.rb +6 -2
  30. data/lib/doorkeeper/helpers/controller.rb +28 -7
  31. data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
  32. data/lib/doorkeeper/models/access_token_mixin.rb +99 -20
  33. data/lib/doorkeeper/models/application_mixin.rb +3 -3
  34. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  35. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  36. data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
  37. data/lib/doorkeeper/oauth/authorization/code.rb +12 -14
  38. data/lib/doorkeeper/oauth/authorization/token.rb +10 -7
  39. data/lib/doorkeeper/oauth/authorization_code_request.rb +31 -15
  40. data/lib/doorkeeper/oauth/base_request.rb +10 -4
  41. data/lib/doorkeeper/oauth/client.rb +7 -8
  42. data/lib/doorkeeper/oauth/client_credentials/creator.rb +23 -2
  43. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
  44. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +10 -2
  45. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
  46. data/lib/doorkeeper/oauth/code_request.rb +5 -11
  47. data/lib/doorkeeper/oauth/code_response.rb +4 -4
  48. data/lib/doorkeeper/oauth/error.rb +1 -1
  49. data/lib/doorkeeper/oauth/error_response.rb +6 -6
  50. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
  51. data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
  52. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +19 -5
  53. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  54. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
  55. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  56. data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -4
  57. data/lib/doorkeeper/oauth/pre_authorization.rb +76 -38
  58. data/lib/doorkeeper/oauth/refresh_token_request.rb +17 -14
  59. data/lib/doorkeeper/oauth/token.rb +2 -2
  60. data/lib/doorkeeper/oauth/token_introspection.rb +26 -16
  61. data/lib/doorkeeper/oauth/token_request.rb +4 -18
  62. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  63. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  64. data/lib/doorkeeper/orm/active_record/application.rb +5 -83
  65. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
  66. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
  67. data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
  68. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
  69. data/lib/doorkeeper/orm/active_record.rb +21 -6
  70. data/lib/doorkeeper/rails/helpers.rb +4 -4
  71. data/lib/doorkeeper/rails/routes.rb +5 -7
  72. data/lib/doorkeeper/rake/db.rake +3 -3
  73. data/lib/doorkeeper/request/authorization_code.rb +5 -3
  74. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  75. data/lib/doorkeeper/request/password.rb +2 -2
  76. data/lib/doorkeeper/request/refresh_token.rb +3 -3
  77. data/lib/doorkeeper/request.rb +7 -12
  78. data/lib/doorkeeper/server.rb +3 -7
  79. data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
  80. data/lib/doorkeeper/version.rb +1 -1
  81. data/lib/doorkeeper.rb +6 -3
  82. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  83. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  84. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  85. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  86. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +7 -7
  87. data/lib/generators/doorkeeper/templates/initializer.rb +149 -33
  88. data/lib/generators/doorkeeper/templates/migration.rb.erb +4 -1
  89. data/spec/controllers/application_metal_controller_spec.rb +1 -1
  90. data/spec/controllers/applications_controller_spec.rb +95 -1
  91. data/spec/controllers/authorizations_controller_spec.rb +156 -75
  92. data/spec/controllers/protected_resources_controller_spec.rb +28 -20
  93. data/spec/controllers/token_info_controller_spec.rb +1 -1
  94. data/spec/controllers/tokens_controller_spec.rb +206 -38
  95. data/spec/dummy/config/application.rb +3 -1
  96. data/spec/dummy/config/initializers/doorkeeper.rb +54 -9
  97. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
  98. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
  99. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
  100. data/spec/generators/install_generator_spec.rb +1 -1
  101. data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
  102. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  103. data/spec/lib/config_spec.rb +104 -7
  104. data/spec/lib/doorkeeper_spec.rb +1 -1
  105. data/spec/lib/models/revocable_spec.rb +3 -3
  106. data/spec/lib/oauth/authorization_code_request_spec.rb +129 -115
  107. data/spec/lib/oauth/base_request_spec.rb +154 -135
  108. data/spec/lib/oauth/base_response_spec.rb +27 -29
  109. data/spec/lib/oauth/client/credentials_spec.rb +1 -1
  110. data/spec/lib/oauth/client_credentials/creator_spec.rb +43 -3
  111. data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
  112. data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
  113. data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
  114. data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
  115. data/spec/lib/oauth/client_spec.rb +26 -26
  116. data/spec/lib/oauth/code_request_spec.rb +34 -35
  117. data/spec/lib/oauth/code_response_spec.rb +21 -25
  118. data/spec/lib/oauth/error_response_spec.rb +42 -44
  119. data/spec/lib/oauth/error_spec.rb +12 -14
  120. data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
  121. data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
  122. data/spec/lib/oauth/helpers/uri_checker_spec.rb +17 -2
  123. data/spec/lib/oauth/invalid_request_response_spec.rb +73 -0
  124. data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
  125. data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
  126. data/spec/lib/oauth/pre_authorization_spec.rb +161 -153
  127. data/spec/lib/oauth/refresh_token_request_spec.rb +138 -138
  128. data/spec/lib/oauth/scopes_spec.rb +104 -106
  129. data/spec/lib/oauth/token_request_spec.rb +117 -110
  130. data/spec/lib/oauth/token_response_spec.rb +71 -73
  131. data/spec/lib/oauth/token_spec.rb +121 -123
  132. data/spec/lib/server_spec.rb +0 -12
  133. data/spec/models/doorkeeper/access_grant_spec.rb +21 -4
  134. data/spec/models/doorkeeper/access_token_spec.rb +42 -11
  135. data/spec/models/doorkeeper/application_spec.rb +114 -77
  136. data/spec/requests/applications/applications_request_spec.rb +1 -1
  137. data/spec/requests/endpoints/authorization_spec.rb +26 -8
  138. data/spec/requests/endpoints/token_spec.rb +1 -1
  139. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
  140. data/spec/requests/flows/authorization_code_spec.rb +123 -45
  141. data/spec/requests/flows/client_credentials_spec.rb +38 -0
  142. data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
  143. data/spec/requests/flows/implicit_grant_spec.rb +9 -8
  144. data/spec/requests/flows/password_spec.rb +67 -10
  145. data/spec/requests/flows/refresh_token_spec.rb +20 -20
  146. data/spec/requests/flows/revoke_token_spec.rb +37 -23
  147. data/spec/spec_helper.rb +1 -4
  148. data/spec/support/doorkeeper_rspec.rb +1 -1
  149. data/spec/support/helpers/request_spec_helper.rb +14 -2
  150. data/spec/support/shared/controllers_shared_context.rb +33 -23
  151. data/spec/validators/redirect_uri_validator_spec.rb +41 -16
  152. metadata +19 -16
  153. data/.coveralls.yml +0 -1
  154. data/.github/ISSUE_TEMPLATE.md +0 -25
  155. data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  156. data/.gitignore +0 -20
  157. data/.gitlab-ci.yml +0 -16
  158. data/.hound.yml +0 -3
  159. data/.rspec +0 -1
  160. data/.rubocop.yml +0 -50
  161. data/.travis.yml +0 -35
  162. data/app/validators/redirect_uri_validator.rb +0 -50
  163. data/spec/support/http_method_shim.rb +0 -29
@@ -40,15 +40,15 @@ describe "Revocable" do
40
40
  `previous_refresh_token` attribute" do
41
41
  previous_token = FactoryBot.create(
42
42
  :access_token,
43
- refresh_token: "refresh_token"
43
+ refresh_token: "refresh_token",
44
44
  )
45
45
  current_token = FactoryBot.create(
46
46
  :access_token,
47
- previous_refresh_token: previous_token.refresh_token
47
+ previous_refresh_token: previous_token.refresh_token,
48
48
  )
49
49
 
50
50
  expect_any_instance_of(
51
- Doorkeeper::AccessToken
51
+ Doorkeeper::AccessToken,
52
52
  ).to receive(:revoke).and_call_original
53
53
  current_token.revoke_previous_refresh_token!
54
54
 
@@ -2,155 +2,169 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe AuthorizationCodeRequest do
7
- let(:server) do
8
- double :server,
9
- access_token_expires_in: 2.days,
10
- refresh_token_enabled?: false,
11
- custom_access_token_expires_in: lambda { |context|
12
- context.grant_type == Doorkeeper::OAuth::AUTHORIZATION_CODE ? 1234 : nil
13
- }
14
- end
5
+ describe Doorkeeper::OAuth::AuthorizationCodeRequest do
6
+ let(:server) do
7
+ double :server,
8
+ access_token_expires_in: 2.days,
9
+ refresh_token_enabled?: false,
10
+ custom_access_token_expires_in: lambda { |context|
11
+ context.grant_type == Doorkeeper::OAuth::AUTHORIZATION_CODE ? 1234 : nil
12
+ }
13
+ end
15
14
 
16
- let(:grant) { FactoryBot.create :access_grant }
17
- let(:client) { grant.application }
18
- let(:redirect_uri) { client.redirect_uri }
19
- let(:params) { { redirect_uri: redirect_uri } }
15
+ let(:grant) { FactoryBot.create :access_grant }
16
+ let(:client) { grant.application }
17
+ let(:redirect_uri) { client.redirect_uri }
18
+ let(:params) { { redirect_uri: redirect_uri } }
20
19
 
21
- before do
22
- allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
23
- end
20
+ before do
21
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
22
+ end
24
23
 
25
- subject do
26
- AuthorizationCodeRequest.new server, grant, client, params
27
- end
24
+ subject do
25
+ described_class.new(server, grant, client, params)
26
+ end
28
27
 
29
- it "issues a new token for the client" do
30
- expect do
31
- subject.authorize
32
- end.to change { client.reload.access_tokens.count }.by(1)
28
+ it "issues a new token for the client" do
29
+ expect do
30
+ subject.authorize
31
+ end.to change { client.reload.access_tokens.count }.by(1)
33
32
 
34
- expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(1234)
35
- end
33
+ expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(1234)
34
+ end
36
35
 
37
- it "issues the token with same grant's scopes" do
38
- subject.authorize
39
- expect(Doorkeeper::AccessToken.last.scopes).to eq(grant.scopes)
40
- end
36
+ it "issues the token with same grant's scopes" do
37
+ subject.authorize
38
+ expect(Doorkeeper::AccessToken.last.scopes).to eq(grant.scopes)
39
+ end
41
40
 
42
- it "revokes the grant" do
43
- expect { subject.authorize }.to(change { grant.reload.accessible? })
44
- end
41
+ it "revokes the grant" do
42
+ expect { subject.authorize }.to(change { grant.reload.accessible? })
43
+ end
45
44
 
46
- it "requires the grant to be accessible" do
47
- grant.revoke
48
- subject.validate
49
- expect(subject.error).to eq(:invalid_grant)
50
- end
45
+ it "requires the grant to be accessible" do
46
+ grant.revoke
47
+ subject.validate
48
+ expect(subject.error).to eq(:invalid_grant)
49
+ end
51
50
 
52
- it "requires the grant" do
53
- subject.grant = nil
54
- subject.validate
55
- expect(subject.error).to eq(:invalid_grant)
56
- end
51
+ it "requires the grant" do
52
+ subject.grant = nil
53
+ subject.validate
54
+ expect(subject.error).to eq(:invalid_grant)
55
+ end
57
56
 
58
- it "requires the client" do
59
- subject.client = nil
60
- subject.validate
61
- expect(subject.error).to eq(:invalid_client)
62
- end
57
+ it "requires the client" do
58
+ subject.client = nil
59
+ subject.validate
60
+ expect(subject.error).to eq(:invalid_client)
61
+ end
63
62
 
64
- it "requires the redirect_uri" do
65
- subject.redirect_uri = nil
66
- subject.validate
67
- expect(subject.error).to eq(:invalid_request)
68
- end
63
+ it "requires the redirect_uri" do
64
+ subject.redirect_uri = nil
65
+ subject.validate
66
+ expect(subject.error).to eq(:invalid_request)
67
+ expect(subject.missing_param).to eq(:redirect_uri)
68
+ end
69
69
 
70
- it "matches the redirect_uri with grant's one" do
71
- subject.redirect_uri = "http://other.com"
72
- subject.validate
73
- expect(subject.error).to eq(:invalid_grant)
74
- end
70
+ it "invalid code_verifier param because server does not support pkce" do
71
+ # Some other ORMs work relies on #respond_to? so it's not a good idea to stub it :\
72
+ allow_any_instance_of(Doorkeeper::AccessGrant).to receive(:respond_to?).with(anything).and_call_original
73
+ allow_any_instance_of(Doorkeeper::AccessGrant).to receive(:respond_to?).with(:code_challenge).and_return(false)
75
74
 
76
- it "matches the client with grant's one" do
77
- subject.client = FactoryBot.create :application
78
- subject.validate
79
- expect(subject.error).to eq(:invalid_grant)
80
- end
75
+ subject.code_verifier = "a45a9fea-0676-477e-95b1-a40f72ac3cfb"
76
+ subject.validate
77
+ expect(subject.error).to eq(:invalid_request)
78
+ expect(subject.invalid_request_reason).to eq(:not_support_pkce)
79
+ end
81
80
 
82
- it "skips token creation if there is a matching one reusable" do
83
- scopes = grant.scopes
81
+ it "matches the redirect_uri with grant's one" do
82
+ subject.redirect_uri = "http://other.com"
83
+ subject.validate
84
+ expect(subject.error).to eq(:invalid_grant)
85
+ end
84
86
 
85
- Doorkeeper.configure do
86
- orm DOORKEEPER_ORM
87
- reuse_access_token
88
- default_scopes(*scopes)
89
- end
87
+ it "matches the client with grant's one" do
88
+ subject.client = FactoryBot.create :application
89
+ subject.validate
90
+ expect(subject.error).to eq(:invalid_grant)
91
+ end
90
92
 
91
- FactoryBot.create(:access_token, application_id: client.id,
92
- resource_owner_id: grant.resource_owner_id, scopes: grant.scopes.to_s)
93
+ it "skips token creation if there is a matching one reusable" do
94
+ scopes = grant.scopes
93
95
 
94
- expect { subject.authorize }.to_not(change { Doorkeeper::AccessToken.count })
96
+ Doorkeeper.configure do
97
+ orm DOORKEEPER_ORM
98
+ reuse_access_token
99
+ default_scopes(*scopes)
95
100
  end
96
101
 
97
- it "creates token if there is a matching one but non reusable" do
98
- scopes = grant.scopes
102
+ FactoryBot.create(
103
+ :access_token, application_id: client.id,
104
+ resource_owner_id: grant.resource_owner_id, scopes: grant.scopes.to_s,
105
+ )
99
106
 
100
- Doorkeeper.configure do
101
- orm DOORKEEPER_ORM
102
- reuse_access_token
103
- default_scopes(*scopes)
104
- end
105
-
106
- FactoryBot.create(:access_token, application_id: client.id,
107
- resource_owner_id: grant.resource_owner_id, scopes: grant.scopes.to_s)
107
+ expect { subject.authorize }.to_not(change { Doorkeeper::AccessToken.count })
108
+ end
108
109
 
109
- allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
110
+ it "creates token if there is a matching one but non reusable" do
111
+ scopes = grant.scopes
110
112
 
111
- expect { subject.authorize }.to change { Doorkeeper::AccessToken.count }.by(1)
113
+ Doorkeeper.configure do
114
+ orm DOORKEEPER_ORM
115
+ reuse_access_token
116
+ default_scopes(*scopes)
112
117
  end
113
118
 
114
- it "calls configured request callback methods" do
115
- expect(Doorkeeper.configuration.before_successful_strategy_response)
116
- .to receive(:call).with(subject).once
117
- expect(Doorkeeper.configuration.after_successful_strategy_response)
118
- .to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
119
+ FactoryBot.create(
120
+ :access_token, application_id: client.id,
121
+ resource_owner_id: grant.resource_owner_id, scopes: grant.scopes.to_s,
122
+ )
119
123
 
120
- subject.authorize
121
- end
124
+ allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
122
125
 
123
- context "when redirect_uri contains some query params" do
124
- let(:redirect_uri) { client.redirect_uri + "?query=q" }
126
+ expect { subject.authorize }.to change { Doorkeeper::AccessToken.count }.by(1)
127
+ end
125
128
 
126
- it "compares only host part with grant's redirect_uri" do
127
- subject.validate
128
- expect(subject.error).to eq(nil)
129
- end
129
+ it "calls configured request callback methods" do
130
+ expect(Doorkeeper.configuration.before_successful_strategy_response)
131
+ .to receive(:call).with(subject).once
132
+ expect(Doorkeeper.configuration.after_successful_strategy_response)
133
+ .to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
134
+
135
+ subject.authorize
136
+ end
137
+
138
+ context "when redirect_uri contains some query params" do
139
+ let(:redirect_uri) { client.redirect_uri + "?query=q" }
140
+
141
+ it "compares only host part with grant's redirect_uri" do
142
+ subject.validate
143
+ expect(subject.error).to eq(nil)
130
144
  end
145
+ end
131
146
 
132
- context "when redirect_uri is not an URI" do
133
- let(:redirect_uri) { "123d#!s" }
147
+ context "when redirect_uri is not an URI" do
148
+ let(:redirect_uri) { "123d#!s" }
134
149
 
135
- it "responds with invalid_grant" do
136
- subject.validate
137
- expect(subject.error).to eq(:invalid_grant)
138
- end
150
+ it "responds with invalid_grant" do
151
+ subject.validate
152
+ expect(subject.error).to eq(:invalid_grant)
139
153
  end
154
+ end
140
155
 
141
- context "when redirect_uri is the native one" do
142
- let(:redirect_uri) { "urn:ietf:wg:oauth:2.0:oob" }
156
+ context "when redirect_uri is the native one" do
157
+ let(:redirect_uri) { "urn:ietf:wg:oauth:2.0:oob" }
143
158
 
144
- it "invalidates when redirect_uri of the grant is not native" do
145
- subject.validate
146
- expect(subject.error).to eq(:invalid_grant)
147
- end
159
+ it "invalidates when redirect_uri of the grant is not native" do
160
+ subject.validate
161
+ expect(subject.error).to eq(:invalid_grant)
162
+ end
148
163
 
149
- it "validates when redirect_uri of the grant is also native" do
150
- allow(grant).to receive(:redirect_uri) { redirect_uri }
151
- subject.validate
152
- expect(subject.error).to eq(nil)
153
- end
164
+ it "validates when redirect_uri of the grant is also native" do
165
+ allow(grant).to receive(:redirect_uri) { redirect_uri }
166
+ subject.validate
167
+ expect(subject.error).to eq(nil)
154
168
  end
155
169
  end
156
170
  end
@@ -2,203 +2,222 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe BaseRequest do
7
- let(:access_token) do
8
- double :access_token,
9
- plaintext_token: "some-token",
10
- expires_in: "3600",
11
- expires_in_seconds: "300",
12
- scopes_string: "two scopes",
13
- plaintext_refresh_token: "some-refresh-token",
14
- token_type: "bearer",
15
- created_at: 0
16
- end
5
+ describe Doorkeeper::OAuth::BaseRequest do
6
+ let(:access_token) do
7
+ double :access_token,
8
+ plaintext_token: "some-token",
9
+ expires_in: "3600",
10
+ expires_in_seconds: "300",
11
+ scopes_string: "two scopes",
12
+ plaintext_refresh_token: "some-refresh-token",
13
+ token_type: "bearer",
14
+ created_at: 0
15
+ end
17
16
 
18
- let(:client) { double :client, id: "1" }
17
+ let(:client) { double :client, id: "1" }
19
18
 
20
- let(:scopes_array) { %w[public write] }
19
+ let(:scopes_array) { %w[public write] }
21
20
 
22
- let(:server) do
23
- double :server,
24
- access_token_expires_in: 100,
25
- custom_access_token_expires_in: ->(_context) { nil },
26
- refresh_token_enabled?: false
27
- end
21
+ let(:server) do
22
+ double :server,
23
+ access_token_expires_in: 100,
24
+ custom_access_token_expires_in: ->(_context) { nil },
25
+ refresh_token_enabled?: false
26
+ end
27
+
28
+ before do
29
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
30
+ end
31
+
32
+ subject do
33
+ described_class.new
34
+ end
28
35
 
36
+ describe "#authorize" do
29
37
  before do
30
- allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
38
+ allow(subject).to receive(:access_token).and_return(access_token)
31
39
  end
32
40
 
33
- subject do
34
- BaseRequest.new
41
+ it "validates itself" do
42
+ expect(subject).to receive(:validate).once
43
+ subject.authorize
35
44
  end
36
45
 
37
- describe "#authorize" do
46
+ context "valid" do
38
47
  before do
39
- allow(subject).to receive(:access_token).and_return(access_token)
48
+ allow(subject).to receive(:valid?).and_return(true)
40
49
  end
41
50
 
42
- it "validates itself" do
43
- expect(subject).to receive(:validate).once
51
+ it "calls callback methods" do
52
+ expect(subject).to receive(:before_successful_response).once
53
+ expect(subject).to receive(:after_successful_response).once
44
54
  subject.authorize
45
55
  end
46
56
 
47
- context "valid" do
48
- before do
49
- allow(subject).to receive(:valid?).and_return(true)
50
- end
57
+ it "returns a TokenResponse object" do
58
+ result = subject.authorize
51
59
 
52
- it "calls callback methods" do
53
- expect(subject).to receive(:before_successful_response).once
54
- expect(subject).to receive(:after_successful_response).once
55
- subject.authorize
60
+ expect(result).to be_an_instance_of(Doorkeeper::OAuth::TokenResponse)
61
+ expect(result.body).to eq(
62
+ Doorkeeper::OAuth::TokenResponse.new(access_token).body,
63
+ )
64
+ end
65
+ end
66
+
67
+ context "invalid" do
68
+ context "with error other than invalid_request" do
69
+ before do
70
+ allow(subject).to receive(:valid?).and_return(false)
71
+ allow(subject).to receive(:error).and_return(:server_error)
72
+ allow(subject).to receive(:state).and_return("hello")
56
73
  end
57
74
 
58
- it "returns a TokenResponse object" do
75
+ it "returns an ErrorResponse object" do
59
76
  result = subject.authorize
60
77
 
61
- expect(result).to be_an_instance_of(TokenResponse)
78
+ expect(result).to be_an_instance_of(Doorkeeper::OAuth::ErrorResponse)
79
+
62
80
  expect(result.body).to eq(
63
- TokenResponse.new(access_token).body
81
+ error: :server_error,
82
+ error_description: translated_error_message(:server_error),
83
+ state: "hello",
64
84
  )
65
85
  end
66
86
  end
67
87
 
68
- context "invalid" do
88
+ context "with invalid_request error" do
69
89
  before do
70
90
  allow(subject).to receive(:valid?).and_return(false)
71
- allow(subject).to receive(:error).and_return("server_error")
91
+ allow(subject).to receive(:error).and_return(:invalid_request)
72
92
  allow(subject).to receive(:state).and_return("hello")
73
93
  end
74
94
 
75
- it "returns an ErrorResponse object" do
76
- error_description = I18n.translate(
77
- "server_error",
78
- scope: %i[doorkeeper errors messages]
79
- )
80
-
95
+ it "returns an InvalidRequestResponse object" do
81
96
  result = subject.authorize
82
97
 
83
- expect(result).to be_an_instance_of(ErrorResponse)
98
+ expect(result).to be_an_instance_of(Doorkeeper::OAuth::InvalidRequestResponse)
84
99
 
85
100
  expect(result.body).to eq(
86
- error: "server_error",
87
- error_description: error_description,
88
- state: "hello"
101
+ error: :invalid_request,
102
+ error_description: translated_invalid_request_error_message(:unknown, :unknown),
103
+ state: "hello",
89
104
  )
90
105
  end
91
106
  end
92
107
  end
108
+ end
93
109
 
94
- describe "#default_scopes" do
95
- it "delegates to the server" do
96
- expect(subject).to receive(:server).and_return(server).once
97
- expect(server).to receive(:default_scopes).once
110
+ describe "#default_scopes" do
111
+ it "delegates to the server" do
112
+ expect(subject).to receive(:server).and_return(server).once
113
+ expect(server).to receive(:default_scopes).once
98
114
 
99
- subject.default_scopes
100
- end
115
+ subject.default_scopes
101
116
  end
117
+ end
102
118
 
103
- describe "#find_or_create_access_token" do
104
- it "returns an instance of AccessToken" do
105
- result = subject.find_or_create_access_token(
106
- client,
107
- "1",
108
- "public",
109
- server
110
- )
119
+ describe "#find_or_create_access_token" do
120
+ it "returns an instance of AccessToken" do
121
+ result = subject.find_or_create_access_token(
122
+ client,
123
+ "1",
124
+ "public",
125
+ server,
126
+ )
111
127
 
112
- expect(result).to be_an_instance_of(Doorkeeper::AccessToken)
113
- end
128
+ expect(result).to be_an_instance_of(Doorkeeper::AccessToken)
129
+ end
114
130
 
115
- it "respects custom_access_token_expires_in" do
116
- server = double(:server,
117
- access_token_expires_in: 100,
118
- custom_access_token_expires_in: ->(context) { context.scopes == "public" ? 500 : nil },
119
- refresh_token_enabled?: false)
131
+ it "respects custom_access_token_expires_in" do
132
+ server = double(
133
+ :server,
134
+ access_token_expires_in: 100,
135
+ custom_access_token_expires_in: ->(context) { context.scopes == "public" ? 500 : nil },
136
+ refresh_token_enabled?: false,
137
+ )
120
138
 
121
- allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
139
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
122
140
 
123
- result = subject.find_or_create_access_token(
124
- client,
125
- "1",
126
- "public",
127
- server
128
- )
129
- expect(result.expires_in).to eql(500)
130
- end
141
+ result = subject.find_or_create_access_token(
142
+ client,
143
+ "1",
144
+ "public",
145
+ server,
146
+ )
147
+ expect(result.expires_in).to eql(500)
148
+ end
131
149
 
132
- it "respects use_refresh_token with a block" do
133
- server = double(:server,
134
- access_token_expires_in: 100,
135
- custom_access_token_expires_in: ->(_context) { nil },
136
- refresh_token_enabled?: lambda { |context|
137
- context.scopes == "public"
138
- })
139
-
140
- allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
141
-
142
- result = subject.find_or_create_access_token(
143
- client,
144
- "1",
145
- "public",
146
- server
147
- )
148
- expect(result.refresh_token).to_not be_nil
150
+ it "respects use_refresh_token with a block" do
151
+ server = double(
152
+ :server,
153
+ access_token_expires_in: 100,
154
+ custom_access_token_expires_in: ->(_context) { nil },
155
+ refresh_token_enabled?: lambda { |context|
156
+ context.scopes == "public"
157
+ },
158
+ )
149
159
 
150
- result = subject.find_or_create_access_token(
151
- client,
152
- "1",
153
- "private",
154
- server
155
- )
156
- expect(result.refresh_token).to be_nil
157
- end
160
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
161
+
162
+ result = subject.find_or_create_access_token(
163
+ client,
164
+ "1",
165
+ "public",
166
+ server,
167
+ )
168
+ expect(result.refresh_token).to_not be_nil
169
+
170
+ result = subject.find_or_create_access_token(
171
+ client,
172
+ "1",
173
+ "private",
174
+ server,
175
+ )
176
+ expect(result.refresh_token).to be_nil
158
177
  end
178
+ end
159
179
 
160
- describe "#scopes" do
161
- context "@original_scopes is present" do
162
- before do
163
- subject.instance_variable_set(:@original_scopes, "public write")
164
- end
180
+ describe "#scopes" do
181
+ context "@original_scopes is present" do
182
+ before do
183
+ subject.instance_variable_set(:@original_scopes, "public write")
184
+ end
165
185
 
166
- it "returns array of @original_scopes" do
167
- result = subject.scopes
186
+ it "returns array of @original_scopes" do
187
+ result = subject.scopes
168
188
 
169
- expect(result).to eq(scopes_array)
170
- end
189
+ expect(result).to eq(scopes_array)
171
190
  end
191
+ end
172
192
 
173
- context "@original_scopes is not present" do
174
- before do
175
- subject.instance_variable_set(:@original_scopes, "")
176
- end
193
+ context "@original_scopes is not present" do
194
+ before do
195
+ subject.instance_variable_set(:@original_scopes, "")
196
+ end
177
197
 
178
- it "calls #default_scopes" do
179
- allow(subject).to receive(:server).and_return(server).once
180
- allow(server).to receive(:default_scopes).and_return(scopes_array).once
198
+ it "calls #default_scopes" do
199
+ allow(subject).to receive(:server).and_return(server).once
200
+ allow(server).to receive(:default_scopes).and_return(scopes_array).once
181
201
 
182
- result = subject.scopes
202
+ result = subject.scopes
183
203
 
184
- expect(result).to eq(scopes_array)
185
- end
204
+ expect(result).to eq(scopes_array)
186
205
  end
187
206
  end
207
+ end
188
208
 
189
- describe "#valid?" do
190
- context "error is nil" do
191
- it "returns true" do
192
- allow(subject).to receive(:error).and_return(nil).once
193
- expect(subject.valid?).to eq(true)
194
- end
209
+ describe "#valid?" do
210
+ context "error is nil" do
211
+ it "returns true" do
212
+ allow(subject).to receive(:error).and_return(nil).once
213
+ expect(subject.valid?).to eq(true)
195
214
  end
215
+ end
196
216
 
197
- context "error is not nil" do
198
- it "returns false" do
199
- allow(subject).to receive(:error).and_return(Object.new).once
200
- expect(subject.valid?).to eq(false)
201
- end
217
+ context "error is not nil" do
218
+ it "returns false" do
219
+ allow(subject).to receive(:error).and_return(Object.new).once
220
+ expect(subject.valid?).to eq(false)
202
221
  end
203
222
  end
204
223
  end