doorkeeper 5.1.0 → 5.5.1

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