doorkeeper 5.2.2 → 5.5.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +198 -3
  3. data/README.md +28 -20
  4. data/app/controllers/doorkeeper/application_controller.rb +3 -2
  5. data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
  6. data/app/controllers/doorkeeper/applications_controller.rb +7 -8
  7. data/app/controllers/doorkeeper/authorizations_controller.rb +48 -18
  8. data/app/controllers/doorkeeper/authorized_applications_controller.rb +6 -6
  9. data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
  10. data/app/controllers/doorkeeper/tokens_controller.rb +70 -25
  11. data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
  12. data/app/views/doorkeeper/applications/_form.html.erb +1 -1
  13. data/app/views/doorkeeper/applications/show.html.erb +35 -14
  14. data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
  15. data/app/views/doorkeeper/authorizations/new.html.erb +2 -0
  16. data/config/locales/en.yml +9 -2
  17. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  18. data/lib/doorkeeper/config/option.rb +26 -14
  19. data/lib/doorkeeper/config/validations.rb +53 -0
  20. data/lib/doorkeeper/config.rb +214 -122
  21. data/lib/doorkeeper/engine.rb +1 -1
  22. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  23. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  24. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  25. data/lib/doorkeeper/grant_flow.rb +45 -0
  26. data/lib/doorkeeper/grape/helpers.rb +2 -2
  27. data/lib/doorkeeper/helpers/controller.rb +18 -12
  28. data/lib/doorkeeper/models/access_grant_mixin.rb +23 -19
  29. data/lib/doorkeeper/models/access_token_mixin.rb +157 -55
  30. data/lib/doorkeeper/models/application_mixin.rb +8 -7
  31. data/lib/doorkeeper/models/concerns/expirable.rb +1 -1
  32. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  33. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  34. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  35. data/lib/doorkeeper/models/concerns/revocable.rb +1 -28
  36. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  37. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  38. data/lib/doorkeeper/oauth/authorization/code.rb +22 -9
  39. data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
  40. data/lib/doorkeeper/oauth/authorization/token.rb +23 -18
  41. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  42. data/lib/doorkeeper/oauth/authorization_code_request.rb +30 -20
  43. data/lib/doorkeeper/oauth/base_request.rb +19 -23
  44. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  45. data/lib/doorkeeper/oauth/client.rb +8 -9
  46. data/lib/doorkeeper/oauth/client_credentials/creator.rb +38 -12
  47. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +10 -8
  48. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +7 -5
  49. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  50. data/lib/doorkeeper/oauth/code_request.rb +4 -4
  51. data/lib/doorkeeper/oauth/code_response.rb +24 -14
  52. data/lib/doorkeeper/oauth/error.rb +1 -1
  53. data/lib/doorkeeper/oauth/error_response.rb +10 -11
  54. data/lib/doorkeeper/oauth/forbidden_token_response.rb +2 -1
  55. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +8 -12
  56. data/lib/doorkeeper/oauth/helpers/unique_token.rb +10 -7
  57. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -19
  58. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  59. data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
  60. data/lib/doorkeeper/oauth/invalid_token_response.rb +7 -4
  61. data/lib/doorkeeper/oauth/password_access_token_request.rb +28 -10
  62. data/lib/doorkeeper/oauth/pre_authorization.rb +73 -37
  63. data/lib/doorkeeper/oauth/refresh_token_request.rb +35 -26
  64. data/lib/doorkeeper/oauth/token.rb +6 -7
  65. data/lib/doorkeeper/oauth/token_introspection.rb +12 -16
  66. data/lib/doorkeeper/oauth/token_request.rb +3 -3
  67. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  68. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  69. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  70. data/lib/doorkeeper/orm/active_record/application.rb +5 -95
  71. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +69 -0
  72. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +60 -0
  73. data/lib/doorkeeper/orm/active_record/mixins/application.rb +199 -0
  74. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +8 -3
  75. data/lib/doorkeeper/orm/active_record.rb +5 -7
  76. data/lib/doorkeeper/rails/helpers.rb +4 -4
  77. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  78. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  79. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  80. data/lib/doorkeeper/rails/routes.rb +17 -25
  81. data/lib/doorkeeper/rake/db.rake +6 -6
  82. data/lib/doorkeeper/rake/setup.rake +5 -0
  83. data/lib/doorkeeper/request/authorization_code.rb +3 -3
  84. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  85. data/lib/doorkeeper/request/password.rb +3 -2
  86. data/lib/doorkeeper/request/refresh_token.rb +5 -4
  87. data/lib/doorkeeper/request/strategy.rb +2 -2
  88. data/lib/doorkeeper/request.rb +49 -12
  89. data/lib/doorkeeper/server.rb +5 -5
  90. data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
  91. data/lib/doorkeeper/version.rb +2 -6
  92. data/lib/doorkeeper.rb +112 -81
  93. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  94. data/lib/generators/doorkeeper/confidential_applications_generator.rb +2 -2
  95. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  96. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  97. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  98. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
  99. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
  100. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  101. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  102. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  103. data/lib/generators/doorkeeper/templates/initializer.rb +99 -14
  104. data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
  105. metadata +37 -306
  106. data/Appraisals +0 -40
  107. data/CODE_OF_CONDUCT.md +0 -46
  108. data/CONTRIBUTING.md +0 -49
  109. data/Dangerfile +0 -67
  110. data/Dockerfile +0 -29
  111. data/Gemfile +0 -25
  112. data/NEWS.md +0 -1
  113. data/RELEASING.md +0 -11
  114. data/Rakefile +0 -28
  115. data/SECURITY.md +0 -15
  116. data/UPGRADE.md +0 -2
  117. data/bin/console +0 -16
  118. data/doorkeeper.gemspec +0 -42
  119. data/gemfiles/rails_5_0.gemfile +0 -18
  120. data/gemfiles/rails_5_1.gemfile +0 -18
  121. data/gemfiles/rails_5_2.gemfile +0 -18
  122. data/gemfiles/rails_6_0.gemfile +0 -18
  123. data/gemfiles/rails_master.gemfile +0 -18
  124. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  125. data/spec/controllers/applications_controller_spec.rb +0 -273
  126. data/spec/controllers/authorizations_controller_spec.rb +0 -608
  127. data/spec/controllers/protected_resources_controller_spec.rb +0 -353
  128. data/spec/controllers/token_info_controller_spec.rb +0 -50
  129. data/spec/controllers/tokens_controller_spec.rb +0 -498
  130. data/spec/dummy/Rakefile +0 -9
  131. data/spec/dummy/app/assets/config/manifest.js +0 -2
  132. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  133. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  134. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  135. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  136. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  137. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  138. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  139. data/spec/dummy/app/models/user.rb +0 -7
  140. data/spec/dummy/app/views/home/index.html.erb +0 -0
  141. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  142. data/spec/dummy/config/application.rb +0 -49
  143. data/spec/dummy/config/boot.rb +0 -7
  144. data/spec/dummy/config/database.yml +0 -15
  145. data/spec/dummy/config/environment.rb +0 -5
  146. data/spec/dummy/config/environments/development.rb +0 -31
  147. data/spec/dummy/config/environments/production.rb +0 -64
  148. data/spec/dummy/config/environments/test.rb +0 -45
  149. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  150. data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
  151. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  152. data/spec/dummy/config/initializers/session_store.rb +0 -10
  153. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  154. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  155. data/spec/dummy/config/routes.rb +0 -13
  156. data/spec/dummy/config.ru +0 -6
  157. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  158. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  159. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  160. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  161. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  162. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  163. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  164. data/spec/dummy/db/schema.rb +0 -68
  165. data/spec/dummy/public/404.html +0 -26
  166. data/spec/dummy/public/422.html +0 -26
  167. data/spec/dummy/public/500.html +0 -26
  168. data/spec/dummy/public/favicon.ico +0 -0
  169. data/spec/dummy/script/rails +0 -9
  170. data/spec/factories.rb +0 -30
  171. data/spec/generators/application_owner_generator_spec.rb +0 -28
  172. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  173. data/spec/generators/install_generator_spec.rb +0 -36
  174. data/spec/generators/migration_generator_spec.rb +0 -28
  175. data/spec/generators/pkce_generator_spec.rb +0 -28
  176. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  177. data/spec/generators/templates/routes.rb +0 -4
  178. data/spec/generators/views_generator_spec.rb +0 -29
  179. data/spec/grape/grape_integration_spec.rb +0 -137
  180. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  181. data/spec/lib/config_spec.rb +0 -739
  182. data/spec/lib/doorkeeper_spec.rb +0 -27
  183. data/spec/lib/models/expirable_spec.rb +0 -61
  184. data/spec/lib/models/reusable_spec.rb +0 -40
  185. data/spec/lib/models/revocable_spec.rb +0 -59
  186. data/spec/lib/models/scopes_spec.rb +0 -53
  187. data/spec/lib/models/secret_storable_spec.rb +0 -135
  188. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  189. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -168
  190. data/spec/lib/oauth/base_request_spec.rb +0 -222
  191. data/spec/lib/oauth/base_response_spec.rb +0 -47
  192. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  193. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -97
  194. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  195. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  196. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -29
  197. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -109
  198. data/spec/lib/oauth/client_spec.rb +0 -38
  199. data/spec/lib/oauth/code_request_spec.rb +0 -46
  200. data/spec/lib/oauth/code_response_spec.rb +0 -36
  201. data/spec/lib/oauth/error_response_spec.rb +0 -66
  202. data/spec/lib/oauth/error_spec.rb +0 -23
  203. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -22
  204. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -98
  205. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  206. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  207. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -75
  208. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -55
  209. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -192
  210. data/spec/lib/oauth/pre_authorization_spec.rb +0 -225
  211. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -178
  212. data/spec/lib/oauth/scopes_spec.rb +0 -148
  213. data/spec/lib/oauth/token_request_spec.rb +0 -153
  214. data/spec/lib/oauth/token_response_spec.rb +0 -86
  215. data/spec/lib/oauth/token_spec.rb +0 -158
  216. data/spec/lib/request/strategy_spec.rb +0 -54
  217. data/spec/lib/secret_storing/base_spec.rb +0 -60
  218. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  219. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  220. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  221. data/spec/lib/server_spec.rb +0 -49
  222. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  223. data/spec/models/doorkeeper/access_grant_spec.rb +0 -163
  224. data/spec/models/doorkeeper/access_token_spec.rb +0 -622
  225. data/spec/models/doorkeeper/application_spec.rb +0 -377
  226. data/spec/requests/applications/applications_request_spec.rb +0 -259
  227. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  228. data/spec/requests/endpoints/authorization_spec.rb +0 -89
  229. data/spec/requests/endpoints/token_spec.rb +0 -75
  230. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
  231. data/spec/requests/flows/authorization_code_spec.rb +0 -513
  232. data/spec/requests/flows/client_credentials_spec.rb +0 -166
  233. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  234. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  235. data/spec/requests/flows/password_spec.rb +0 -296
  236. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  237. data/spec/requests/flows/revoke_token_spec.rb +0 -151
  238. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  239. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  240. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  241. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  242. data/spec/routing/default_routes_spec.rb +0 -41
  243. data/spec/routing/scoped_routes_spec.rb +0 -47
  244. data/spec/spec_helper.rb +0 -57
  245. data/spec/spec_helper_integration.rb +0 -4
  246. data/spec/support/dependencies/factory_bot.rb +0 -4
  247. data/spec/support/doorkeeper_rspec.rb +0 -22
  248. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  249. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  250. data/spec/support/helpers/config_helper.rb +0 -11
  251. data/spec/support/helpers/model_helper.rb +0 -78
  252. data/spec/support/helpers/request_spec_helper.rb +0 -110
  253. data/spec/support/helpers/url_helper.rb +0 -62
  254. data/spec/support/http_method_shim.rb +0 -29
  255. data/spec/support/orm/active_record.rb +0 -5
  256. data/spec/support/shared/controllers_shared_context.rb +0 -123
  257. data/spec/support/shared/hashing_shared_context.rb +0 -36
  258. data/spec/support/shared/models_shared_examples.rb +0 -54
  259. data/spec/validators/redirect_uri_validator_spec.rb +0 -183
  260. data/spec/version/version_spec.rb +0 -17
@@ -1,225 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
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
13
-
14
- let(:application) { FactoryBot.create(:application, redirect_uri: "https://app.com/callback") }
15
- let(:client) { Client.find(application.uid) }
16
-
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
25
-
26
- subject do
27
- PreAuthorization.new(server, attributes)
28
- end
29
-
30
- it "is authorizable when request is valid" do
31
- expect(subject).to be_authorizable
32
- end
33
-
34
- it "accepts code as response type" do
35
- attributes[:response_type] = "code"
36
- expect(subject).to be_authorizable
37
- end
38
-
39
- it "accepts token as response type" do
40
- allow(server).to receive(:grant_flows).and_return(["implicit"])
41
- attributes[:response_type] = "token"
42
- expect(subject).to be_authorizable
43
- end
44
-
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
50
-
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
56
- end
57
-
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
62
-
63
- it 'does not accept "code" as response type' do
64
- attributes[:response_type] = "code"
65
- expect(subject).not_to be_authorizable
66
- end
67
- end
68
-
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
73
-
74
- it 'does not accept "token" as response type' do
75
- attributes[:response_type] = "token"
76
- expect(subject).not_to be_authorizable
77
- end
78
- end
79
-
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
85
-
86
- it "rejects (globally) non-valid scopes" do
87
- attributes[:scope] = "invalid"
88
- expect(subject).not_to be_authorizable
89
- end
90
-
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
96
-
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
102
- end
103
-
104
- context "client application restricts valid scopes" do
105
- let(:application) do
106
- FactoryBot.create(:application, scopes: Scopes.from_string("public nonsense"))
107
- end
108
-
109
- it "accepts valid scopes" do
110
- attributes[:scope] = "public"
111
- expect(subject).to be_authorizable
112
- end
113
-
114
- it "rejects (globally) non-valid scopes" do
115
- attributes[:scope] = "invalid"
116
- expect(subject).not_to be_authorizable
117
- end
118
-
119
- it "rejects (application level) non-valid scopes" do
120
- attributes[:scope] = "profile"
121
- expect(subject).to_not be_authorizable
122
- end
123
-
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"
127
- expect(subject).to be_authorizable
128
- end
129
-
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"
133
- expect(subject).not_to be_authorizable
134
- end
135
- end
136
-
137
- context "when scope is not provided to pre_authorization" do
138
- before { attributes[:scope] = nil }
139
-
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
148
-
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
156
-
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
161
-
162
- it "stores the state" do
163
- expect(subject.state).to eq("save-this")
164
- end
165
-
166
- it "rejects if response type is not allowed" do
167
- attributes[:response_type] = "whops"
168
- expect(subject).not_to be_authorizable
169
- end
170
-
171
- it "requires an existing client" do
172
- attributes[:client_id] = nil
173
- expect(subject).not_to be_authorizable
174
- end
175
-
176
- it "requires a redirect uri" do
177
- attributes[:redirect_uri] = nil
178
- expect(subject).not_to be_authorizable
179
- end
180
-
181
- describe "as_json" do
182
- before { subject.authorizable? }
183
-
184
- it { is_expected.to respond_to :as_json }
185
-
186
- shared_examples "returns the pre authorization" do
187
- it "returns the pre authorization" do
188
- expect(json[:client_id]).to eq client.uid
189
- expect(json[:redirect_uri]).to eq subject.redirect_uri
190
- expect(json[:state]).to eq subject.state
191
- expect(json[:response_type]).to eq subject.response_type
192
- expect(json[:scope]).to eq subject.scope
193
- expect(json[:client_name]).to eq client.name
194
- expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
195
- end
196
- end
197
-
198
- context "when attributes param is not passed" do
199
- let(:json) { subject.as_json }
200
-
201
- include_examples "returns the pre authorization"
202
- end
203
-
204
- context "when attributes param is passed" do
205
- context "when attributes is a hash" do
206
- let(:custom_attributes) { { custom_id: "1234", custom_name: "a pretty good name" } }
207
- let(:json) { subject.as_json(custom_attributes) }
208
-
209
- include_examples "returns the pre authorization"
210
-
211
- it "merges the attributes in params" do
212
- expect(json[:custom_id]).to eq custom_attributes[:custom_id]
213
- expect(json[:custom_name]).to eq custom_attributes[:custom_name]
214
- end
215
- end
216
-
217
- context "when attributes is not a hash" do
218
- let(:json) { subject.as_json(nil) }
219
-
220
- include_examples "returns the pre authorization"
221
- end
222
- end
223
- end
224
- end
225
- end
@@ -1,178 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- module Doorkeeper::OAuth
6
- describe RefreshTokenRequest do
7
- let(:server) do
8
- double :server,
9
- access_token_expires_in: 2.minutes
10
- end
11
-
12
- let(:refresh_token) do
13
- FactoryBot.create(:access_token, use_refresh_token: true)
14
- end
15
-
16
- let(:client) { refresh_token.application }
17
- let(:credentials) { Client::Credentials.new(client.uid, client.secret) }
18
-
19
- before do
20
- allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(false)
21
- allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(false)
22
- end
23
-
24
- subject { RefreshTokenRequest.new server, refresh_token, credentials }
25
-
26
- it "issues a new token for the client" do
27
- expect { subject.authorize }.to change { client.reload.access_tokens.count }.by(1)
28
- # #sort_by used for MongoDB ORM extensions for valid ordering
29
- expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(120)
30
- end
31
-
32
- it "issues a new token for the client with custom expires_in" do
33
- server = double :server,
34
- access_token_expires_in: 2.minutes,
35
- custom_access_token_expires_in: lambda { |context|
36
- context.grant_type == Doorkeeper::OAuth::REFRESH_TOKEN ? 1234 : nil
37
- }
38
-
39
- allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
40
- allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(false)
41
-
42
- RefreshTokenRequest.new(server, refresh_token, credentials).authorize
43
-
44
- # #sort_by used for MongoDB ORM extensions for valid ordering
45
- expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(1234)
46
- end
47
-
48
- it "revokes the previous token" do
49
- expect { subject.authorize }.to change { refresh_token.revoked? }.from(false).to(true)
50
- end
51
-
52
- it "calls configured request callback methods" do
53
- expect(Doorkeeper.configuration.before_successful_strategy_response)
54
- .to receive(:call).with(subject).once
55
-
56
- expect(Doorkeeper.configuration.after_successful_strategy_response)
57
- .to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
58
-
59
- subject.authorize
60
- end
61
-
62
- it "requires the refresh token" do
63
- subject.refresh_token = nil
64
- subject.validate
65
- expect(subject.error).to eq(:invalid_request)
66
- expect(subject.missing_param).to eq(:refresh_token)
67
- end
68
-
69
- it "requires credentials to be valid if provided" do
70
- subject.client = nil
71
- subject.validate
72
- expect(subject.error).to eq(:invalid_client)
73
- end
74
-
75
- it "requires the token's client and current client to match" do
76
- subject.client = FactoryBot.create(:application)
77
- subject.validate
78
- expect(subject.error).to eq(:invalid_grant)
79
- end
80
-
81
- it "rejects revoked tokens" do
82
- refresh_token.revoke
83
- subject.validate
84
- expect(subject.error).to eq(:invalid_grant)
85
- end
86
-
87
- it "accepts expired tokens" do
88
- refresh_token.expires_in = -1
89
- refresh_token.save
90
- subject.validate
91
- expect(subject).to be_valid
92
- end
93
-
94
- context "refresh tokens expire on access token use" do
95
- let(:server) do
96
- double :server,
97
- access_token_expires_in: 2.minutes,
98
- custom_access_token_expires_in: lambda { |context|
99
- context.grant_type == Doorkeeper::OAuth::REFRESH_TOKEN ? 1234 : nil
100
- }
101
- end
102
-
103
- before do
104
- allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(true)
105
- end
106
-
107
- it "issues a new token for the client" do
108
- expect { subject.authorize }.to change { client.reload.access_tokens.count }.by(1)
109
- end
110
-
111
- it "does not revoke the previous token" do
112
- subject.authorize
113
- expect(refresh_token).not_to be_revoked
114
- end
115
-
116
- it "sets the previous refresh token in the new access token" do
117
- subject.authorize
118
- expect(
119
- # #sort_by used for MongoDB ORM extensions for valid ordering
120
- client.access_tokens.max_by(&:created_at).previous_refresh_token
121
- ).to eq(refresh_token.refresh_token)
122
- end
123
- end
124
-
125
- context "clientless access tokens" do
126
- let!(:refresh_token) { FactoryBot.create(:clientless_access_token, use_refresh_token: true) }
127
-
128
- subject { RefreshTokenRequest.new server, refresh_token, nil }
129
-
130
- it "issues a new token without a client" do
131
- expect { subject.authorize }.to change { Doorkeeper::AccessToken.count }.by(1)
132
- end
133
- end
134
-
135
- context "with scopes" do
136
- let(:refresh_token) do
137
- FactoryBot.create :access_token,
138
- use_refresh_token: true,
139
- scopes: "public write"
140
- end
141
- let(:parameters) { {} }
142
- subject { RefreshTokenRequest.new server, refresh_token, credentials, parameters }
143
-
144
- it "transfers scopes from the old token to the new token" do
145
- subject.authorize
146
- expect(Doorkeeper::AccessToken.last.scopes).to eq(%i[public write])
147
- end
148
-
149
- it "reduces scopes to the provided scopes" do
150
- parameters[:scopes] = "public"
151
- subject.authorize
152
- expect(Doorkeeper::AccessToken.last.scopes).to eq(%i[public])
153
- end
154
-
155
- it "validates that scopes are included in the original access token" do
156
- parameters[:scopes] = "public update"
157
-
158
- subject.validate
159
- expect(subject.error).to eq(:invalid_scope)
160
- end
161
-
162
- it "uses params[:scope] in favor of scopes if present (valid)" do
163
- parameters[:scopes] = "public update"
164
- parameters[:scope] = "public"
165
- subject.authorize
166
- expect(Doorkeeper::AccessToken.last.scopes).to eq(%i[public])
167
- end
168
-
169
- it "uses params[:scope] in favor of scopes if present (invalid)" do
170
- parameters[:scopes] = "public"
171
- parameters[:scope] = "public update"
172
-
173
- subject.validate
174
- expect(subject.error).to eq(:invalid_scope)
175
- end
176
- end
177
- end
178
- end
@@ -1,148 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- module Doorkeeper::OAuth
6
- describe Scopes do
7
- describe "#add" do
8
- it "allows you to add scopes with symbols" do
9
- subject.add :public
10
- expect(subject.all).to eq(["public"])
11
- end
12
-
13
- it "allows you to add scopes with strings" do
14
- subject.add "public"
15
- expect(subject.all).to eq(["public"])
16
- end
17
-
18
- it "do not add already included scopes" do
19
- subject.add :public
20
- subject.add :public
21
- expect(subject.all).to eq(["public"])
22
- end
23
- end
24
-
25
- describe "#exists" do
26
- before do
27
- subject.add :public
28
- end
29
-
30
- it "returns true if scope with given name is present" do
31
- expect(subject.exists?("public")).to be_truthy
32
- end
33
-
34
- it "returns false if scope with given name does not exist" do
35
- expect(subject.exists?("other")).to be_falsey
36
- end
37
-
38
- it "handles symbols" do
39
- expect(subject.exists?(:public)).to be_truthy
40
- expect(subject.exists?(:other)).to be_falsey
41
- end
42
- end
43
-
44
- describe ".from_string" do
45
- let(:string) { "public write" }
46
-
47
- subject { Scopes.from_string(string) }
48
-
49
- it { expect(subject).to be_a(Scopes) }
50
-
51
- describe "#all" do
52
- it "should be an array of the expected scopes" do
53
- scopes_array = subject.all
54
- expect(scopes_array.size).to eq(2)
55
- expect(scopes_array).to include("public")
56
- expect(scopes_array).to include("write")
57
- end
58
- end
59
- end
60
-
61
- describe "#+" do
62
- it "can add to another scope object" do
63
- scopes = Scopes.from_string("public") + Scopes.from_string("admin")
64
- expect(scopes.all).to eq(%w[public admin])
65
- end
66
-
67
- it "does not change the existing object" do
68
- origin = Scopes.from_string("public")
69
- expect(origin.to_s).to eq("public")
70
- end
71
-
72
- it "can add an array to a scope object" do
73
- scopes = Scopes.from_string("public") + ["admin"]
74
- expect(scopes.all).to eq(%w[public admin])
75
- end
76
-
77
- it "raises an error if cannot handle addition" do
78
- expect do
79
- Scopes.from_string("public") + "admin"
80
- end.to raise_error(NoMethodError)
81
- end
82
- end
83
-
84
- describe "#&" do
85
- it "can get intersection with another scope object" do
86
- scopes = Scopes.from_string("public admin") & Scopes.from_string("write admin")
87
- expect(scopes.all).to eq(%w[admin])
88
- end
89
-
90
- it "does not change the existing object" do
91
- origin = Scopes.from_string("public admin")
92
- origin & Scopes.from_string("write admin")
93
- expect(origin.to_s).to eq("public admin")
94
- end
95
-
96
- it "can get intersection with an array" do
97
- scopes = Scopes.from_string("public admin") & %w[write admin]
98
- expect(scopes.all).to eq(%w[admin])
99
- end
100
- end
101
-
102
- describe "#==" do
103
- it "is equal to another set of scopes" do
104
- expect(Scopes.from_string("public")).to eq(Scopes.from_string("public"))
105
- end
106
-
107
- it "is equal to another set of scopes with no particular order" do
108
- expect(Scopes.from_string("public write")).to eq(Scopes.from_string("write public"))
109
- end
110
-
111
- it "differs from another set of scopes when scopes are not the same" do
112
- expect(Scopes.from_string("public write")).not_to eq(Scopes.from_string("write"))
113
- end
114
-
115
- it "does not raise an error when compared to a non-enumerable object" do
116
- expect { Scopes.from_string("public") == false }.not_to raise_error
117
- end
118
- end
119
-
120
- describe "#has_scopes?" do
121
- subject { Scopes.from_string("public admin") }
122
-
123
- it "returns true when at least one scope is included" do
124
- expect(subject.has_scopes?(Scopes.from_string("public"))).to be_truthy
125
- end
126
-
127
- it "returns true when all scopes are included" do
128
- expect(subject.has_scopes?(Scopes.from_string("public admin"))).to be_truthy
129
- end
130
-
131
- it "is true if all scopes are included in any order" do
132
- expect(subject.has_scopes?(Scopes.from_string("admin public"))).to be_truthy
133
- end
134
-
135
- it "is false if no scopes are included" do
136
- expect(subject.has_scopes?(Scopes.from_string("notexistent"))).to be_falsey
137
- end
138
-
139
- it "returns false when any scope is not included" do
140
- expect(subject.has_scopes?(Scopes.from_string("public nope"))).to be_falsey
141
- end
142
-
143
- it "is false if no scopes are included even for existing ones" do
144
- expect(subject.has_scopes?(Scopes.from_string("public admin notexistent"))).to be_falsey
145
- end
146
- end
147
- end
148
- end
@@ -1,153 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- module Doorkeeper::OAuth
6
- describe TokenRequest do
7
- let :application do
8
- FactoryBot.create(:application, scopes: "public")
9
- end
10
-
11
- let :pre_auth do
12
- server = Doorkeeper.configuration
13
- allow(server).to receive(:default_scopes).and_return(Scopes.from_string("public"))
14
- allow(server).to receive(:grant_flows).and_return(Scopes.from_string("implicit"))
15
-
16
- client = Doorkeeper::OAuth::Client.new(application)
17
-
18
- attributes = {
19
- client_id: client.uid,
20
- response_type: "token",
21
- redirect_uri: "https://app.com/callback",
22
- }
23
-
24
- pre_auth = PreAuthorization.new(server, attributes)
25
- pre_auth.authorizable?
26
- pre_auth
27
- end
28
-
29
- let :owner do
30
- double :owner, id: 7866
31
- end
32
-
33
- subject do
34
- TokenRequest.new(pre_auth, owner)
35
- end
36
-
37
- it "creates an access token" do
38
- expect do
39
- subject.authorize
40
- end.to change { Doorkeeper::AccessToken.count }.by(1)
41
- end
42
-
43
- it "returns a code response" do
44
- expect(subject.authorize).to be_a(CodeResponse)
45
- end
46
-
47
- context "when pre_auth is denied" do
48
- it "does not create token and returns a error response" do
49
- expect { subject.deny }.not_to(change { Doorkeeper::AccessToken.count })
50
- expect(subject.deny).to be_a(ErrorResponse)
51
- end
52
- end
53
-
54
- describe "with custom expiration" do
55
- context "when proper TTL returned" do
56
- before do
57
- Doorkeeper.configure do
58
- orm DOORKEEPER_ORM
59
- custom_access_token_expires_in do |context|
60
- context.grant_type == Doorkeeper::OAuth::IMPLICIT ? 1234 : nil
61
- end
62
- end
63
- end
64
-
65
- it "should use the custom ttl" do
66
- subject.authorize
67
- token = Doorkeeper::AccessToken.first
68
- expect(token.expires_in).to eq(1234)
69
- end
70
- end
71
-
72
- context "when nil TTL returned" do
73
- before do
74
- Doorkeeper.configure do
75
- orm DOORKEEPER_ORM
76
- access_token_expires_in 654
77
- custom_access_token_expires_in do |_context|
78
- nil
79
- end
80
- end
81
- end
82
-
83
- it "should fallback to access_token_expires_in" do
84
- subject.authorize
85
- token = Doorkeeper::AccessToken.first
86
- expect(token.expires_in).to eq(654)
87
- end
88
- end
89
-
90
- context "when infinite TTL returned" do
91
- before do
92
- Doorkeeper.configure do
93
- orm DOORKEEPER_ORM
94
- access_token_expires_in 654
95
- custom_access_token_expires_in do |_context|
96
- Float::INFINITY
97
- end
98
- end
99
- end
100
-
101
- it "should fallback to access_token_expires_in" do
102
- subject.authorize
103
- token = Doorkeeper::AccessToken.first
104
- expect(token.expires_in).to be_nil
105
- end
106
- end
107
- end
108
-
109
- context "token reuse" do
110
- it "creates a new token if there are no matching tokens" do
111
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
112
- expect do
113
- subject.authorize
114
- end.to change { Doorkeeper::AccessToken.count }.by(1)
115
- end
116
-
117
- it "creates a new token if scopes do not match" do
118
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
119
- FactoryBot.create(:access_token, application_id: pre_auth.client.id,
120
- resource_owner_id: owner.id, scopes: "")
121
- expect do
122
- subject.authorize
123
- end.to change { Doorkeeper::AccessToken.count }.by(1)
124
- end
125
-
126
- it "skips token creation if there is a matching one reusable" do
127
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
128
- allow(application.scopes).to receive(:has_scopes?).and_return(true)
129
- allow(application.scopes).to receive(:all?).and_return(true)
130
-
131
- FactoryBot.create(:access_token, application_id: pre_auth.client.id,
132
- resource_owner_id: owner.id, scopes: "public")
133
-
134
- expect { subject.authorize }.not_to(change { Doorkeeper::AccessToken.count })
135
- end
136
-
137
- it "creates new token if there is a matching one but non reusable" do
138
- allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
139
- allow(application.scopes).to receive(:has_scopes?).and_return(true)
140
- allow(application.scopes).to receive(:all?).and_return(true)
141
-
142
- FactoryBot.create(:access_token, application_id: pre_auth.client.id,
143
- resource_owner_id: owner.id, scopes: "public")
144
-
145
- allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
146
-
147
- expect do
148
- subject.authorize
149
- end.to change { Doorkeeper::AccessToken.count }.by(1)
150
- end
151
- end
152
- end
153
- end