doorkeeper 5.1.2 → 5.2.2

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.

Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +1 -1
  3. data/CHANGELOG.md +854 -0
  4. data/CONTRIBUTING.md +11 -9
  5. data/Dangerfile +2 -2
  6. data/Dockerfile +29 -0
  7. data/Gemfile +3 -2
  8. data/NEWS.md +1 -819
  9. data/README.md +11 -3
  10. data/RELEASING.md +6 -5
  11. data/app/controllers/doorkeeper/application_controller.rb +1 -1
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +2 -1
  13. data/app/controllers/doorkeeper/applications_controller.rb +5 -3
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +14 -7
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
  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 +1 -0
  22. data/gemfiles/rails_5_1.gemfile +1 -0
  23. data/gemfiles/rails_5_2.gemfile +1 -0
  24. data/gemfiles/rails_6_0.gemfile +2 -1
  25. data/gemfiles/rails_master.gemfile +1 -0
  26. data/lib/doorkeeper/config/option.rb +13 -7
  27. data/lib/doorkeeper/config.rb +88 -6
  28. data/lib/doorkeeper/errors.rb +13 -18
  29. data/lib/doorkeeper/grape/helpers.rb +5 -1
  30. data/lib/doorkeeper/helpers/controller.rb +23 -4
  31. data/lib/doorkeeper/models/access_token_mixin.rb +43 -2
  32. data/lib/doorkeeper/oauth/authorization/code.rb +11 -13
  33. data/lib/doorkeeper/oauth/authorization/token.rb +1 -1
  34. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -9
  35. data/lib/doorkeeper/oauth/base_request.rb +2 -0
  36. data/lib/doorkeeper/oauth/client_credentials/creator.rb +14 -0
  37. data/lib/doorkeeper/oauth/client_credentials/validation.rb +8 -0
  38. data/lib/doorkeeper/oauth/code_request.rb +5 -11
  39. data/lib/doorkeeper/oauth/code_response.rb +2 -2
  40. data/lib/doorkeeper/oauth/error_response.rb +1 -1
  41. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +18 -4
  42. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  43. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  44. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -2
  45. data/lib/doorkeeper/oauth/pre_authorization.rb +70 -37
  46. data/lib/doorkeeper/oauth/refresh_token_request.rb +13 -10
  47. data/lib/doorkeeper/oauth/token_introspection.rb +23 -13
  48. data/lib/doorkeeper/oauth/token_request.rb +4 -18
  49. data/lib/doorkeeper/orm/active_record/access_grant.rb +1 -1
  50. data/lib/doorkeeper/orm/active_record/access_token.rb +2 -2
  51. data/lib/doorkeeper/orm/active_record/application.rb +15 -69
  52. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
  53. data/lib/doorkeeper/orm/active_record.rb +19 -3
  54. data/lib/doorkeeper/request/authorization_code.rb +2 -0
  55. data/lib/doorkeeper/request.rb +6 -11
  56. data/lib/doorkeeper/server.rb +2 -6
  57. data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
  58. data/lib/doorkeeper/version.rb +1 -1
  59. data/lib/doorkeeper.rb +4 -0
  60. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +6 -6
  61. data/lib/generators/doorkeeper/templates/initializer.rb +110 -33
  62. data/lib/generators/doorkeeper/templates/migration.rb.erb +4 -1
  63. data/spec/controllers/applications_controller_spec.rb +93 -0
  64. data/spec/controllers/authorizations_controller_spec.rb +143 -62
  65. data/spec/controllers/protected_resources_controller_spec.rb +3 -3
  66. data/spec/controllers/tokens_controller_spec.rb +205 -37
  67. data/spec/dummy/config/application.rb +3 -1
  68. data/spec/dummy/config/initializers/doorkeeper.rb +54 -9
  69. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +1 -1
  70. data/spec/lib/config_spec.rb +43 -1
  71. data/spec/lib/oauth/authorization_code_request_spec.rb +13 -1
  72. data/spec/lib/oauth/base_request_spec.rb +33 -16
  73. data/spec/lib/oauth/client_credentials/creator_spec.rb +3 -0
  74. data/spec/lib/oauth/code_request_spec.rb +27 -28
  75. data/spec/lib/oauth/helpers/uri_checker_spec.rb +17 -2
  76. data/spec/lib/oauth/invalid_request_response_spec.rb +75 -0
  77. data/spec/lib/oauth/pre_authorization_spec.rb +76 -66
  78. data/spec/lib/oauth/refresh_token_request_spec.rb +1 -0
  79. data/spec/lib/oauth/token_request_spec.rb +20 -17
  80. data/spec/lib/server_spec.rb +0 -12
  81. data/spec/models/doorkeeper/access_grant_spec.rb +21 -2
  82. data/spec/models/doorkeeper/access_token_spec.rb +35 -4
  83. data/spec/models/doorkeeper/application_spec.rb +275 -370
  84. data/spec/requests/endpoints/authorization_spec.rb +21 -5
  85. data/spec/requests/endpoints/token_spec.rb +1 -1
  86. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
  87. data/spec/requests/flows/authorization_code_spec.rb +93 -27
  88. data/spec/requests/flows/client_credentials_spec.rb +38 -0
  89. data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
  90. data/spec/requests/flows/implicit_grant_spec.rb +9 -8
  91. data/spec/requests/flows/password_spec.rb +37 -0
  92. data/spec/requests/flows/refresh_token_spec.rb +1 -1
  93. data/spec/requests/flows/revoke_token_spec.rb +19 -11
  94. data/spec/support/doorkeeper_rspec.rb +1 -1
  95. data/spec/support/helpers/request_spec_helper.rb +14 -2
  96. data/spec/validators/redirect_uri_validator_spec.rb +40 -15
  97. metadata +16 -15
  98. data/.coveralls.yml +0 -1
  99. data/.github/ISSUE_TEMPLATE.md +0 -25
  100. data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  101. data/.gitignore +0 -20
  102. data/.gitlab-ci.yml +0 -16
  103. data/.hound.yml +0 -3
  104. data/.rspec +0 -1
  105. data/.rubocop.yml +0 -50
  106. data/.travis.yml +0 -35
  107. data/app/validators/redirect_uri_validator.rb +0 -50
@@ -4,18 +4,23 @@ require "spec_helper"
4
4
 
5
5
  module Doorkeeper::OAuth
6
6
  describe CodeRequest do
7
- let(:pre_auth) do
8
- double(
9
- :pre_auth,
10
- client: double(:application, id: 9990),
11
- redirect_uri: "http://tst.com/cb",
12
- scopes: nil,
13
- state: nil,
14
- error: nil,
15
- authorizable?: true,
16
- code_challenge: nil,
17
- code_challenge_method: nil
18
- )
7
+ let :pre_auth do
8
+ server = Doorkeeper.configuration
9
+ allow(server).to receive(:default_scopes).and_return(Scopes.from_string("public"))
10
+ allow(server).to receive(:grant_flows).and_return(Scopes.from_string("authorization_code"))
11
+
12
+ application = FactoryBot.create(:application, scopes: "public")
13
+ client = Doorkeeper::OAuth::Client.new(application)
14
+
15
+ attributes = {
16
+ client_id: client.uid,
17
+ response_type: "code",
18
+ redirect_uri: "https://app.com/callback",
19
+ }
20
+
21
+ pre_auth = PreAuthorization.new(server, attributes)
22
+ pre_auth.authorizable?
23
+ pre_auth
19
24
  end
20
25
 
21
26
  let(:owner) { double :owner, id: 8900 }
@@ -24,24 +29,18 @@ module Doorkeeper::OAuth
24
29
  CodeRequest.new(pre_auth, owner)
25
30
  end
26
31
 
27
- it "creates an access grant" do
28
- expect do
29
- subject.authorize
30
- end.to change { Doorkeeper::AccessGrant.count }.by(1)
32
+ context "when pre_auth is authorized" do
33
+ it "creates an access grant and returns a code response" do
34
+ expect { subject.authorize }.to change { Doorkeeper::AccessGrant.count }.by(1)
35
+ expect(subject.authorize).to be_a(CodeResponse)
36
+ end
31
37
  end
32
38
 
33
- it "returns a code response" do
34
- expect(subject.authorize).to be_a(CodeResponse)
35
- end
36
-
37
- it "does not create grant when not authorizable" do
38
- allow(pre_auth).to receive(:authorizable?).and_return(false)
39
- expect { subject.authorize }.not_to(change { Doorkeeper::AccessGrant.count })
40
- end
41
-
42
- it "returns a error response" do
43
- allow(pre_auth).to receive(:authorizable?).and_return(false)
44
- expect(subject.authorize).to be_a(ErrorResponse)
39
+ context "when pre_auth is denied" do
40
+ it "does not create access grant and returns a error response" do
41
+ expect { subject.deny }.not_to(change { Doorkeeper::AccessGrant.count })
42
+ expect(subject.deny).to be_a(ErrorResponse)
43
+ end
45
44
  end
46
45
  end
47
46
  end
@@ -40,13 +40,28 @@ module Doorkeeper::OAuth::Helpers
40
40
  expect(URIChecker.valid?(uri)).to be_falsey
41
41
  end
42
42
 
43
+ it "is invalid if localhost is resolved as as scheme (no scheme specified)" do
44
+ uri = "localhost:8080"
45
+ expect(URIChecker.valid?(uri)).to be_falsey
46
+ end
47
+
48
+ it "is invalid if scheme is missing #2" do
49
+ uri = "app.co:80"
50
+ expect(URIChecker.valid?(uri)).to be_falsey
51
+ end
52
+
43
53
  it "is invalid if is not an uri" do
44
54
  uri = " "
45
55
  expect(URIChecker.valid?(uri)).to be_falsey
46
56
  end
47
57
 
48
- it "is valid for native uris" do
49
- uri = "urn:ietf:wg:oauth:2.0:oob"
58
+ it "is valid for custom schemes" do
59
+ uri = "com.example.app:/test"
60
+ expect(URIChecker.valid?(uri)).to be_truthy
61
+ end
62
+
63
+ it "is valid for custom schemes with authority marker (common misconfiguration)" do
64
+ uri = "com.example.app://test"
50
65
  expect(URIChecker.valid?(uri)).to be_truthy
51
66
  end
52
67
  end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Doorkeeper::OAuth
6
+ describe InvalidRequestResponse do
7
+ describe "#name" do
8
+ it { expect(subject.name).to eq(:invalid_request) }
9
+ end
10
+
11
+ describe "#status" do
12
+ it { expect(subject.status).to eq(:bad_request) }
13
+ end
14
+
15
+ describe :from_request do
16
+ let(:response) { InvalidRequestResponse.from_request(request) }
17
+
18
+ context "missing param" do
19
+ let(:request) { double(missing_param: "some_param") }
20
+
21
+ it "sets a description" do
22
+ expect(response.description).to eq(
23
+ I18n.t(:missing_param, scope: %i[doorkeeper errors messages invalid_request], value: "some_param")
24
+ )
25
+ end
26
+
27
+ it "sets the reason" do
28
+ expect(response.reason).to eq(:missing_param)
29
+ end
30
+ end
31
+
32
+ context "server doesn not support_pkce" do
33
+ let(:request) { double(invalid_request_reason: :not_support_pkce) }
34
+
35
+ it "sets a description" do
36
+ expect(response.description).to eq(
37
+ I18n.t(:not_support_pkce, scope: %i[doorkeeper errors messages invalid_request])
38
+ )
39
+ end
40
+
41
+ it "sets the reason" do
42
+ expect(response.reason).to eq(:not_support_pkce)
43
+ end
44
+ end
45
+
46
+ context "request is not authorized" do
47
+ let(:request) { double(invalid_request_reason: :request_not_authorized) }
48
+
49
+ it "sets a description" do
50
+ expect(response.description).to eq(
51
+ I18n.t(:request_not_authorized, scope: %i[doorkeeper errors messages invalid_request])
52
+ )
53
+ end
54
+
55
+ it "sets the reason" do
56
+ expect(response.reason).to eq(:request_not_authorized)
57
+ end
58
+ end
59
+
60
+ context "unknown reason" do
61
+ let(:request) { double(invalid_request_reason: :unknown_reason) }
62
+
63
+ it "sets a description" do
64
+ expect(response.description).to eq(
65
+ I18n.t(:unknown, scope: %i[doorkeeper errors messages invalid_request])
66
+ )
67
+ end
68
+
69
+ it "unknown reason" do
70
+ expect(response.reason).to eq(:unknown_reason)
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -6,31 +6,25 @@ module Doorkeeper::OAuth
6
6
  describe PreAuthorization do
7
7
  let(:server) do
8
8
  server = Doorkeeper.configuration
9
- allow(server).to receive(:default_scopes).and_return(Scopes.new)
10
- allow(server).to receive(:scopes).and_return(Scopes.from_string("public profile"))
9
+ allow(server).to receive(:default_scopes).and_return(Scopes.from_string("default"))
10
+ allow(server).to receive(:optional_scopes).and_return(Scopes.from_string("public profile"))
11
11
  server
12
12
  end
13
13
 
14
- let(:application) do
15
- application = double :application
16
- allow(application).to receive(:scopes).and_return(Scopes.from_string(""))
17
- application
18
- end
19
-
20
- let(:client) do
21
- double :client, redirect_uri: "http://tst.com/auth", application: application
22
- end
14
+ let(:application) { FactoryBot.create(:application, redirect_uri: "https://app.com/callback") }
15
+ let(:client) { Client.find(application.uid) }
23
16
 
24
17
  let :attributes do
25
18
  {
19
+ client_id: client.uid,
26
20
  response_type: "code",
27
- redirect_uri: "http://tst.com/auth",
21
+ redirect_uri: "https://app.com/callback",
28
22
  state: "save-this",
29
23
  }
30
24
  end
31
25
 
32
26
  subject do
33
- PreAuthorization.new(server, client, attributes)
27
+ PreAuthorization.new(server, attributes)
34
28
  end
35
29
 
36
30
  it "is authorizable when request is valid" do
@@ -38,25 +32,25 @@ module Doorkeeper::OAuth
38
32
  end
39
33
 
40
34
  it "accepts code as response type" do
41
- subject.response_type = "code"
35
+ attributes[:response_type] = "code"
42
36
  expect(subject).to be_authorizable
43
37
  end
44
38
 
45
39
  it "accepts token as response type" do
46
40
  allow(server).to receive(:grant_flows).and_return(["implicit"])
47
- subject.response_type = "token"
41
+ attributes[:response_type] = "token"
48
42
  expect(subject).to be_authorizable
49
43
  end
50
44
 
51
45
  context "when using default grant flows" do
52
46
  it 'accepts "code" as response type' do
53
- subject.response_type = "code"
47
+ attributes[:response_type] = "code"
54
48
  expect(subject).to be_authorizable
55
49
  end
56
50
 
57
51
  it 'accepts "token" as response type' do
58
52
  allow(server).to receive(:grant_flows).and_return(["implicit"])
59
- subject.response_type = "token"
53
+ attributes[:response_type] = "token"
60
54
  expect(subject).to be_authorizable
61
55
  end
62
56
  end
@@ -67,7 +61,7 @@ module Doorkeeper::OAuth
67
61
  end
68
62
 
69
63
  it 'does not accept "code" as response type' do
70
- subject.response_type = "code"
64
+ attributes[:response_type] = "code"
71
65
  expect(subject).not_to be_authorizable
72
66
  end
73
67
  end
@@ -78,94 +72,90 @@ module Doorkeeper::OAuth
78
72
  end
79
73
 
80
74
  it 'does not accept "token" as response type' do
81
- subject.response_type = "token"
75
+ attributes[:response_type] = "token"
82
76
  expect(subject).not_to be_authorizable
83
77
  end
84
78
  end
85
79
 
86
80
  context "client application does not restrict valid scopes" do
87
81
  it "accepts valid scopes" do
88
- subject.scope = "public"
82
+ attributes[:scope] = "public"
89
83
  expect(subject).to be_authorizable
90
84
  end
91
85
 
92
86
  it "rejects (globally) non-valid scopes" do
93
- subject.scope = "invalid"
87
+ attributes[:scope] = "invalid"
94
88
  expect(subject).not_to be_authorizable
95
89
  end
96
90
 
97
91
  it "accepts scopes which are permitted for grant_type" do
98
92
  allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
99
- subject.scope = "public"
93
+ attributes[:scope] = "public"
100
94
  expect(subject).to be_authorizable
101
95
  end
102
96
 
103
97
  it "rejects scopes which are not permitted for grant_type" do
104
98
  allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
105
- subject.scope = "public"
99
+ attributes[:scope] = "public"
106
100
  expect(subject).not_to be_authorizable
107
101
  end
108
102
  end
109
103
 
110
104
  context "client application restricts valid scopes" do
111
105
  let(:application) do
112
- application = double :application
113
- allow(application).to receive(:scopes).and_return(Scopes.from_string("public nonsense"))
114
- application
106
+ FactoryBot.create(:application, scopes: Scopes.from_string("public nonsense"))
115
107
  end
116
108
 
117
109
  it "accepts valid scopes" do
118
- subject.scope = "public"
110
+ attributes[:scope] = "public"
119
111
  expect(subject).to be_authorizable
120
112
  end
121
113
 
122
114
  it "rejects (globally) non-valid scopes" do
123
- subject.scope = "invalid"
115
+ attributes[:scope] = "invalid"
124
116
  expect(subject).not_to be_authorizable
125
117
  end
126
118
 
127
119
  it "rejects (application level) non-valid scopes" do
128
- subject.scope = "profile"
120
+ attributes[:scope] = "profile"
129
121
  expect(subject).to_not be_authorizable
130
122
  end
131
123
 
132
124
  it "accepts scopes which are permitted for grant_type" do
133
125
  allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
134
- subject.scope = "public"
126
+ attributes[:scope] = "public"
135
127
  expect(subject).to be_authorizable
136
128
  end
137
129
 
138
130
  it "rejects scopes which are not permitted for grant_type" do
139
131
  allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
140
- subject.scope = "public"
132
+ attributes[:scope] = "public"
141
133
  expect(subject).not_to be_authorizable
142
134
  end
143
135
  end
144
136
 
145
- it "uses default scopes when none is required" do
146
- allow(server).to receive(:default_scopes).and_return(Scopes.from_string("default"))
147
- subject.scope = nil
148
- expect(subject.scope).to eq("default")
149
- expect(subject.scopes).to eq(Scopes.from_string("default"))
150
- end
151
-
152
- context "with native redirect uri" do
153
- let(:native_redirect_uri) { "urn:ietf:wg:oauth:2.0:oob" }
137
+ context "when scope is not provided to pre_authorization" do
138
+ before { attributes[:scope] = nil }
154
139
 
155
- it "accepts redirect_uri when it matches with the client" do
156
- subject.redirect_uri = native_redirect_uri
157
- allow(subject.client).to receive(:redirect_uri) { native_redirect_uri }
158
- expect(subject).to be_authorizable
140
+ context "when default scopes is provided" do
141
+ it "uses default scopes" do
142
+ allow(server).to receive(:default_scopes).and_return(Scopes.from_string("default_scope"))
143
+ expect(subject).to be_authorizable
144
+ expect(subject.scope).to eq("default_scope")
145
+ expect(subject.scopes).to eq(Scopes.from_string("default_scope"))
146
+ end
159
147
  end
160
148
 
161
- it "invalidates redirect_uri when it does'n match with the client" do
162
- subject.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
163
- expect(subject).not_to be_authorizable
149
+ context "when default scopes is none" do
150
+ it "not be authorizable when none default scope" do
151
+ allow(server).to receive(:default_scopes).and_return(Scopes.new)
152
+ expect(subject).not_to be_authorizable
153
+ end
164
154
  end
165
155
  end
166
156
 
167
157
  it "matches the redirect uri against client's one" do
168
- subject.redirect_uri = "http://nothesame.com"
158
+ attributes[:redirect_uri] = "http://nothesame.com"
169
159
  expect(subject).not_to be_authorizable
170
160
  end
171
161
 
@@ -174,41 +164,61 @@ module Doorkeeper::OAuth
174
164
  end
175
165
 
176
166
  it "rejects if response type is not allowed" do
177
- subject.response_type = "whops"
167
+ attributes[:response_type] = "whops"
178
168
  expect(subject).not_to be_authorizable
179
169
  end
180
170
 
181
171
  it "requires an existing client" do
182
- subject.client = nil
172
+ attributes[:client_id] = nil
183
173
  expect(subject).not_to be_authorizable
184
174
  end
185
175
 
186
176
  it "requires a redirect uri" do
187
- subject.redirect_uri = nil
177
+ attributes[:redirect_uri] = nil
188
178
  expect(subject).not_to be_authorizable
189
179
  end
190
180
 
191
181
  describe "as_json" do
192
- let(:client_id) { "client_uid_123" }
193
- let(:client_name) { "Acme Co." }
182
+ before { subject.authorizable? }
194
183
 
195
- before do
196
- allow(client).to receive(:uid).and_return client_id
197
- allow(client).to receive(:name).and_return client_name
184
+ it { is_expected.to respond_to :as_json }
185
+
186
+ shared_examples "returns the pre authorization" do
187
+ it "returns the pre authorization" do
188
+ expect(json[:client_id]).to eq client.uid
189
+ expect(json[:redirect_uri]).to eq subject.redirect_uri
190
+ expect(json[:state]).to eq subject.state
191
+ expect(json[:response_type]).to eq subject.response_type
192
+ expect(json[:scope]).to eq subject.scope
193
+ expect(json[:client_name]).to eq client.name
194
+ expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
195
+ end
198
196
  end
199
197
 
200
- let(:json) { subject.as_json({}) }
198
+ context "when attributes param is not passed" do
199
+ let(:json) { subject.as_json }
201
200
 
202
- it { is_expected.to respond_to :as_json }
201
+ include_examples "returns the pre authorization"
202
+ end
203
+
204
+ context "when attributes param is passed" do
205
+ context "when attributes is a hash" do
206
+ let(:custom_attributes) { { custom_id: "1234", custom_name: "a pretty good name" } }
207
+ let(:json) { subject.as_json(custom_attributes) }
208
+
209
+ include_examples "returns the pre authorization"
210
+
211
+ it "merges the attributes in params" do
212
+ expect(json[:custom_id]).to eq custom_attributes[:custom_id]
213
+ expect(json[:custom_name]).to eq custom_attributes[:custom_name]
214
+ end
215
+ end
216
+
217
+ context "when attributes is not a hash" do
218
+ let(:json) { subject.as_json(nil) }
203
219
 
204
- it "returns correct values" do
205
- expect(json[:client_id]).to eq client_id
206
- expect(json[:redirect_uri]).to eq subject.redirect_uri
207
- expect(json[:state]).to eq subject.state
208
- expect(json[:response_type]).to eq subject.response_type
209
- expect(json[:scope]).to eq subject.scope
210
- expect(json[:client_name]).to eq client_name
211
- expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
220
+ include_examples "returns the pre authorization"
221
+ end
212
222
  end
213
223
  end
214
224
  end
@@ -63,6 +63,7 @@ module Doorkeeper::OAuth
63
63
  subject.refresh_token = nil
64
64
  subject.validate
65
65
  expect(subject.error).to eq(:invalid_request)
66
+ expect(subject.missing_param).to eq(:refresh_token)
66
67
  end
67
68
 
68
69
  it "requires credentials to be valid if provided" do
@@ -9,15 +9,21 @@ module Doorkeeper::OAuth
9
9
  end
10
10
 
11
11
  let :pre_auth do
12
- double(
13
- :pre_auth,
14
- client: application,
15
- redirect_uri: "http://tst.com/cb",
16
- state: nil,
17
- scopes: Scopes.from_string("public"),
18
- error: nil,
19
- authorizable?: true
20
- )
12
+ server = Doorkeeper.configuration
13
+ allow(server).to receive(:default_scopes).and_return(Scopes.from_string("public"))
14
+ allow(server).to receive(:grant_flows).and_return(Scopes.from_string("implicit"))
15
+
16
+ client = Doorkeeper::OAuth::Client.new(application)
17
+
18
+ attributes = {
19
+ client_id: client.uid,
20
+ response_type: "token",
21
+ redirect_uri: "https://app.com/callback",
22
+ }
23
+
24
+ pre_auth = PreAuthorization.new(server, attributes)
25
+ pre_auth.authorizable?
26
+ pre_auth
21
27
  end
22
28
 
23
29
  let :owner do
@@ -38,14 +44,11 @@ module Doorkeeper::OAuth
38
44
  expect(subject.authorize).to be_a(CodeResponse)
39
45
  end
40
46
 
41
- it "does not create token when not authorizable" do
42
- allow(pre_auth).to receive(:authorizable?).and_return(false)
43
- expect { subject.authorize }.not_to(change { Doorkeeper::AccessToken.count })
44
- end
45
-
46
- it "returns a error response" do
47
- allow(pre_auth).to receive(:authorizable?).and_return(false)
48
- expect(subject.authorize).to be_a(ErrorResponse)
47
+ context "when pre_auth is denied" do
48
+ it "does not create token and returns a error response" do
49
+ expect { subject.deny }.not_to(change { Doorkeeper::AccessToken.count })
50
+ expect(subject.deny).to be_a(ErrorResponse)
51
+ end
49
52
  end
50
53
 
51
54
  describe "with custom expiration" do
@@ -10,12 +10,6 @@ describe Doorkeeper::Server do
10
10
  end
11
11
 
12
12
  describe ".authorization_request" do
13
- it "raises error when strategy does not exist" do
14
- expect do
15
- subject.authorization_request(:duh)
16
- end.to raise_error(Doorkeeper::Errors::InvalidAuthorizationStrategy)
17
- end
18
-
19
13
  it "raises error when strategy does not match phase" do
20
14
  expect do
21
15
  subject.token_request(:code)
@@ -29,12 +23,6 @@ describe Doorkeeper::Server do
29
23
  .and_return(["authorization_code"])
30
24
  end
31
25
 
32
- it "raises error when using the disabled Implicit strategy" do
33
- expect do
34
- subject.authorization_request(:token)
35
- end.to raise_error(Doorkeeper::Errors::InvalidAuthorizationStrategy)
36
- end
37
-
38
26
  it "raises error when using the disabled Client Credentials strategy" do
39
27
  expect do
40
28
  subject.token_request(:client_credentials)
@@ -61,10 +61,29 @@ describe Doorkeeper::AccessGrant do
61
61
  it "upgrades a plain token when falling back to it" do
62
62
  # Side-effect: This will automatically upgrade the token
63
63
  expect(clazz).to receive(:upgrade_fallback_value).and_call_original
64
- expect(clazz.by_token(plain_text_token)).to eq(grant)
64
+ expect(clazz.by_token(plain_text_token))
65
+ .to have_attributes(
66
+ resource_owner_id: grant.resource_owner_id,
67
+ application_id: grant.application_id,
68
+ redirect_uri: grant.redirect_uri,
69
+ expires_in: grant.expires_in,
70
+ scopes: grant.scopes,
71
+ )
65
72
 
66
73
  # Will find subsequently by hashing the token
67
- expect(clazz.by_token(plain_text_token)).to eq(grant)
74
+ expect(clazz.by_token(plain_text_token))
75
+ .to have_attributes(
76
+ resource_owner_id: grant.resource_owner_id,
77
+ application_id: grant.application_id,
78
+ redirect_uri: grant.redirect_uri,
79
+ expires_in: grant.expires_in,
80
+ scopes: grant.scopes,
81
+ )
82
+
83
+ # Not all the ORM support :id PK
84
+ if grant.respond_to?(:id)
85
+ expect(clazz.by_token(plain_text_token).id).to eq(grant.id)
86
+ end
68
87
 
69
88
  # And it modifies the token value
70
89
  grant.reload
@@ -73,10 +73,25 @@ module Doorkeeper
73
73
  it "upgrades a plain token when falling back to it" do
74
74
  # Side-effect: This will automatically upgrade the token
75
75
  expect(clazz).to receive(:upgrade_fallback_value).and_call_original
76
- expect(clazz.by_token(plain_text_token)).to eq(access_token)
76
+ expect(clazz.by_token(plain_text_token))
77
+ .to have_attributes(
78
+ resource_owner_id: access_token.resource_owner_id,
79
+ application_id: access_token.application_id,
80
+ scopes: access_token.scopes,
81
+ )
77
82
 
78
83
  # Will find subsequently by hashing the token
79
- expect(clazz.by_token(plain_text_token)).to eq(access_token)
84
+ expect(clazz.by_token(plain_text_token))
85
+ .to have_attributes(
86
+ resource_owner_id: access_token.resource_owner_id,
87
+ application_id: access_token.application_id,
88
+ scopes: access_token.scopes,
89
+ )
90
+
91
+ # Not all the ORM support :id PK
92
+ if access_token.respond_to?(:id)
93
+ expect(clazz.by_token(plain_text_token).id).to eq(access_token.id)
94
+ end
80
95
 
81
96
  # And it modifies the token value
82
97
  access_token.reload
@@ -113,6 +128,7 @@ module Doorkeeper
113
128
  eigenclass.class_eval do
114
129
  remove_method :generate
115
130
  end
131
+
116
132
  module CustomGeneratorArgs
117
133
  def self.generate(opts = {})
118
134
  "custom_generator_token_#{opts[:application].name}"
@@ -307,10 +323,25 @@ module Doorkeeper
307
323
  it "upgrades a plain token when falling back to it" do
308
324
  # Side-effect: This will automatically upgrade the token
309
325
  expect(clazz).to receive(:upgrade_fallback_value).and_call_original
310
- expect(clazz.by_refresh_token(plain_refresh_token)).to eq(access_token)
326
+ expect(clazz.by_refresh_token(plain_refresh_token))
327
+ .to have_attributes(
328
+ token: access_token.token,
329
+ resource_owner_id: access_token.resource_owner_id,
330
+ application_id: access_token.application_id,
331
+ )
311
332
 
312
333
  # Will find subsequently by hashing the token
313
- expect(clazz.by_refresh_token(plain_refresh_token)).to eq(access_token)
334
+ expect(clazz.by_refresh_token(plain_refresh_token))
335
+ .to have_attributes(
336
+ token: access_token.token,
337
+ resource_owner_id: access_token.resource_owner_id,
338
+ application_id: access_token.application_id,
339
+ )
340
+
341
+ # Not all the ORM support :id PK
342
+ if access_token.respond_to?(:id)
343
+ expect(clazz.by_refresh_token(plain_refresh_token).id).to eq(access_token.id)
344
+ end
314
345
 
315
346
  # And it modifies the token value
316
347
  access_token.reload