doorkeeper 5.3.3 → 5.5.0.rc2

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