doorkeeper 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. checksums.yaml +5 -5
  2. data/.hound.yml +2 -1
  3. data/.rubocop.yml +37 -4
  4. data/.travis.yml +16 -21
  5. data/Appraisals +29 -7
  6. data/Dangerfile +67 -0
  7. data/Gemfile +19 -5
  8. data/NEWS.md +107 -10
  9. data/README.md +75 -470
  10. data/Rakefile +10 -8
  11. data/app/controllers/doorkeeper/application_controller.rb +3 -2
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -13
  13. data/app/controllers/doorkeeper/applications_controller.rb +21 -7
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +3 -3
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -0
  16. data/app/controllers/doorkeeper/token_info_controller.rb +4 -2
  17. data/app/controllers/doorkeeper/tokens_controller.rb +13 -11
  18. data/app/helpers/doorkeeper/dashboard_helper.rb +3 -1
  19. data/app/validators/redirect_uri_validator.rb +7 -2
  20. data/app/views/doorkeeper/applications/_form.html.erb +6 -0
  21. data/app/views/doorkeeper/applications/show.html.erb +1 -1
  22. data/app/views/layouts/doorkeeper/admin.html.erb +5 -3
  23. data/bin/console +16 -0
  24. data/config/locales/en.yml +1 -0
  25. data/doorkeeper.gemspec +28 -24
  26. data/gemfiles/rails_5_0.gemfile +9 -4
  27. data/gemfiles/rails_5_1.gemfile +9 -4
  28. data/gemfiles/rails_5_2.gemfile +10 -5
  29. data/gemfiles/rails_6_0.gemfile +17 -0
  30. data/gemfiles/rails_master.gemfile +9 -9
  31. data/lib/doorkeeper/config/option.rb +64 -0
  32. data/lib/doorkeeper/config.rb +197 -76
  33. data/lib/doorkeeper/engine.rb +3 -1
  34. data/lib/doorkeeper/errors.rb +17 -0
  35. data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
  36. data/lib/doorkeeper/grape/helpers.rb +5 -3
  37. data/lib/doorkeeper/helpers/controller.rb +5 -2
  38. data/lib/doorkeeper/models/access_grant_mixin.rb +25 -6
  39. data/lib/doorkeeper/models/access_token_mixin.rb +68 -22
  40. data/lib/doorkeeper/models/application_mixin.rb +45 -1
  41. data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
  42. data/lib/doorkeeper/models/concerns/expirable.rb +6 -2
  43. data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
  44. data/lib/doorkeeper/models/concerns/ownership.rb +3 -6
  45. data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
  46. data/lib/doorkeeper/models/concerns/revocable.rb +4 -1
  47. data/lib/doorkeeper/models/concerns/scopes.rb +7 -1
  48. data/lib/doorkeeper/models/concerns/secret_storable.rb +108 -0
  49. data/lib/doorkeeper/oauth/authorization/code.rb +4 -2
  50. data/lib/doorkeeper/oauth/authorization/context.rb +2 -0
  51. data/lib/doorkeeper/oauth/authorization/token.rb +14 -7
  52. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +3 -1
  53. data/lib/doorkeeper/oauth/authorization_code_request.rb +8 -4
  54. data/lib/doorkeeper/oauth/base_request.rb +2 -0
  55. data/lib/doorkeeper/oauth/base_response.rb +2 -0
  56. data/lib/doorkeeper/oauth/client/credentials.rb +2 -0
  57. data/lib/doorkeeper/oauth/client.rb +3 -1
  58. data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -0
  59. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +2 -0
  60. data/lib/doorkeeper/oauth/client_credentials/validation.rb +7 -4
  61. data/lib/doorkeeper/oauth/client_credentials_request.rb +3 -1
  62. data/lib/doorkeeper/oauth/code_request.rb +2 -0
  63. data/lib/doorkeeper/oauth/code_response.rb +4 -2
  64. data/lib/doorkeeper/oauth/error.rb +2 -0
  65. data/lib/doorkeeper/oauth/error_response.rb +20 -6
  66. data/lib/doorkeeper/oauth/forbidden_token_response.rb +10 -3
  67. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +25 -8
  68. data/lib/doorkeeper/oauth/helpers/unique_token.rb +15 -1
  69. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +42 -3
  70. data/lib/doorkeeper/oauth/invalid_token_response.rb +22 -0
  71. data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -2
  72. data/lib/doorkeeper/oauth/pre_authorization.rb +13 -5
  73. data/lib/doorkeeper/oauth/refresh_token_request.rb +15 -4
  74. data/lib/doorkeeper/oauth/scopes.rb +7 -3
  75. data/lib/doorkeeper/oauth/token.rb +4 -2
  76. data/lib/doorkeeper/oauth/token_introspection.rb +76 -8
  77. data/lib/doorkeeper/oauth/token_request.rb +2 -0
  78. data/lib/doorkeeper/oauth/token_response.rb +11 -9
  79. data/lib/doorkeeper/oauth.rb +5 -5
  80. data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -13
  81. data/lib/doorkeeper/orm/active_record/access_token.rb +6 -13
  82. data/lib/doorkeeper/orm/active_record/application.rb +26 -7
  83. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
  84. data/lib/doorkeeper/orm/active_record.rb +8 -6
  85. data/lib/doorkeeper/rails/helpers.rb +5 -1
  86. data/lib/doorkeeper/rails/routes/mapper.rb +2 -0
  87. data/lib/doorkeeper/rails/routes/mapping.rb +9 -7
  88. data/lib/doorkeeper/rails/routes.rb +19 -12
  89. data/lib/doorkeeper/rake/db.rake +17 -17
  90. data/lib/doorkeeper/rake.rb +1 -1
  91. data/lib/doorkeeper/request/authorization_code.rb +2 -0
  92. data/lib/doorkeeper/request/client_credentials.rb +2 -0
  93. data/lib/doorkeeper/request/code.rb +2 -0
  94. data/lib/doorkeeper/request/password.rb +2 -0
  95. data/lib/doorkeeper/request/refresh_token.rb +2 -0
  96. data/lib/doorkeeper/request/strategy.rb +2 -0
  97. data/lib/doorkeeper/request/token.rb +2 -0
  98. data/lib/doorkeeper/request.rb +3 -1
  99. data/lib/doorkeeper/secret_storing/base.rb +64 -0
  100. data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
  101. data/lib/doorkeeper/secret_storing/plain.rb +33 -0
  102. data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
  103. data/lib/doorkeeper/server.rb +2 -0
  104. data/lib/doorkeeper/stale_records_cleaner.rb +20 -0
  105. data/lib/doorkeeper/validations.rb +2 -0
  106. data/lib/doorkeeper/version.rb +4 -2
  107. data/lib/doorkeeper.rb +69 -59
  108. data/lib/generators/doorkeeper/application_owner_generator.rb +10 -9
  109. data/lib/generators/doorkeeper/confidential_applications_generator.rb +10 -9
  110. data/lib/generators/doorkeeper/install_generator.rb +11 -9
  111. data/lib/generators/doorkeeper/migration_generator.rb +9 -9
  112. data/lib/generators/doorkeeper/pkce_generator.rb +10 -9
  113. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +10 -9
  114. data/lib/generators/doorkeeper/templates/initializer.rb +138 -13
  115. data/lib/generators/doorkeeper/templates/migration.rb.erb +17 -10
  116. data/lib/generators/doorkeeper/views_generator.rb +6 -4
  117. data/spec/controllers/application_metal_controller_spec.rb +24 -10
  118. data/spec/controllers/applications_controller_spec.rb +76 -78
  119. data/spec/controllers/authorizations_controller_spec.rb +189 -142
  120. data/spec/controllers/protected_resources_controller_spec.rb +111 -67
  121. data/spec/controllers/token_info_controller_spec.rb +14 -12
  122. data/spec/controllers/tokens_controller_spec.rb +170 -112
  123. data/spec/dummy/Rakefile +3 -1
  124. data/spec/dummy/app/controllers/application_controller.rb +3 -1
  125. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +3 -1
  126. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -2
  127. data/spec/dummy/app/controllers/home_controller.rb +6 -5
  128. data/spec/dummy/app/controllers/metal_controller.rb +2 -0
  129. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +4 -2
  130. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  131. data/spec/dummy/app/models/user.rb +2 -0
  132. data/spec/dummy/config/application.rb +26 -2
  133. data/spec/dummy/config/boot.rb +2 -4
  134. data/spec/dummy/config/environment.rb +1 -1
  135. data/spec/dummy/config/environments/development.rb +2 -0
  136. data/spec/dummy/config/environments/production.rb +2 -0
  137. data/spec/dummy/config/environments/test.rb +4 -2
  138. data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
  139. data/spec/dummy/config/initializers/doorkeeper.rb +7 -3
  140. data/spec/dummy/config/initializers/secret_token.rb +3 -1
  141. data/spec/dummy/config/initializers/session_store.rb +3 -1
  142. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
  143. data/spec/dummy/config.ru +3 -1
  144. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +20 -13
  145. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +1 -1
  146. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +2 -0
  147. data/spec/dummy/db/schema.rb +1 -1
  148. data/spec/dummy/script/rails +7 -4
  149. data/spec/factories.rb +11 -9
  150. data/spec/generators/application_owner_generator_spec.rb +13 -26
  151. data/spec/generators/confidential_applications_generator_spec.rb +12 -28
  152. data/spec/generators/install_generator_spec.rb +19 -14
  153. data/spec/generators/migration_generator_spec.rb +13 -26
  154. data/spec/generators/pkce_generator_spec.rb +11 -26
  155. data/spec/generators/previous_refresh_token_generator_spec.rb +16 -29
  156. data/spec/generators/templates/routes.rb +2 -1
  157. data/spec/generators/views_generator_spec.rb +14 -12
  158. data/spec/grape/grape_integration_spec.rb +35 -33
  159. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +9 -7
  160. data/spec/lib/config_spec.rb +290 -104
  161. data/spec/lib/doorkeeper_spec.rb +8 -6
  162. data/spec/lib/models/expirable_spec.rb +22 -8
  163. data/spec/lib/models/reusable_spec.rb +40 -0
  164. data/spec/lib/models/revocable_spec.rb +8 -6
  165. data/spec/lib/models/scopes_spec.rb +27 -13
  166. data/spec/lib/models/secret_storable_spec.rb +135 -0
  167. data/spec/lib/oauth/authorization/uri_builder_spec.rb +17 -15
  168. data/spec/lib/oauth/authorization_code_request_spec.rb +43 -17
  169. data/spec/lib/oauth/base_request_spec.rb +24 -12
  170. data/spec/lib/oauth/base_response_spec.rb +3 -1
  171. data/spec/lib/oauth/client/credentials_spec.rb +26 -24
  172. data/spec/lib/oauth/client_credentials/creator_spec.rb +56 -10
  173. data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -20
  174. data/spec/lib/oauth/client_credentials/validation_spec.rb +21 -15
  175. data/spec/lib/oauth/client_credentials_integration_spec.rb +8 -6
  176. data/spec/lib/oauth/client_credentials_request_spec.rb +27 -21
  177. data/spec/lib/oauth/client_spec.rb +15 -13
  178. data/spec/lib/oauth/code_request_spec.rb +10 -8
  179. data/spec/lib/oauth/code_response_spec.rb +9 -7
  180. data/spec/lib/oauth/error_response_spec.rb +19 -11
  181. data/spec/lib/oauth/error_spec.rb +4 -2
  182. data/spec/lib/oauth/forbidden_token_response_spec.rb +7 -5
  183. data/spec/lib/oauth/helpers/scope_checker_spec.rb +68 -31
  184. data/spec/lib/oauth/helpers/unique_token_spec.rb +8 -6
  185. data/spec/lib/oauth/helpers/uri_checker_spec.rb +124 -93
  186. data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
  187. data/spec/lib/oauth/password_access_token_request_spec.rb +95 -34
  188. data/spec/lib/oauth/pre_authorization_spec.rb +80 -54
  189. data/spec/lib/oauth/refresh_token_request_spec.rb +46 -39
  190. data/spec/lib/oauth/scopes_spec.rb +63 -61
  191. data/spec/lib/oauth/token_request_spec.rb +80 -25
  192. data/spec/lib/oauth/token_response_spec.rb +40 -38
  193. data/spec/lib/oauth/token_spec.rb +64 -45
  194. data/spec/lib/request/strategy_spec.rb +3 -1
  195. data/spec/lib/secret_storing/base_spec.rb +60 -0
  196. data/spec/lib/secret_storing/bcrypt_spec.rb +49 -0
  197. data/spec/lib/secret_storing/plain_spec.rb +44 -0
  198. data/spec/lib/secret_storing/sha256_hash_spec.rb +48 -0
  199. data/spec/lib/server_spec.rb +20 -18
  200. data/spec/lib/{orm/active_record/stale_records_cleaner_spec.rb → stale_records_cleaner_spec.rb} +28 -18
  201. data/spec/models/doorkeeper/access_grant_spec.rb +80 -15
  202. data/spec/models/doorkeeper/access_token_spec.rb +212 -83
  203. data/spec/models/doorkeeper/application_spec.rb +146 -49
  204. data/spec/requests/applications/applications_request_spec.rb +100 -68
  205. data/spec/requests/applications/authorized_applications_spec.rb +20 -18
  206. data/spec/requests/endpoints/authorization_spec.rb +27 -25
  207. data/spec/requests/endpoints/token_spec.rb +38 -36
  208. data/spec/requests/flows/authorization_code_errors_spec.rb +27 -25
  209. data/spec/requests/flows/authorization_code_spec.rb +260 -158
  210. data/spec/requests/flows/client_credentials_spec.rb +54 -52
  211. data/spec/requests/flows/implicit_grant_errors_spec.rb +11 -9
  212. data/spec/requests/flows/implicit_grant_spec.rb +27 -25
  213. data/spec/requests/flows/password_spec.rb +64 -56
  214. data/spec/requests/flows/refresh_token_spec.rb +91 -32
  215. data/spec/requests/flows/revoke_token_spec.rb +49 -63
  216. data/spec/requests/flows/skip_authorization_spec.rb +23 -21
  217. data/spec/requests/protected_resources/metal_spec.rb +7 -5
  218. data/spec/requests/protected_resources/private_api_spec.rb +37 -35
  219. data/spec/routing/custom_controller_routes_spec.rb +71 -65
  220. data/spec/routing/default_routes_spec.rb +22 -20
  221. data/spec/routing/scoped_routes_spec.rb +20 -18
  222. data/spec/spec_helper.rb +15 -13
  223. data/spec/spec_helper_integration.rb +3 -1
  224. data/spec/support/dependencies/factory_bot.rb +3 -1
  225. data/spec/support/doorkeeper_rspec.rb +5 -2
  226. data/spec/support/helpers/access_token_request_helper.rb +3 -1
  227. data/spec/support/helpers/authorization_request_helper.rb +4 -2
  228. data/spec/support/helpers/config_helper.rb +2 -0
  229. data/spec/support/helpers/model_helper.rb +11 -5
  230. data/spec/support/helpers/request_spec_helper.rb +5 -3
  231. data/spec/support/helpers/url_helper.rb +20 -18
  232. data/spec/support/http_method_shim.rb +4 -9
  233. data/spec/support/orm/active_record.rb +3 -1
  234. data/spec/support/shared/controllers_shared_context.rb +68 -10
  235. data/spec/support/shared/hashing_shared_context.rb +36 -0
  236. data/spec/support/shared/models_shared_examples.rb +12 -10
  237. data/spec/validators/redirect_uri_validator_spec.rb +76 -47
  238. data/spec/version/version_spec.rb +7 -5
  239. metadata +70 -21
  240. data/gemfiles/rails_4_2.gemfile +0 -13
  241. data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -10
@@ -1,4 +1,6 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth
4
6
  describe InvalidTokenResponse do
@@ -1,4 +1,6 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth
4
6
  describe PasswordAccessTokenRequest do
@@ -16,87 +18,134 @@ module Doorkeeper::OAuth
16
18
  let(:client) { FactoryBot.create(:application) }
17
19
  let(:owner) { double :owner, id: 99 }
18
20
 
21
+ before do
22
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
23
+ end
24
+
19
25
  subject do
20
26
  PasswordAccessTokenRequest.new(server, client, owner)
21
27
  end
22
28
 
23
- it 'issues a new token for the client' do
29
+ it "issues a new token for the client" do
24
30
  expect do
25
31
  subject.authorize
26
32
  end.to change { client.reload.access_tokens.count }.by(1)
27
- expect(client.reload.access_tokens.sort_by(&:created_at).last.expires_in).to eq(1234)
33
+
34
+ expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(1234)
28
35
  end
29
36
 
30
- it 'issues a new token without a client' do
37
+ it "issues a new token without a client" do
31
38
  expect do
32
39
  subject.client = nil
33
40
  subject.authorize
34
41
  end.to change { Doorkeeper::AccessToken.count }.by(1)
35
42
  end
36
43
 
37
- it 'does not issue a new token with an invalid client' do
44
+ it "does not issue a new token with an invalid client" do
38
45
  expect do
39
46
  subject.client = nil
40
- subject.parameters = { client_id: 'bad_id' }
47
+ subject.parameters = { client_id: "bad_id" }
41
48
  subject.authorize
42
- end.to_not change { Doorkeeper::AccessToken.count }
49
+ end.not_to(change { Doorkeeper::AccessToken.count })
43
50
 
44
51
  expect(subject.error).to eq(:invalid_client)
45
52
  end
46
53
 
47
- it 'requires the owner' do
54
+ it "requires the owner" do
48
55
  subject.resource_owner = nil
49
56
  subject.validate
50
57
  expect(subject.error).to eq(:invalid_grant)
51
58
  end
52
59
 
53
- it 'optionally accepts the client' do
60
+ it "optionally accepts the client" do
54
61
  subject.client = nil
55
62
  expect(subject).to be_valid
56
63
  end
57
64
 
58
- it 'creates token even when there is already one (default)' do
65
+ it "creates token even when there is already one (default)" do
59
66
  FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
67
+
60
68
  expect do
61
69
  subject.authorize
62
70
  end.to change { Doorkeeper::AccessToken.count }.by(1)
63
71
  end
64
72
 
65
- it 'skips token creation if there is already one' do
73
+ it "skips token creation if there is already one reusable" do
66
74
  allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
67
75
  FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
76
+
68
77
  expect do
69
78
  subject.authorize
70
- end.to_not change { Doorkeeper::AccessToken.count }
79
+ end.not_to(change { Doorkeeper::AccessToken.count })
80
+ end
81
+
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)
86
+
87
+ expect do
88
+ subject.authorize
89
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
71
90
  end
72
91
 
73
92
  it "calls configured request callback methods" do
74
- expect(Doorkeeper.configuration.before_successful_strategy_response).to receive(:call).with(subject).once
75
- expect(Doorkeeper.configuration.after_successful_strategy_response).to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
93
+ expect(Doorkeeper.configuration.before_successful_strategy_response)
94
+ .to receive(:call).with(subject).once
95
+
96
+ expect(Doorkeeper.configuration.after_successful_strategy_response)
97
+ .to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
98
+
76
99
  subject.authorize
77
100
  end
78
101
 
79
- describe 'with scopes' do
102
+ describe "with scopes" do
80
103
  subject do
81
- PasswordAccessTokenRequest.new(server, client, owner, scope: 'public')
104
+ PasswordAccessTokenRequest.new(server, client, owner, scope: "public")
82
105
  end
83
106
 
84
- it 'validates the current scope' do
85
- allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('another'))
86
- subject.validate
87
- expect(subject.error).to eq(:invalid_scope)
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
88
122
  end
89
123
 
90
- it 'creates the token with scopes' do
91
- allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('public'))
92
- expect do
93
- subject.authorize
94
- end.to change { Doorkeeper::AccessToken.count }.by(1)
95
- expect(Doorkeeper::AccessToken.last.scopes).to include('public')
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
96
145
  end
97
146
  end
98
147
 
99
- describe 'with custom expiry' do
148
+ describe "with custom expiry" do
100
149
  let(:server) do
101
150
  double(
102
151
  :server,
@@ -104,26 +153,38 @@ module Doorkeeper::OAuth
104
153
  access_token_expires_in: 2.hours,
105
154
  refresh_token_enabled?: false,
106
155
  custom_access_token_expires_in: lambda { |context|
107
- context.scopes.exists?('public') ? 222 : nil
156
+ if context.scopes.exists?("public")
157
+ 222
158
+ elsif context.scopes.exists?("magic")
159
+ Float::INFINITY
160
+ end
108
161
  }
109
162
  )
110
163
  end
111
164
 
112
- it 'checks scopes' do
113
- subject = PasswordAccessTokenRequest.new(server, client, owner, scope: 'public')
114
- allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('public'))
165
+ before do
166
+ allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
167
+ end
168
+
169
+ it "checks scopes" do
170
+ subject = PasswordAccessTokenRequest.new(server, client, owner, scope: "public")
171
+ allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
172
+
115
173
  expect do
116
174
  subject.authorize
117
175
  end.to change { Doorkeeper::AccessToken.count }.by(1)
176
+
118
177
  expect(Doorkeeper::AccessToken.last.expires_in).to eq(222)
119
178
  end
120
179
 
121
- it 'falls back to the default otherwise' do
122
- subject = PasswordAccessTokenRequest.new(server, client, owner, scope: 'private')
123
- allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('private'))
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"))
183
+
124
184
  expect do
125
185
  subject.authorize
126
186
  end.to change { Doorkeeper::AccessToken.count }.by(1)
187
+
127
188
  expect(Doorkeeper::AccessToken.last.expires_in).to eq(2.hours)
128
189
  end
129
190
  end
@@ -1,29 +1,31 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  module Doorkeeper::OAuth
4
6
  describe PreAuthorization do
5
7
  let(:server) do
6
8
  server = Doorkeeper.configuration
7
9
  allow(server).to receive(:default_scopes).and_return(Scopes.new)
8
- allow(server).to receive(:scopes).and_return(Scopes.from_string('public profile'))
10
+ allow(server).to receive(:scopes).and_return(Scopes.from_string("public profile"))
9
11
  server
10
12
  end
11
13
 
12
14
  let(:application) do
13
15
  application = double :application
14
- allow(application).to receive(:scopes).and_return(Scopes.from_string(''))
16
+ allow(application).to receive(:scopes).and_return(Scopes.from_string(""))
15
17
  application
16
18
  end
17
19
 
18
20
  let(:client) do
19
- double :client, redirect_uri: 'http://tst.com/auth', application: application
21
+ double :client, redirect_uri: "http://tst.com/auth", application: application
20
22
  end
21
23
 
22
24
  let :attributes do
23
25
  {
24
- response_type: 'code',
25
- redirect_uri: 'http://tst.com/auth',
26
- state: 'save-this'
26
+ response_type: "code",
27
+ redirect_uri: "http://tst.com/auth",
28
+ state: "save-this",
27
29
  }
28
30
  end
29
31
 
@@ -31,133 +33,157 @@ module Doorkeeper::OAuth
31
33
  PreAuthorization.new(server, client, attributes)
32
34
  end
33
35
 
34
- it 'is authorizable when request is valid' do
36
+ it "is authorizable when request is valid" do
35
37
  expect(subject).to be_authorizable
36
38
  end
37
39
 
38
- it 'accepts code as response type' do
39
- subject.response_type = 'code'
40
+ it "accepts code as response type" do
41
+ subject.response_type = "code"
40
42
  expect(subject).to be_authorizable
41
43
  end
42
44
 
43
- it 'accepts token as response type' do
44
- allow(server).to receive(:grant_flows).and_return(['implicit'])
45
- subject.response_type = 'token'
45
+ it "accepts token as response type" do
46
+ allow(server).to receive(:grant_flows).and_return(["implicit"])
47
+ subject.response_type = "token"
46
48
  expect(subject).to be_authorizable
47
49
  end
48
50
 
49
- context 'when using default grant flows' do
51
+ context "when using default grant flows" do
50
52
  it 'accepts "code" as response type' do
51
- subject.response_type = 'code'
53
+ subject.response_type = "code"
52
54
  expect(subject).to be_authorizable
53
55
  end
54
56
 
55
57
  it 'accepts "token" as response type' do
56
- allow(server).to receive(:grant_flows).and_return(['implicit'])
57
- subject.response_type = 'token'
58
+ allow(server).to receive(:grant_flows).and_return(["implicit"])
59
+ subject.response_type = "token"
58
60
  expect(subject).to be_authorizable
59
61
  end
60
62
  end
61
63
 
62
- context 'when authorization code grant flow is disabled' do
64
+ context "when authorization code grant flow is disabled" do
63
65
  before do
64
- allow(server).to receive(:grant_flows).and_return(['implicit'])
66
+ allow(server).to receive(:grant_flows).and_return(["implicit"])
65
67
  end
66
68
 
67
69
  it 'does not accept "code" as response type' do
68
- subject.response_type = 'code'
70
+ subject.response_type = "code"
69
71
  expect(subject).not_to be_authorizable
70
72
  end
71
73
  end
72
74
 
73
- context 'when implicit grant flow is disabled' do
75
+ context "when implicit grant flow is disabled" do
74
76
  before do
75
- allow(server).to receive(:grant_flows).and_return(['authorization_code'])
77
+ allow(server).to receive(:grant_flows).and_return(["authorization_code"])
76
78
  end
77
79
 
78
80
  it 'does not accept "token" as response type' do
79
- subject.response_type = 'token'
81
+ subject.response_type = "token"
80
82
  expect(subject).not_to be_authorizable
81
83
  end
82
84
  end
83
85
 
84
- context 'client application does not restrict valid scopes' do
85
- it 'accepts valid scopes' do
86
- subject.scope = 'public'
86
+ context "client application does not restrict valid scopes" do
87
+ it "accepts valid scopes" do
88
+ subject.scope = "public"
89
+ expect(subject).to be_authorizable
90
+ end
91
+
92
+ it "rejects (globally) non-valid scopes" do
93
+ subject.scope = "invalid"
94
+ expect(subject).not_to be_authorizable
95
+ end
96
+
97
+ it "accepts scopes which are permitted for grant_type" do
98
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
99
+ subject.scope = "public"
87
100
  expect(subject).to be_authorizable
88
101
  end
89
102
 
90
- it 'rejects (globally) non-valid scopes' do
91
- subject.scope = 'invalid'
103
+ it "rejects scopes which are not permitted for grant_type" do
104
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
105
+ subject.scope = "public"
92
106
  expect(subject).not_to be_authorizable
93
107
  end
94
108
  end
95
109
 
96
- context 'client application restricts valid scopes' do
110
+ context "client application restricts valid scopes" do
97
111
  let(:application) do
98
112
  application = double :application
99
- allow(application).to receive(:scopes).and_return(Scopes.from_string('public nonsense'))
113
+ allow(application).to receive(:scopes).and_return(Scopes.from_string("public nonsense"))
100
114
  application
101
115
  end
102
116
 
103
- it 'accepts valid scopes' do
104
- subject.scope = 'public'
117
+ it "accepts valid scopes" do
118
+ subject.scope = "public"
105
119
  expect(subject).to be_authorizable
106
120
  end
107
121
 
108
- it 'rejects (globally) non-valid scopes' do
109
- subject.scope = 'invalid'
122
+ it "rejects (globally) non-valid scopes" do
123
+ subject.scope = "invalid"
110
124
  expect(subject).not_to be_authorizable
111
125
  end
112
126
 
113
- it 'rejects (application level) non-valid scopes' do
114
- subject.scope = 'profile'
127
+ it "rejects (application level) non-valid scopes" do
128
+ subject.scope = "profile"
115
129
  expect(subject).to_not be_authorizable
116
130
  end
131
+
132
+ it "accepts scopes which are permitted for grant_type" do
133
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
134
+ subject.scope = "public"
135
+ expect(subject).to be_authorizable
136
+ end
137
+
138
+ it "rejects scopes which are not permitted for grant_type" do
139
+ allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
140
+ subject.scope = "public"
141
+ expect(subject).not_to be_authorizable
142
+ end
117
143
  end
118
144
 
119
- it 'uses default scopes when none is required' do
120
- allow(server).to receive(:default_scopes).and_return(Scopes.from_string('default'))
145
+ it "uses default scopes when none is required" do
146
+ allow(server).to receive(:default_scopes).and_return(Scopes.from_string("default"))
121
147
  subject.scope = nil
122
- expect(subject.scope).to eq('default')
123
- expect(subject.scopes).to eq(Scopes.from_string('default'))
148
+ expect(subject.scope).to eq("default")
149
+ expect(subject.scopes).to eq(Scopes.from_string("default"))
124
150
  end
125
151
 
126
- context 'with native redirect uri' do
127
- let(:native_redirect_uri) { 'urn:ietf:wg:oauth:2.0:oob' }
152
+ context "with native redirect uri" do
153
+ let(:native_redirect_uri) { "urn:ietf:wg:oauth:2.0:oob" }
128
154
 
129
- it 'accepts redirect_uri when it matches with the client' do
155
+ it "accepts redirect_uri when it matches with the client" do
130
156
  subject.redirect_uri = native_redirect_uri
131
157
  allow(subject.client).to receive(:redirect_uri) { native_redirect_uri }
132
158
  expect(subject).to be_authorizable
133
159
  end
134
160
 
135
- it 'invalidates redirect_uri when it does\'n match with the client' do
136
- subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
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"
137
163
  expect(subject).not_to be_authorizable
138
164
  end
139
165
  end
140
166
 
141
- it 'matches the redirect uri against client\'s one' do
142
- subject.redirect_uri = 'http://nothesame.com'
167
+ it "matches the redirect uri against client's one" do
168
+ subject.redirect_uri = "http://nothesame.com"
143
169
  expect(subject).not_to be_authorizable
144
170
  end
145
171
 
146
- it 'stores the state' do
147
- expect(subject.state).to eq('save-this')
172
+ it "stores the state" do
173
+ expect(subject.state).to eq("save-this")
148
174
  end
149
175
 
150
- it 'rejects if response type is not allowed' do
151
- subject.response_type = 'whops'
176
+ it "rejects if response type is not allowed" do
177
+ subject.response_type = "whops"
152
178
  expect(subject).not_to be_authorizable
153
179
  end
154
180
 
155
- it 'requires an existing client' do
181
+ it "requires an existing client" do
156
182
  subject.client = nil
157
183
  expect(subject).not_to be_authorizable
158
184
  end
159
185
 
160
- it 'requires a redirect uri' do
186
+ it "requires a redirect uri" do
161
187
  subject.redirect_uri = nil
162
188
  expect(subject).not_to be_authorizable
163
189
  end
@@ -182,7 +208,7 @@ module Doorkeeper::OAuth
182
208
  expect(json[:response_type]).to eq subject.response_type
183
209
  expect(json[:scope]).to eq subject.scope
184
210
  expect(json[:client_name]).to eq client_name
185
- expect(json[:status]).to eq I18n.t('doorkeeper.pre_authorization.status')
211
+ expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
186
212
  end
187
213
  end
188
214
  end