doorkeeper 5.3.0 → 5.4.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 (120) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +0 -14
  3. data/CHANGELOG.md +44 -1
  4. data/Dangerfile +7 -7
  5. data/Dockerfile +2 -2
  6. data/Gemfile +9 -9
  7. data/README.md +6 -4
  8. data/app/controllers/doorkeeper/applications_controller.rb +4 -4
  9. data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
  10. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  11. data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
  12. data/app/views/doorkeeper/applications/show.html.erb +19 -2
  13. data/bin/console +14 -0
  14. data/config/locales/en.yml +3 -1
  15. data/doorkeeper.gemspec +1 -1
  16. data/gemfiles/rails_5_0.gemfile +8 -7
  17. data/gemfiles/rails_5_1.gemfile +8 -7
  18. data/gemfiles/rails_5_2.gemfile +8 -7
  19. data/gemfiles/rails_6_0.gemfile +8 -7
  20. data/gemfiles/rails_master.gemfile +8 -7
  21. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  22. data/lib/doorkeeper/config/option.rb +28 -14
  23. data/lib/doorkeeper/config.rb +41 -17
  24. data/lib/doorkeeper/grape/helpers.rb +1 -1
  25. data/lib/doorkeeper/models/access_grant_mixin.rb +9 -11
  26. data/lib/doorkeeper/models/access_token_mixin.rb +102 -42
  27. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  28. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  29. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  30. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  31. data/lib/doorkeeper/oauth/authorization/code.rb +14 -5
  32. data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
  33. data/lib/doorkeeper/oauth/authorization/token.rb +7 -11
  34. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  35. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
  36. data/lib/doorkeeper/oauth/base_request.rb +11 -19
  37. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  38. data/lib/doorkeeper/oauth/client.rb +1 -1
  39. data/lib/doorkeeper/oauth/client_credentials/creator.rb +25 -7
  40. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  41. data/lib/doorkeeper/oauth/client_credentials/validator.rb +1 -1
  42. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  43. data/lib/doorkeeper/oauth/code_request.rb +1 -1
  44. data/lib/doorkeeper/oauth/code_response.rb +6 -2
  45. data/lib/doorkeeper/oauth/error_response.rb +2 -4
  46. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
  47. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  48. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  49. data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -5
  50. data/lib/doorkeeper/oauth/pre_authorization.rb +32 -27
  51. data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
  52. data/lib/doorkeeper/oauth/token.rb +1 -1
  53. data/lib/doorkeeper/oauth/token_introspection.rb +3 -3
  54. data/lib/doorkeeper/oauth/token_request.rb +2 -2
  55. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  56. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +7 -2
  57. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +6 -2
  58. data/lib/doorkeeper/orm/active_record/mixins/application.rb +6 -2
  59. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  60. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  61. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  62. data/lib/doorkeeper/rails/routes.rb +13 -17
  63. data/lib/doorkeeper/request/strategy.rb +2 -2
  64. data/lib/doorkeeper/server.rb +3 -3
  65. data/lib/doorkeeper/version.rb +2 -2
  66. data/lib/doorkeeper.rb +106 -79
  67. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  68. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  69. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
  70. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  71. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  72. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  73. data/lib/generators/doorkeeper/templates/initializer.rb +47 -3
  74. data/lib/generators/doorkeeper/templates/migration.rb.erb +2 -0
  75. data/spec/controllers/applications_controller_spec.rb +2 -2
  76. data/spec/controllers/authorizations_controller_spec.rb +165 -30
  77. data/spec/controllers/tokens_controller_spec.rb +6 -5
  78. data/spec/dummy/app/helpers/application_helper.rb +1 -1
  79. data/spec/dummy/app/models/user.rb +5 -1
  80. data/spec/dummy/config/application.rb +6 -4
  81. data/spec/dummy/config/boot.rb +4 -4
  82. data/spec/dummy/config/environment.rb +1 -1
  83. data/spec/dummy/config/routes.rb +4 -4
  84. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +2 -2
  85. data/spec/dummy/db/schema.rb +3 -1
  86. data/spec/factories.rb +1 -1
  87. data/spec/generators/enable_polymorphic_resource_owner_generator_spec.rb +47 -0
  88. data/spec/lib/config_spec.rb +30 -11
  89. data/spec/lib/models/revocable_spec.rb +2 -3
  90. data/spec/lib/models/scopes_spec.rb +8 -0
  91. data/spec/lib/oauth/authorization_code_request_spec.rb +25 -15
  92. data/spec/lib/oauth/base_request_spec.rb +6 -20
  93. data/spec/lib/oauth/client_credentials/creator_spec.rb +90 -89
  94. data/spec/lib/oauth/client_credentials/issuer_spec.rb +84 -86
  95. data/spec/lib/oauth/client_credentials/validation_spec.rb +38 -40
  96. data/spec/lib/oauth/client_credentials_request_spec.rb +5 -4
  97. data/spec/lib/oauth/code_request_spec.rb +1 -1
  98. data/spec/lib/oauth/code_response_spec.rb +5 -1
  99. data/spec/lib/oauth/error_response_spec.rb +1 -1
  100. data/spec/lib/oauth/password_access_token_request_spec.rb +24 -13
  101. data/spec/lib/oauth/pre_authorization_spec.rb +13 -18
  102. data/spec/lib/oauth/refresh_token_request_spec.rb +19 -30
  103. data/spec/lib/oauth/token_request_spec.rb +14 -7
  104. data/spec/lib/option_spec.rb +51 -0
  105. data/spec/lib/stale_records_cleaner_spec.rb +18 -5
  106. data/spec/models/doorkeeper/access_grant_spec.rb +18 -4
  107. data/spec/models/doorkeeper/access_token_spec.rb +507 -479
  108. data/spec/models/doorkeeper/application_spec.rb +338 -300
  109. data/spec/requests/endpoints/token_spec.rb +5 -1
  110. data/spec/requests/flows/authorization_code_errors_spec.rb +4 -1
  111. data/spec/requests/flows/authorization_code_spec.rb +6 -1
  112. data/spec/requests/flows/client_credentials_spec.rb +41 -0
  113. data/spec/requests/flows/refresh_token_spec.rb +16 -8
  114. data/spec/requests/flows/revoke_token_spec.rb +143 -104
  115. data/spec/support/helpers/access_token_request_helper.rb +1 -0
  116. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  117. data/spec/support/helpers/config_helper.rb +1 -1
  118. data/spec/support/shared/controllers_shared_context.rb +2 -2
  119. data/spec/support/shared/models_shared_examples.rb +6 -4
  120. metadata +15 -4
@@ -12,7 +12,12 @@ describe Doorkeeper::OAuth::AuthorizationCodeRequest do
12
12
  }
13
13
  end
14
14
 
15
- let(:grant) { FactoryBot.create :access_grant }
15
+ let(:resource_owner) { FactoryBot.create :resource_owner }
16
+ let(:grant) do
17
+ FactoryBot.create :access_grant,
18
+ resource_owner_id: resource_owner.id,
19
+ resource_owner_type: resource_owner.class.name
20
+ end
16
21
  let(:client) { grant.application }
17
22
  let(:redirect_uri) { client.redirect_uri }
18
23
  let(:params) { { redirect_uri: redirect_uri } }
@@ -49,43 +54,42 @@ describe Doorkeeper::OAuth::AuthorizationCodeRequest do
49
54
  end
50
55
 
51
56
  it "requires the grant" do
52
- subject.grant = nil
57
+ subject = described_class.new(server, nil, client, params)
53
58
  subject.validate
54
59
  expect(subject.error).to eq(:invalid_grant)
55
60
  end
56
61
 
57
62
  it "requires the client" do
58
- subject.client = nil
63
+ subject = described_class.new(server, grant, nil, params)
59
64
  subject.validate
60
65
  expect(subject.error).to eq(:invalid_client)
61
66
  end
62
67
 
63
68
  it "requires the redirect_uri" do
64
- subject.redirect_uri = nil
69
+ subject = described_class.new(server, grant, nil, params.except(:redirect_uri))
65
70
  subject.validate
66
71
  expect(subject.error).to eq(:invalid_request)
67
72
  expect(subject.missing_param).to eq(:redirect_uri)
68
73
  end
69
74
 
70
75
  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)
74
-
75
- subject.code_verifier = "a45a9fea-0676-477e-95b1-a40f72ac3cfb"
76
+ allow(Doorkeeper::AccessGrant).to receive(:pkce_supported?).and_return(false)
77
+ code_verifier = "a45a9fea-0676-477e-95b1-a40f72ac3cfb"
78
+ subject = described_class.new(server, grant, client, params.merge(code_verifier: code_verifier))
76
79
  subject.validate
77
80
  expect(subject.error).to eq(:invalid_request)
78
81
  expect(subject.invalid_request_reason).to eq(:not_support_pkce)
79
82
  end
80
83
 
81
84
  it "matches the redirect_uri with grant's one" do
82
- subject.redirect_uri = "http://other.com"
85
+ subject = described_class.new(server, grant, client, params.merge(redirect_uri: "http://other.com"))
83
86
  subject.validate
84
87
  expect(subject.error).to eq(:invalid_grant)
85
88
  end
86
89
 
87
90
  it "matches the client with grant's one" do
88
- subject.client = FactoryBot.create :application
91
+ other_client = FactoryBot.create :application
92
+ subject = described_class.new(server, grant, other_client, params)
89
93
  subject.validate
90
94
  expect(subject.error).to eq(:invalid_grant)
91
95
  end
@@ -100,8 +104,11 @@ describe Doorkeeper::OAuth::AuthorizationCodeRequest do
100
104
  end
101
105
 
102
106
  FactoryBot.create(
103
- :access_token, application_id: client.id,
104
- resource_owner_id: grant.resource_owner_id, scopes: grant.scopes.to_s,
107
+ :access_token,
108
+ application_id: client.id,
109
+ resource_owner_id: grant.resource_owner_id,
110
+ resource_owner_type: grant.resource_owner_type,
111
+ scopes: grant.scopes.to_s,
105
112
  )
106
113
 
107
114
  expect { subject.authorize }.to_not(change { Doorkeeper::AccessToken.count })
@@ -117,8 +124,11 @@ describe Doorkeeper::OAuth::AuthorizationCodeRequest do
117
124
  end
118
125
 
119
126
  FactoryBot.create(
120
- :access_token, application_id: client.id,
121
- resource_owner_id: grant.resource_owner_id, scopes: grant.scopes.to_s,
127
+ :access_token,
128
+ application_id: client.id,
129
+ resource_owner_id: grant.resource_owner_id,
130
+ resource_owner_type: grant.resource_owner_type,
131
+ scopes: grant.scopes.to_s,
122
132
  )
123
133
 
124
134
  allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
@@ -117,10 +117,12 @@ describe Doorkeeper::OAuth::BaseRequest do
117
117
  end
118
118
 
119
119
  describe "#find_or_create_access_token" do
120
+ let(:resource_owner) { FactoryBot.build_stubbed(:resource_owner) }
121
+
120
122
  it "returns an instance of AccessToken" do
121
123
  result = subject.find_or_create_access_token(
122
124
  client,
123
- "1",
125
+ resource_owner,
124
126
  "public",
125
127
  server,
126
128
  )
@@ -140,7 +142,7 @@ describe Doorkeeper::OAuth::BaseRequest do
140
142
 
141
143
  result = subject.find_or_create_access_token(
142
144
  client,
143
- "1",
145
+ resource_owner,
144
146
  "public",
145
147
  server,
146
148
  )
@@ -161,7 +163,7 @@ describe Doorkeeper::OAuth::BaseRequest do
161
163
 
162
164
  result = subject.find_or_create_access_token(
163
165
  client,
164
- "1",
166
+ resource_owner,
165
167
  "public",
166
168
  server,
167
169
  )
@@ -169,7 +171,7 @@ describe Doorkeeper::OAuth::BaseRequest do
169
171
 
170
172
  result = subject.find_or_create_access_token(
171
173
  client,
172
- "1",
174
+ resource_owner,
173
175
  "private",
174
176
  server,
175
177
  )
@@ -205,20 +207,4 @@ describe Doorkeeper::OAuth::BaseRequest do
205
207
  end
206
208
  end
207
209
  end
208
-
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)
214
- end
215
- end
216
-
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)
221
- end
222
- end
223
- end
224
210
  end
@@ -2,133 +2,134 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- class Doorkeeper::OAuth::ClientCredentialsRequest
6
- describe Creator do
7
- let(:client) { FactoryBot.create :application }
8
- let(:scopes) { Doorkeeper::OAuth::Scopes.from_string("public") }
5
+ describe Doorkeeper::OAuth::ClientCredentials::Creator do
6
+ let(:client) { FactoryBot.create :application }
7
+ let(:scopes) { Doorkeeper::OAuth::Scopes.from_string("public") }
9
8
 
10
- before do
11
- default_scopes_exist :public
12
- end
9
+ before do
10
+ default_scopes_exist :public
11
+ end
13
12
 
14
- it "creates a new token" do
15
- expect do
16
- subject.call(client, scopes)
17
- end.to change { Doorkeeper::AccessToken.count }.by(1)
13
+ it "creates a new token" do
14
+ expect do
15
+ subject.call(client, scopes)
16
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
17
+ end
18
+
19
+ context "when reuse_access_token is true" do
20
+ before do
21
+ allow(Doorkeeper.config).to receive(:reuse_access_token).and_return(true)
18
22
  end
19
23
 
20
- context "when reuse_access_token is true" do
21
- context "when expiration is disabled" do
22
- it "returns the existing valid token" do
23
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
24
- existing_token = subject.call(client, scopes)
24
+ context "when expiration is disabled" do
25
+ it "returns the existing valid token" do
26
+ existing_token = subject.call(client, scopes)
25
27
 
26
- result = subject.call(client, scopes)
28
+ result = subject.call(client, scopes)
27
29
 
28
- expect(Doorkeeper::AccessToken.count).to eq(1)
29
- expect(result).to eq(existing_token)
30
- end
30
+ expect(Doorkeeper::AccessToken.count).to eq(1)
31
+ expect(result).to eq(existing_token)
31
32
  end
33
+ end
32
34
 
33
- context "when existing token has not crossed token_reuse_limit" do
34
- let!(:existing_token) { subject.call(client, scopes, expires_in: 1000) }
35
-
36
- before do
37
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
38
- allow(Doorkeeper.configuration).to receive(:token_reuse_limit).and_return(50)
39
- allow_any_instance_of(Doorkeeper::AccessToken).to receive(:expires_in_seconds).and_return(600)
40
- end
41
-
42
- it "returns the existing valid token" do
43
- result = subject.call(client, scopes, expires_in: 1000)
35
+ context "when existing token has not crossed token_reuse_limit" do
36
+ let!(:existing_token) { subject.call(client, scopes, expires_in: 1000) }
44
37
 
45
- expect(Doorkeeper::AccessToken.count).to eq(1)
46
- expect(result).to eq(existing_token)
47
- end
38
+ before do
39
+ allow(Doorkeeper.config).to receive(:token_reuse_limit).and_return(50)
40
+ allow_any_instance_of(Doorkeeper::AccessToken).to receive(:expires_in_seconds).and_return(600)
41
+ end
48
42
 
49
- context "and when revoke_previous_client_credentials_token is true" do
50
- before do
51
- allow(Doorkeeper.configuration).to receive(:revoke_previous_client_credentials_token).and_return(false)
52
- end
43
+ it "returns the existing valid token" do
44
+ result = subject.call(client, scopes, expires_in: 1000)
53
45
 
54
- it "does not revoke the existing valid token" do
55
- subject.call(client, scopes, expires_in: 1000)
56
- expect(existing_token.reload).not_to be_revoked
57
- end
58
- end
46
+ expect(Doorkeeper::AccessToken.count).to eq(1)
47
+ expect(result).to eq(existing_token)
59
48
  end
60
49
 
61
- context "when existing token has crossed token_reuse_limit" do
62
- it "returns a new token" do
63
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
64
- allow(Doorkeeper.configuration).to receive(:token_reuse_limit).and_return(50)
65
- existing_token = subject.call(client, scopes, expires_in: 1000)
66
-
67
- allow_any_instance_of(Doorkeeper::AccessToken).to receive(:expires_in_seconds).and_return(400)
68
- result = subject.call(client, scopes, expires_in: 1000)
50
+ context "and when revoke_previous_client_credentials_token is false" do
51
+ before do
52
+ allow(Doorkeeper.config).to receive(:revoke_previous_client_credentials_token).and_return(false)
53
+ end
69
54
 
70
- expect(Doorkeeper::AccessToken.count).to eq(2)
71
- expect(result).not_to eq(existing_token)
55
+ it "does not revoke the existing valid token" do
56
+ subject.call(client, scopes, expires_in: 1000)
57
+ expect(existing_token.reload).not_to be_revoked
72
58
  end
73
59
  end
60
+ end
74
61
 
75
- context "when existing token has been expired" do
76
- it "returns a new token" do
77
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
78
- allow(Doorkeeper.configuration).to receive(:token_reuse_limit).and_return(50)
79
- existing_token = subject.call(client, scopes, expires_in: 1000)
62
+ context "when existing token has crossed token_reuse_limit" do
63
+ it "returns a new token" do
64
+ allow(Doorkeeper.config).to receive(:token_reuse_limit).and_return(50)
65
+ existing_token = subject.call(client, scopes, expires_in: 1000)
80
66
 
81
- allow_any_instance_of(Doorkeeper::AccessToken).to receive(:expired?).and_return(true)
82
- result = subject.call(client, scopes, expires_in: 1000)
67
+ allow_any_instance_of(Doorkeeper::AccessToken).to receive(:expires_in_seconds).and_return(400)
68
+ result = subject.call(client, scopes, expires_in: 1000)
83
69
 
84
- expect(Doorkeeper::AccessToken.count).to eq(2)
85
- expect(result).not_to eq(existing_token)
86
- end
70
+ expect(Doorkeeper::AccessToken.count).to eq(2)
71
+ expect(result).not_to eq(existing_token)
87
72
  end
88
73
  end
89
74
 
90
- context "when reuse_access_token is false" do
75
+ context "when existing token has been expired" do
91
76
  it "returns a new token" do
92
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(false)
93
- existing_token = subject.call(client, scopes)
77
+ allow(Doorkeeper.configuration).to receive(:token_reuse_limit).and_return(50)
78
+ existing_token = subject.call(client, scopes, expires_in: 1000)
94
79
 
95
- result = subject.call(client, scopes)
80
+ allow_any_instance_of(Doorkeeper::AccessToken).to receive(:expired?).and_return(true)
81
+ result = subject.call(client, scopes, expires_in: 1000)
96
82
 
97
83
  expect(Doorkeeper::AccessToken.count).to eq(2)
98
84
  expect(result).not_to eq(existing_token)
99
85
  end
100
86
  end
87
+ end
101
88
 
102
- context "when revoke_previous_client_credentials_token is true" do
103
- let!(:existing_token) { subject.call(client, scopes, expires_in: 1000) }
89
+ context "when reuse_access_token is false" do
90
+ before do
91
+ allow(Doorkeeper.config).to receive(:reuse_access_token).and_return(false)
92
+ end
104
93
 
105
- before do
106
- allow(Doorkeeper.configuration).to receive(:revoke_previous_client_credentials_token).and_return(true)
107
- end
94
+ it "returns a new token" do
95
+ existing_token = subject.call(client, scopes)
108
96
 
109
- it "revokes the existing token" do
110
- subject.call(client, scopes, expires_in: 1000)
111
- expect(existing_token.reload).to be_revoked
112
- end
97
+ result = subject.call(client, scopes)
98
+
99
+ expect(Doorkeeper::AccessToken.count).to eq(2)
100
+ expect(result).not_to eq(existing_token)
113
101
  end
102
+ end
114
103
 
115
- context "when revoke_previous_client_credentials_token is false" do
116
- let!(:existing_token) { subject.call(client, scopes, expires_in: 1000) }
104
+ context "when revoke_previous_client_credentials_token is true" do
105
+ let!(:existing_token) { subject.call(client, scopes, expires_in: 1000) }
117
106
 
118
- before do
119
- allow(Doorkeeper.configuration).to receive(:revoke_previous_client_credentials_token).and_return(false)
120
- end
107
+ before do
108
+ allow(Doorkeeper.configuration).to receive(:revoke_previous_client_credentials_token).and_return(true)
109
+ end
121
110
 
122
- it "does not revoke the existing token" do
123
- subject.call(client, scopes, expires_in: 1000)
124
- expect(existing_token.reload).not_to be_revoked
125
- end
111
+ it "revokes the existing token" do
112
+ subject.call(client, scopes, expires_in: 1000)
113
+ expect(existing_token.reload).to be_revoked
114
+ end
115
+ end
116
+
117
+ context "when revoke_previous_client_credentials_token is false" do
118
+ let!(:existing_token) { subject.call(client, scopes, expires_in: 1000) }
119
+
120
+ before do
121
+ allow(Doorkeeper.configuration).to receive(:revoke_previous_client_credentials_token).and_return(false)
126
122
  end
127
123
 
128
- it "returns false if creation fails" do
129
- expect(Doorkeeper::AccessToken).to receive(:find_or_create_for).and_return(false)
130
- created = subject.call(client, scopes)
131
- expect(created).to be_falsey
124
+ it "does not revoke the existing token" do
125
+ subject.call(client, scopes, expires_in: 1000)
126
+ expect(existing_token.reload).not_to be_revoked
132
127
  end
133
128
  end
129
+
130
+ it "returns false if creation fails" do
131
+ expect(Doorkeeper::AccessToken).to receive(:find_or_create_for).and_return(false)
132
+ created = subject.call(client, scopes)
133
+ expect(created).to be_falsey
134
+ end
134
135
  end
@@ -2,110 +2,108 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- class Doorkeeper::OAuth::ClientCredentialsRequest
6
- describe Issuer do
7
- let(:creator) { double :access_token_creator }
8
- let(:server) do
9
- double(
10
- :server,
11
- access_token_expires_in: 100,
12
- )
5
+ describe Doorkeeper::OAuth::ClientCredentials::Issuer do
6
+ let(:creator) { double :access_token_creator }
7
+ let(:server) do
8
+ double(
9
+ :server,
10
+ access_token_expires_in: 100,
11
+ )
12
+ end
13
+ let(:validator) { double :validator, valid?: true }
14
+
15
+ before do
16
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(false)
17
+ end
18
+
19
+ subject { described_class.new(server, validator) }
20
+
21
+ describe "#create" do
22
+ let(:client) { double :client, id: "some-id" }
23
+ let(:scopes) { "some scope" }
24
+
25
+ it "creates and sets the token" do
26
+ expect(creator).to receive(:call).and_return("token")
27
+ subject.create client, scopes, creator
28
+
29
+ expect(subject.token).to eq("token")
13
30
  end
14
- let(:validator) { double :validator, valid?: true }
15
31
 
16
- before do
17
- allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(false)
32
+ it "creates with correct token parameters" do
33
+ expect(creator).to receive(:call).with(
34
+ client,
35
+ scopes,
36
+ expires_in: 100,
37
+ use_refresh_token: false,
38
+ )
39
+
40
+ subject.create client, scopes, creator
18
41
  end
19
42
 
20
- subject { Issuer.new(server, validator) }
43
+ it "has error set to :server_error if creator fails" do
44
+ expect(creator).to receive(:call).and_return(false)
45
+ subject.create client, scopes, creator
46
+
47
+ expect(subject.error).to eq(:server_error)
48
+ end
21
49
 
22
- describe :create do
23
- let(:client) { double :client, id: "some-id" }
24
- let(:scopes) { "some scope" }
50
+ context "when validator fails" do
51
+ before do
52
+ allow(validator).to receive(:valid?).and_return(false)
53
+ allow(validator).to receive(:error).and_return(:validation_error)
54
+ expect(creator).not_to receive(:create)
55
+ end
25
56
 
26
- it "creates and sets the token" do
27
- expect(creator).to receive(:call).and_return("token")
57
+ it "has error set from validator" do
28
58
  subject.create client, scopes, creator
59
+ expect(subject.error).to eq(:validation_error)
60
+ end
29
61
 
30
- expect(subject.token).to eq("token")
62
+ it "returns false" do
63
+ expect(subject.create(client, scopes, creator)).to be_falsey
31
64
  end
65
+ end
32
66
 
33
- it "creates with correct token parameters" do
67
+ context "with custom expiration" do
68
+ let(:custom_ttl_grant) { 1234 }
69
+ let(:custom_ttl_scope) { 1235 }
70
+ let(:custom_scope) { "special" }
71
+ let(:server) do
72
+ double(
73
+ :server,
74
+ custom_access_token_expires_in: lambda { |context|
75
+ # scopes is normally an object but is a string in this test
76
+ if context.scopes == custom_scope
77
+ custom_ttl_scope
78
+ elsif context.grant_type == Doorkeeper::OAuth::CLIENT_CREDENTIALS
79
+ custom_ttl_grant
80
+ end
81
+ },
82
+ )
83
+ end
84
+
85
+ before do
86
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
87
+ end
88
+
89
+ it "respects grant based rules" do
34
90
  expect(creator).to receive(:call).with(
35
91
  client,
36
92
  scopes,
37
- expires_in: 100,
93
+ expires_in: custom_ttl_grant,
38
94
  use_refresh_token: false,
39
95
  )
40
-
41
96
  subject.create client, scopes, creator
42
97
  end
43
98
 
44
- it "has error set to :server_error if creator fails" do
45
- expect(creator).to receive(:call).and_return(false)
46
- subject.create client, scopes, creator
47
-
48
- expect(subject.error).to eq(:server_error)
49
- end
50
-
51
- context "when validator fails" do
52
- before do
53
- allow(validator).to receive(:valid?).and_return(false)
54
- allow(validator).to receive(:error).and_return(:validation_error)
55
- expect(creator).not_to receive(:create)
56
- end
57
-
58
- it "has error set from validator" do
59
- subject.create client, scopes, creator
60
- expect(subject.error).to eq(:validation_error)
61
- end
62
-
63
- it "returns false" do
64
- expect(subject.create(client, scopes, creator)).to be_falsey
65
- end
66
- end
67
-
68
- context "with custom expiration" do
69
- let(:custom_ttl_grant) { 1234 }
70
- let(:custom_ttl_scope) { 1235 }
71
- let(:custom_scope) { "special" }
72
- let(:server) do
73
- double(
74
- :server,
75
- custom_access_token_expires_in: lambda { |context|
76
- # scopes is normally an object but is a string in this test
77
- if context.scopes == custom_scope
78
- custom_ttl_scope
79
- elsif context.grant_type == Doorkeeper::OAuth::CLIENT_CREDENTIALS
80
- custom_ttl_grant
81
- end
82
- },
83
- )
84
- end
85
-
86
- before do
87
- allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
88
- end
89
-
90
- it "respects grant based rules" do
91
- expect(creator).to receive(:call).with(
92
- client,
93
- scopes,
94
- expires_in: custom_ttl_grant,
95
- use_refresh_token: false,
96
- )
97
- subject.create client, scopes, creator
98
- end
99
-
100
- it "respects scope based rules" do
101
- expect(creator).to receive(:call).with(
102
- client,
103
- custom_scope,
104
- expires_in: custom_ttl_scope,
105
- use_refresh_token: false,
106
- )
107
- subject.create client, custom_scope, creator
108
- end
99
+ it "respects scope based rules" do
100
+ expect(creator).to receive(:call).with(
101
+ client,
102
+ custom_scope,
103
+ expires_in: custom_ttl_scope,
104
+ use_refresh_token: false,
105
+ )
106
+ subject.create client, custom_scope, creator
109
107
  end
110
108
  end
111
109
  end
@@ -2,58 +2,56 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- class Doorkeeper::OAuth::ClientCredentialsRequest
6
- describe Validator do
7
- let(:server) { double :server, scopes: nil }
8
- let(:application) { double scopes: nil }
9
- let(:client) { double application: application }
10
- let(:request) { double :request, client: client, scopes: nil }
5
+ describe Doorkeeper::OAuth::ClientCredentials::Validator do
6
+ let(:server) { double :server, scopes: nil }
7
+ let(:application) { double scopes: nil }
8
+ let(:client) { double application: application }
9
+ let(:request) { double :request, client: client, scopes: nil }
11
10
 
12
- subject { described_class.new(server, request) }
11
+ subject { described_class.new(server, request) }
13
12
 
14
- it "is valid with valid request" do
15
- expect(subject).to be_valid
16
- end
13
+ it "is valid with valid request" do
14
+ expect(subject).to be_valid
15
+ end
17
16
 
18
- it "is invalid when client is not present" do
19
- allow(request).to receive(:client).and_return(nil)
17
+ it "is invalid when client is not present" do
18
+ allow(request).to receive(:client).and_return(nil)
19
+ expect(subject).not_to be_valid
20
+ end
21
+
22
+ context "with scopes" do
23
+ it "is invalid when scopes are not included in the server" do
24
+ server_scopes = Doorkeeper::OAuth::Scopes.from_string "email"
25
+ allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
26
+ allow(server).to receive(:scopes).and_return(server_scopes)
27
+ allow(request).to receive(:scopes).and_return(
28
+ Doorkeeper::OAuth::Scopes.from_string("invalid"),
29
+ )
20
30
  expect(subject).not_to be_valid
21
31
  end
22
32
 
23
- context "with scopes" do
24
- it "is invalid when scopes are not included in the server" do
25
- server_scopes = Doorkeeper::OAuth::Scopes.from_string "email"
33
+ context "with application scopes" do
34
+ it "is valid when scopes are included in the application" do
35
+ application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
36
+ server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
37
+ allow(application).to receive(:scopes).and_return(application_scopes)
38
+ allow(server).to receive(:scopes).and_return(server_scopes)
39
+ allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
40
+ allow(request).to receive(:scopes).and_return(application_scopes)
41
+ expect(subject).to be_valid
42
+ end
43
+
44
+ it "is invalid when scopes are not included in the application" do
45
+ application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
46
+ server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
47
+ allow(application).to receive(:scopes).and_return(application_scopes)
26
48
  allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
27
49
  allow(server).to receive(:scopes).and_return(server_scopes)
28
50
  allow(request).to receive(:scopes).and_return(
29
- Doorkeeper::OAuth::Scopes.from_string("invalid"),
51
+ Doorkeeper::OAuth::Scopes.from_string("email"),
30
52
  )
31
53
  expect(subject).not_to be_valid
32
54
  end
33
-
34
- context "with application scopes" do
35
- it "is valid when scopes are included in the application" do
36
- application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
37
- server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
38
- allow(application).to receive(:scopes).and_return(application_scopes)
39
- allow(server).to receive(:scopes).and_return(server_scopes)
40
- allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
41
- allow(request).to receive(:scopes).and_return(application_scopes)
42
- expect(subject).to be_valid
43
- end
44
-
45
- it "is invalid when scopes are not included in the application" do
46
- application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
47
- server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
48
- allow(application).to receive(:scopes).and_return(application_scopes)
49
- allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
50
- allow(server).to receive(:scopes).and_return(server_scopes)
51
- allow(request).to receive(:scopes).and_return(
52
- Doorkeeper::OAuth::Scopes.from_string("email"),
53
- )
54
- expect(subject).not_to be_valid
55
- end
56
- end
57
55
  end
58
56
  end
59
57
  end