doorkeeper 5.2.6 → 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.

Potentially problematic release.


This version of doorkeeper might be problematic. Click here for more details.

Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +2 -2
  3. data/CHANGELOG.md +15 -14
  4. data/Gemfile +2 -2
  5. data/app/controllers/doorkeeper/application_controller.rb +2 -2
  6. data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
  7. data/app/controllers/doorkeeper/applications_controller.rb +3 -3
  8. data/app/controllers/doorkeeper/authorizations_controller.rb +2 -2
  9. data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
  10. data/gemfiles/rails_5_0.gemfile +2 -2
  11. data/gemfiles/rails_5_1.gemfile +2 -2
  12. data/gemfiles/rails_5_2.gemfile +2 -2
  13. data/gemfiles/rails_6_0.gemfile +2 -2
  14. data/gemfiles/rails_master.gemfile +2 -2
  15. data/lib/doorkeeper.rb +2 -3
  16. data/lib/doorkeeper/config.rb +71 -39
  17. data/lib/doorkeeper/grape/helpers.rb +1 -1
  18. data/lib/doorkeeper/helpers/controller.rb +10 -8
  19. data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
  20. data/lib/doorkeeper/models/access_token_mixin.rb +55 -18
  21. data/lib/doorkeeper/models/application_mixin.rb +3 -3
  22. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  23. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  24. data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
  25. data/lib/doorkeeper/oauth/authorization/code.rb +4 -4
  26. data/lib/doorkeeper/oauth/authorization/token.rb +9 -6
  27. data/lib/doorkeeper/oauth/authorization_code_request.rb +13 -6
  28. data/lib/doorkeeper/oauth/base_request.rb +8 -4
  29. data/lib/doorkeeper/oauth/client.rb +7 -8
  30. data/lib/doorkeeper/oauth/client_credentials/creator.rb +16 -9
  31. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
  32. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +4 -4
  33. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
  34. data/lib/doorkeeper/oauth/code_response.rb +2 -2
  35. data/lib/doorkeeper/oauth/error.rb +1 -1
  36. data/lib/doorkeeper/oauth/error_response.rb +5 -5
  37. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
  38. data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
  39. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -1
  40. data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
  41. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
  42. data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -3
  43. data/lib/doorkeeper/oauth/pre_authorization.rb +7 -5
  44. data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -5
  45. data/lib/doorkeeper/oauth/token.rb +2 -2
  46. data/lib/doorkeeper/oauth/token_introspection.rb +6 -6
  47. data/lib/doorkeeper/orm/active_record.rb +3 -3
  48. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  49. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  50. data/lib/doorkeeper/orm/active_record/application.rb +3 -155
  51. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
  52. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
  53. data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
  54. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +3 -3
  55. data/lib/doorkeeper/rails/helpers.rb +4 -4
  56. data/lib/doorkeeper/rails/routes.rb +5 -7
  57. data/lib/doorkeeper/rake/db.rake +3 -3
  58. data/lib/doorkeeper/request.rb +1 -1
  59. data/lib/doorkeeper/request/authorization_code.rb +3 -3
  60. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  61. data/lib/doorkeeper/request/password.rb +2 -2
  62. data/lib/doorkeeper/request/refresh_token.rb +3 -3
  63. data/lib/doorkeeper/server.rb +1 -1
  64. data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
  65. data/lib/doorkeeper/version.rb +2 -2
  66. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  67. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  68. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  69. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  70. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
  71. data/lib/generators/doorkeeper/templates/initializer.rb +39 -8
  72. data/spec/controllers/application_metal_controller_spec.rb +1 -1
  73. data/spec/controllers/applications_controller_spec.rb +3 -2
  74. data/spec/controllers/authorizations_controller_spec.rb +18 -18
  75. data/spec/controllers/protected_resources_controller_spec.rb +25 -17
  76. data/spec/controllers/token_info_controller_spec.rb +1 -1
  77. data/spec/controllers/tokens_controller_spec.rb +1 -1
  78. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
  79. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
  80. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
  81. data/spec/generators/install_generator_spec.rb +1 -1
  82. data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
  83. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  84. data/spec/lib/config_spec.rb +61 -21
  85. data/spec/lib/doorkeeper_spec.rb +1 -1
  86. data/spec/lib/models/revocable_spec.rb +3 -3
  87. data/spec/lib/oauth/authorization_code_request_spec.rb +127 -125
  88. data/spec/lib/oauth/base_request_spec.rb +160 -158
  89. data/spec/lib/oauth/base_response_spec.rb +27 -29
  90. data/spec/lib/oauth/client/credentials_spec.rb +1 -1
  91. data/spec/lib/oauth/client_credentials/creator_spec.rb +42 -5
  92. data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
  93. data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
  94. data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
  95. data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
  96. data/spec/lib/oauth/client_spec.rb +26 -26
  97. data/spec/lib/oauth/code_request_spec.rb +34 -34
  98. data/spec/lib/oauth/code_response_spec.rb +21 -25
  99. data/spec/lib/oauth/error_response_spec.rb +42 -44
  100. data/spec/lib/oauth/error_spec.rb +12 -14
  101. data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
  102. data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
  103. data/spec/lib/oauth/invalid_request_response_spec.rb +48 -50
  104. data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
  105. data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
  106. data/spec/lib/oauth/pre_authorization_spec.rb +159 -161
  107. data/spec/lib/oauth/refresh_token_request_spec.rb +138 -139
  108. data/spec/lib/oauth/scopes_spec.rb +104 -106
  109. data/spec/lib/oauth/token_request_spec.rb +115 -111
  110. data/spec/lib/oauth/token_response_spec.rb +71 -73
  111. data/spec/lib/oauth/token_spec.rb +121 -123
  112. data/spec/models/doorkeeper/access_grant_spec.rb +3 -5
  113. data/spec/models/doorkeeper/access_token_spec.rb +7 -7
  114. data/spec/models/doorkeeper/application_spec.rb +295 -373
  115. data/spec/requests/applications/applications_request_spec.rb +1 -1
  116. data/spec/requests/endpoints/authorization_spec.rb +5 -3
  117. data/spec/requests/flows/authorization_code_spec.rb +34 -22
  118. data/spec/requests/flows/client_credentials_spec.rb +1 -1
  119. data/spec/requests/flows/password_spec.rb +32 -12
  120. data/spec/requests/flows/refresh_token_spec.rb +19 -19
  121. data/spec/requests/flows/revoke_token_spec.rb +18 -12
  122. data/spec/spec_helper.rb +1 -4
  123. data/spec/support/shared/controllers_shared_context.rb +33 -23
  124. data/spec/validators/redirect_uri_validator_spec.rb +1 -1
  125. metadata +6 -5
  126. data/spec/support/http_method_shim.rb +0 -29
@@ -2,53 +2,51 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe InvalidTokenResponse do
7
- describe "#name" do
8
- it { expect(subject.name).to eq(:invalid_token) }
9
- end
5
+ describe Doorkeeper::OAuth::InvalidTokenResponse do
6
+ describe "#name" do
7
+ it { expect(subject.name).to eq(:invalid_token) }
8
+ end
10
9
 
11
- describe "#status" do
12
- it { expect(subject.status).to eq(:unauthorized) }
13
- end
10
+ describe "#status" do
11
+ it { expect(subject.status).to eq(:unauthorized) }
12
+ end
14
13
 
15
- describe :from_access_token do
16
- let(:response) { InvalidTokenResponse.from_access_token(access_token) }
14
+ describe ".from_access_token" do
15
+ let(:response) { described_class.from_access_token(access_token) }
17
16
 
18
- context "revoked" do
19
- let(:access_token) { double(revoked?: true, expired?: true) }
17
+ context "revoked" do
18
+ let(:access_token) { double(revoked?: true, expired?: true) }
20
19
 
21
- it "sets a description" do
22
- expect(response.description).to include("revoked")
23
- end
20
+ it "sets a description" do
21
+ expect(response.description).to include("revoked")
22
+ end
24
23
 
25
- it "sets the reason" do
26
- expect(response.reason).to eq(:revoked)
27
- end
24
+ it "sets the reason" do
25
+ expect(response.reason).to eq(:revoked)
28
26
  end
27
+ end
29
28
 
30
- context "expired" do
31
- let(:access_token) { double(revoked?: false, expired?: true) }
29
+ context "expired" do
30
+ let(:access_token) { double(revoked?: false, expired?: true) }
32
31
 
33
- it "sets a description" do
34
- expect(response.description).to include("expired")
35
- end
32
+ it "sets a description" do
33
+ expect(response.description).to include("expired")
34
+ end
36
35
 
37
- it "sets the reason" do
38
- expect(response.reason).to eq(:expired)
39
- end
36
+ it "sets the reason" do
37
+ expect(response.reason).to eq(:expired)
40
38
  end
39
+ end
41
40
 
42
- context "unknown" do
43
- let(:access_token) { double(revoked?: false, expired?: false) }
41
+ context "unknown" do
42
+ let(:access_token) { double(revoked?: false, expired?: false) }
44
43
 
45
- it "sets a description" do
46
- expect(response.description).to include("invalid")
47
- end
44
+ it "sets a description" do
45
+ expect(response.description).to include("invalid")
46
+ end
48
47
 
49
- it "sets the reason" do
50
- expect(response.reason).to eq(:unknown)
51
- end
48
+ it "sets the reason" do
49
+ expect(response.reason).to eq(:unknown)
52
50
  end
53
51
  end
54
52
  end
@@ -2,191 +2,189 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe PasswordAccessTokenRequest do
7
- let(:server) do
8
- double(
9
- :server,
10
- default_scopes: Doorkeeper::OAuth::Scopes.new,
11
- access_token_expires_in: 2.hours,
12
- refresh_token_enabled?: false,
13
- custom_access_token_expires_in: lambda { |context|
14
- context.grant_type == Doorkeeper::OAuth::PASSWORD ? 1234 : nil
15
- }
16
- )
17
- end
18
- let(:client) { FactoryBot.create(:application) }
19
- let(:owner) { double :owner, id: 99 }
5
+ describe Doorkeeper::OAuth::PasswordAccessTokenRequest do
6
+ let(:server) do
7
+ double(
8
+ :server,
9
+ default_scopes: Doorkeeper::OAuth::Scopes.new,
10
+ access_token_expires_in: 2.hours,
11
+ refresh_token_enabled?: false,
12
+ custom_access_token_expires_in: lambda { |context|
13
+ context.grant_type == Doorkeeper::OAuth::PASSWORD ? 1234 : nil
14
+ },
15
+ )
16
+ end
17
+ let(:client) { FactoryBot.create(:application) }
18
+ let(:owner) { double :owner, id: 99 }
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
- PasswordAccessTokenRequest.new(server, client, owner)
27
- end
24
+ subject do
25
+ described_class.new(server, client, owner)
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 a new token without a client" do
38
- expect do
39
- subject.client = nil
40
- subject.authorize
41
- end.to change { Doorkeeper::AccessToken.count }.by(1)
42
- end
36
+ it "issues a new token without a client" do
37
+ expect do
38
+ subject.client = nil
39
+ subject.authorize
40
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
41
+ end
43
42
 
44
- it "does not issue a new token with an invalid client" do
45
- expect do
46
- subject.client = nil
47
- subject.parameters = { client_id: "bad_id" }
48
- subject.authorize
49
- end.not_to(change { Doorkeeper::AccessToken.count })
43
+ it "does not issue a new token with an invalid client" do
44
+ expect do
45
+ subject.client = nil
46
+ subject.parameters = { client_id: "bad_id" }
47
+ subject.authorize
48
+ end.not_to(change { Doorkeeper::AccessToken.count })
50
49
 
51
- expect(subject.error).to eq(:invalid_client)
52
- end
50
+ expect(subject.error).to eq(:invalid_client)
51
+ end
53
52
 
54
- it "requires the owner" do
55
- subject.resource_owner = nil
56
- subject.validate
57
- expect(subject.error).to eq(:invalid_grant)
58
- end
53
+ it "requires the owner" do
54
+ subject.resource_owner = nil
55
+ subject.validate
56
+ expect(subject.error).to eq(:invalid_grant)
57
+ end
59
58
 
60
- it "optionally accepts the client" do
61
- subject.client = nil
62
- expect(subject).to be_valid
63
- end
59
+ it "optionally accepts the client" do
60
+ subject.client = nil
61
+ expect(subject).to be_valid
62
+ end
64
63
 
65
- it "creates token even when there is already one (default)" do
66
- FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
64
+ it "creates token even when there is already one (default)" do
65
+ FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
67
66
 
68
- expect do
69
- subject.authorize
70
- end.to change { Doorkeeper::AccessToken.count }.by(1)
71
- end
67
+ expect do
68
+ subject.authorize
69
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
70
+ end
72
71
 
73
- it "skips token creation if there is already one reusable" do
74
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
75
- FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
72
+ it "skips token creation if there is already one reusable" do
73
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
74
+ FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
76
75
 
77
- expect do
78
- subject.authorize
79
- end.not_to(change { Doorkeeper::AccessToken.count })
80
- end
76
+ expect do
77
+ subject.authorize
78
+ end.not_to(change { Doorkeeper::AccessToken.count })
79
+ end
81
80
 
82
- it "creates token when there is already one but non reusable" do
83
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
84
- FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
85
- allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
81
+ it "creates token when there is already one but non reusable" do
82
+ allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
83
+ FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
84
+ allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
86
85
 
87
- expect do
88
- subject.authorize
89
- end.to change { Doorkeeper::AccessToken.count }.by(1)
90
- end
86
+ expect do
87
+ subject.authorize
88
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
89
+ end
91
90
 
92
- it "calls configured request callback methods" do
93
- expect(Doorkeeper.configuration.before_successful_strategy_response)
94
- .to receive(:call).with(subject).once
91
+ it "calls configured request callback methods" do
92
+ expect(Doorkeeper.configuration.before_successful_strategy_response)
93
+ .to receive(:call).with(subject).once
95
94
 
96
- expect(Doorkeeper.configuration.after_successful_strategy_response)
97
- .to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
95
+ expect(Doorkeeper.configuration.after_successful_strategy_response)
96
+ .to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
98
97
 
99
- subject.authorize
98
+ subject.authorize
99
+ end
100
+
101
+ describe "with scopes" do
102
+ subject do
103
+ described_class.new(server, client, owner, scope: "public")
100
104
  end
101
105
 
102
- describe "with scopes" do
103
- subject do
104
- PasswordAccessTokenRequest.new(server, client, owner, scope: "public")
106
+ context "when scopes_by_grant_type is not configured for grant_type" do
107
+ it "returns error when scopes are invalid" do
108
+ allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("another"))
109
+ subject.validate
110
+ expect(subject.error).to eq(:invalid_scope)
105
111
  end
106
112
 
107
- context "when scopes_by_grant_type is not configured for grant_type" do
108
- it "returns error when scopes are invalid" do
109
- allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("another"))
110
- subject.validate
111
- expect(subject.error).to eq(:invalid_scope)
112
- end
113
-
114
- it "creates the token with scopes if scopes are valid" do
115
- allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
116
- expect do
117
- subject.authorize
118
- end.to change { Doorkeeper::AccessToken.count }.by(1)
119
-
120
- expect(Doorkeeper::AccessToken.last.scopes).to include("public")
121
- end
122
- end
113
+ it "creates the token with scopes if scopes are valid" do
114
+ allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
115
+ expect do
116
+ subject.authorize
117
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
123
118
 
124
- context "when scopes_by_grant_type is configured for grant_type" do
125
- it "returns error when scopes are valid but not permitted for grant_type" do
126
- allow(server)
127
- .to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
128
- allow(Doorkeeper.configuration)
129
- .to receive(:scopes_by_grant_type).and_return(password: "another")
130
- subject.validate
131
- expect(subject.error).to eq(:invalid_scope)
132
- end
133
-
134
- it "creates the token with scopes if scopes are valid and permitted for grant_type" do
135
- allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
136
- allow(Doorkeeper.configuration)
137
- .to receive(:scopes_by_grant_type).and_return(password: [:public])
138
-
139
- expect do
140
- subject.authorize
141
- end.to change { Doorkeeper::AccessToken.count }.by(1)
142
-
143
- expect(Doorkeeper::AccessToken.last.scopes).to include("public")
144
- end
119
+ expect(Doorkeeper::AccessToken.last.scopes).to include("public")
145
120
  end
146
121
  end
147
122
 
148
- describe "with custom expiry" do
149
- let(:server) do
150
- double(
151
- :server,
152
- default_scopes: Doorkeeper::OAuth::Scopes.new,
153
- access_token_expires_in: 2.hours,
154
- refresh_token_enabled?: false,
155
- custom_access_token_expires_in: lambda { |context|
156
- if context.scopes.exists?("public")
157
- 222
158
- elsif context.scopes.exists?("magic")
159
- Float::INFINITY
160
- end
161
- }
162
- )
163
- end
164
-
165
- before do
166
- allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
123
+ context "when scopes_by_grant_type is configured for grant_type" do
124
+ it "returns error when scopes are valid but not permitted for grant_type" do
125
+ allow(server)
126
+ .to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
127
+ allow(Doorkeeper.configuration)
128
+ .to receive(:scopes_by_grant_type).and_return(password: "another")
129
+ subject.validate
130
+ expect(subject.error).to eq(:invalid_scope)
167
131
  end
168
132
 
169
- it "checks scopes" do
170
- subject = PasswordAccessTokenRequest.new(server, client, owner, scope: "public")
133
+ it "creates the token with scopes if scopes are valid and permitted for grant_type" do
171
134
  allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
135
+ allow(Doorkeeper.configuration)
136
+ .to receive(:scopes_by_grant_type).and_return(password: [:public])
172
137
 
173
138
  expect do
174
139
  subject.authorize
175
140
  end.to change { Doorkeeper::AccessToken.count }.by(1)
176
141
 
177
- expect(Doorkeeper::AccessToken.last.expires_in).to eq(222)
142
+ expect(Doorkeeper::AccessToken.last.scopes).to include("public")
178
143
  end
144
+ end
145
+ end
179
146
 
180
- it "falls back to the default otherwise" do
181
- subject = PasswordAccessTokenRequest.new(server, client, owner, scope: "private")
182
- allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("private"))
147
+ describe "with custom expiry" do
148
+ let(:server) do
149
+ double(
150
+ :server,
151
+ default_scopes: Doorkeeper::OAuth::Scopes.new,
152
+ access_token_expires_in: 2.hours,
153
+ refresh_token_enabled?: false,
154
+ custom_access_token_expires_in: lambda { |context|
155
+ if context.scopes.exists?("public")
156
+ 222
157
+ elsif context.scopes.exists?("magic")
158
+ Float::INFINITY
159
+ end
160
+ },
161
+ )
162
+ end
183
163
 
184
- expect do
185
- subject.authorize
186
- end.to change { Doorkeeper::AccessToken.count }.by(1)
164
+ before do
165
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
166
+ end
187
167
 
188
- expect(Doorkeeper::AccessToken.last.expires_in).to eq(2.hours)
189
- end
168
+ it "checks scopes" do
169
+ subject = described_class.new(server, client, owner, scope: "public")
170
+ allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
171
+
172
+ expect do
173
+ subject.authorize
174
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
175
+
176
+ expect(Doorkeeper::AccessToken.last.expires_in).to eq(222)
177
+ end
178
+
179
+ it "falls back to the default otherwise" do
180
+ subject = described_class.new(server, client, owner, scope: "private")
181
+ allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("private"))
182
+
183
+ expect do
184
+ subject.authorize
185
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
186
+
187
+ expect(Doorkeeper::AccessToken.last.expires_in).to eq(2.hours)
190
188
  end
191
189
  end
192
190
  end
@@ -2,223 +2,221 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
- module Doorkeeper::OAuth
6
- describe PreAuthorization do
7
- let(:server) do
8
- server = Doorkeeper.configuration
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
- server
12
- end
5
+ describe Doorkeeper::OAuth::PreAuthorization do
6
+ let(:server) do
7
+ server = Doorkeeper.configuration
8
+ allow(server).to receive(:default_scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("default"))
9
+ allow(server).to receive(:optional_scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public profile"))
10
+ server
11
+ end
13
12
 
14
- let(:application) { FactoryBot.create(:application, redirect_uri: "https://app.com/callback") }
15
- let(:client) { Client.find(application.uid) }
13
+ let(:application) { FactoryBot.create(:application, redirect_uri: "https://app.com/callback") }
14
+ let(:client) { Doorkeeper::OAuth::Client.find(application.uid) }
16
15
 
17
- let :attributes do
18
- {
19
- client_id: client.uid,
20
- response_type: "code",
21
- redirect_uri: "https://app.com/callback",
22
- state: "save-this",
23
- }
24
- end
16
+ let :attributes do
17
+ {
18
+ client_id: client.uid,
19
+ response_type: "code",
20
+ redirect_uri: "https://app.com/callback",
21
+ state: "save-this",
22
+ }
23
+ end
25
24
 
26
- subject do
27
- PreAuthorization.new(server, attributes)
28
- end
25
+ subject do
26
+ described_class.new(server, attributes)
27
+ end
29
28
 
30
- it "is authorizable when request is valid" do
31
- expect(subject).to be_authorizable
32
- end
29
+ it "is authorizable when request is valid" do
30
+ expect(subject).to be_authorizable
31
+ end
32
+
33
+ it "accepts code as response type" do
34
+ attributes[:response_type] = "code"
35
+ expect(subject).to be_authorizable
36
+ end
37
+
38
+ it "accepts token as response type" do
39
+ allow(server).to receive(:grant_flows).and_return(["implicit"])
40
+ attributes[:response_type] = "token"
41
+ expect(subject).to be_authorizable
42
+ end
33
43
 
34
- it "accepts code as response type" do
44
+ context "when using default grant flows" do
45
+ it 'accepts "code" as response type' do
35
46
  attributes[:response_type] = "code"
36
47
  expect(subject).to be_authorizable
37
48
  end
38
49
 
39
- it "accepts token as response type" do
50
+ it 'accepts "token" as response type' do
40
51
  allow(server).to receive(:grant_flows).and_return(["implicit"])
41
52
  attributes[:response_type] = "token"
42
53
  expect(subject).to be_authorizable
43
54
  end
55
+ end
44
56
 
45
- context "when using default grant flows" do
46
- it 'accepts "code" as response type' do
47
- attributes[:response_type] = "code"
48
- expect(subject).to be_authorizable
49
- end
57
+ context "when authorization code grant flow is disabled" do
58
+ before do
59
+ allow(server).to receive(:grant_flows).and_return(["implicit"])
60
+ end
50
61
 
51
- it 'accepts "token" as response type' do
52
- allow(server).to receive(:grant_flows).and_return(["implicit"])
53
- attributes[:response_type] = "token"
54
- expect(subject).to be_authorizable
55
- end
62
+ it 'does not accept "code" as response type' do
63
+ attributes[:response_type] = "code"
64
+ expect(subject).not_to be_authorizable
56
65
  end
66
+ end
57
67
 
58
- context "when authorization code grant flow is disabled" do
59
- before do
60
- allow(server).to receive(:grant_flows).and_return(["implicit"])
61
- end
68
+ context "when implicit grant flow is disabled" do
69
+ before do
70
+ allow(server).to receive(:grant_flows).and_return(["authorization_code"])
71
+ end
62
72
 
63
- it 'does not accept "code" as response type' do
64
- attributes[:response_type] = "code"
65
- expect(subject).not_to be_authorizable
66
- end
73
+ it 'does not accept "token" as response type' do
74
+ attributes[:response_type] = "token"
75
+ expect(subject).not_to be_authorizable
67
76
  end
77
+ end
68
78
 
69
- context "when implicit grant flow is disabled" do
70
- before do
71
- allow(server).to receive(:grant_flows).and_return(["authorization_code"])
72
- end
79
+ context "client application does not restrict valid scopes" do
80
+ it "accepts valid scopes" do
81
+ attributes[:scope] = "public"
82
+ expect(subject).to be_authorizable
83
+ end
73
84
 
74
- it 'does not accept "token" as response type' do
75
- attributes[:response_type] = "token"
76
- expect(subject).not_to be_authorizable
77
- end
85
+ it "rejects (globally) non-valid scopes" do
86
+ attributes[:scope] = "invalid"
87
+ expect(subject).not_to be_authorizable
78
88
  end
79
89
 
80
- context "client application does not restrict valid scopes" do
81
- it "accepts valid scopes" do
82
- attributes[:scope] = "public"
83
- expect(subject).to be_authorizable
84
- end
90
+ it "accepts scopes which are permitted for grant_type" do
91
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
92
+ attributes[:scope] = "public"
93
+ expect(subject).to be_authorizable
94
+ end
85
95
 
86
- it "rejects (globally) non-valid scopes" do
87
- attributes[:scope] = "invalid"
88
- expect(subject).not_to be_authorizable
89
- end
96
+ it "rejects scopes which are not permitted for grant_type" do
97
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
98
+ attributes[:scope] = "public"
99
+ expect(subject).not_to be_authorizable
100
+ end
101
+ end
90
102
 
91
- it "accepts scopes which are permitted for grant_type" do
92
- allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
93
- attributes[:scope] = "public"
94
- expect(subject).to be_authorizable
95
- end
103
+ context "client application restricts valid scopes" do
104
+ let(:application) do
105
+ FactoryBot.create(:application, scopes: Doorkeeper::OAuth::Scopes.from_string("public nonsense"))
106
+ end
96
107
 
97
- it "rejects scopes which are not permitted for grant_type" do
98
- allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
99
- attributes[:scope] = "public"
100
- expect(subject).not_to be_authorizable
101
- end
108
+ it "accepts valid scopes" do
109
+ attributes[:scope] = "public"
110
+ expect(subject).to be_authorizable
102
111
  end
103
112
 
104
- context "client application restricts valid scopes" do
105
- let(:application) do
106
- FactoryBot.create(:application, scopes: Scopes.from_string("public nonsense"))
107
- end
113
+ it "rejects (globally) non-valid scopes" do
114
+ attributes[:scope] = "invalid"
115
+ expect(subject).not_to be_authorizable
116
+ end
108
117
 
109
- it "accepts valid scopes" do
110
- attributes[:scope] = "public"
111
- expect(subject).to be_authorizable
112
- end
118
+ it "rejects (application level) non-valid scopes" do
119
+ attributes[:scope] = "profile"
120
+ expect(subject).to_not be_authorizable
121
+ end
113
122
 
114
- it "rejects (globally) non-valid scopes" do
115
- attributes[:scope] = "invalid"
116
- expect(subject).not_to be_authorizable
117
- end
123
+ it "accepts scopes which are permitted for grant_type" do
124
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
125
+ attributes[:scope] = "public"
126
+ expect(subject).to be_authorizable
127
+ end
118
128
 
119
- it "rejects (application level) non-valid scopes" do
120
- attributes[:scope] = "profile"
121
- expect(subject).to_not be_authorizable
122
- end
129
+ it "rejects scopes which are not permitted for grant_type" do
130
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
131
+ attributes[:scope] = "public"
132
+ expect(subject).not_to be_authorizable
133
+ end
134
+ end
135
+
136
+ context "when scope is not provided to pre_authorization" do
137
+ before { attributes[:scope] = nil }
123
138
 
124
- it "accepts scopes which are permitted for grant_type" do
125
- allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
126
- attributes[:scope] = "public"
139
+ context "when default scopes is provided" do
140
+ it "uses default scopes" do
141
+ allow(server).to receive(:default_scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("default_scope"))
127
142
  expect(subject).to be_authorizable
143
+ expect(subject.scope).to eq("default_scope")
144
+ expect(subject.scopes).to eq(Doorkeeper::OAuth::Scopes.from_string("default_scope"))
128
145
  end
146
+ end
129
147
 
130
- it "rejects scopes which are not permitted for grant_type" do
131
- allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
132
- attributes[:scope] = "public"
148
+ context "when default scopes is none" do
149
+ it "not be authorizable when none default scope" do
150
+ allow(server).to receive(:default_scopes).and_return(Doorkeeper::OAuth::Scopes.new)
133
151
  expect(subject).not_to be_authorizable
134
152
  end
135
153
  end
154
+ end
136
155
 
137
- context "when scope is not provided to pre_authorization" do
138
- before { attributes[:scope] = nil }
156
+ it "matches the redirect uri against client's one" do
157
+ attributes[:redirect_uri] = "http://nothesame.com"
158
+ expect(subject).not_to be_authorizable
159
+ end
139
160
 
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
147
- end
161
+ it "stores the state" do
162
+ expect(subject.state).to eq("save-this")
163
+ end
148
164
 
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
154
- end
155
- end
165
+ it "rejects if response type is not allowed" do
166
+ attributes[:response_type] = "whops"
167
+ expect(subject).not_to be_authorizable
168
+ end
156
169
 
157
- it "matches the redirect uri against client's one" do
158
- attributes[:redirect_uri] = "http://nothesame.com"
159
- expect(subject).not_to be_authorizable
160
- end
170
+ it "requires an existing client" do
171
+ attributes[:client_id] = nil
172
+ expect(subject).not_to be_authorizable
173
+ end
161
174
 
162
- it "stores the state" do
163
- expect(subject.state).to eq("save-this")
164
- end
175
+ it "requires a redirect uri" do
176
+ attributes[:redirect_uri] = nil
177
+ expect(subject).not_to be_authorizable
178
+ end
165
179
 
166
- it "rejects if response type is not allowed" do
167
- attributes[:response_type] = "whops"
168
- expect(subject).not_to be_authorizable
169
- end
180
+ describe "as_json" do
181
+ before { subject.authorizable? }
170
182
 
171
- it "requires an existing client" do
172
- attributes[:client_id] = nil
173
- expect(subject).not_to be_authorizable
174
- end
183
+ it { is_expected.to respond_to :as_json }
175
184
 
176
- it "requires a redirect uri" do
177
- attributes[:redirect_uri] = nil
178
- expect(subject).not_to be_authorizable
185
+ shared_examples "returns the pre authorization" do
186
+ it "returns the pre authorization" do
187
+ expect(json[:client_id]).to eq client.uid
188
+ expect(json[:redirect_uri]).to eq subject.redirect_uri
189
+ expect(json[:state]).to eq subject.state
190
+ expect(json[:response_type]).to eq subject.response_type
191
+ expect(json[:scope]).to eq subject.scope
192
+ expect(json[:client_name]).to eq client.name
193
+ expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
194
+ end
179
195
  end
180
196
 
181
- describe "as_json" do
182
- before { subject.authorizable? }
183
-
184
- it { is_expected.to respond_to :as_json }
197
+ context "when attributes param is not passed" do
198
+ let(:json) { subject.as_json }
185
199
 
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
196
- end
200
+ include_examples "returns the pre authorization"
201
+ end
197
202
 
198
- context "when attributes param is not passed" do
199
- let(:json) { subject.as_json }
203
+ context "when attributes param is passed" do
204
+ context "when attributes is a hash" do
205
+ let(:custom_attributes) { { custom_id: "1234", custom_name: "a pretty good name" } }
206
+ let(:json) { subject.as_json(custom_attributes) }
200
207
 
201
208
  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
209
 
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
210
+ it "merges the attributes in params" do
211
+ expect(json[:custom_id]).to eq custom_attributes[:custom_id]
212
+ expect(json[:custom_name]).to eq custom_attributes[:custom_name]
215
213
  end
214
+ end
216
215
 
217
- context "when attributes is not a hash" do
218
- let(:json) { subject.as_json(nil) }
216
+ context "when attributes is not a hash" do
217
+ let(:json) { subject.as_json(nil) }
219
218
 
220
- include_examples "returns the pre authorization"
221
- end
219
+ include_examples "returns the pre authorization"
222
220
  end
223
221
  end
224
222
  end