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,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- describe ::Doorkeeper::SecretStoring::Sha256Hash do
6
- subject { described_class }
7
- let(:instance) { double("instance") }
8
-
9
- let(:hash_function) do
10
- ->(input) { ::Digest::SHA256.hexdigest(input) }
11
- end
12
-
13
- describe "#transform_secret" do
14
- it "raises" do
15
- expect(subject.transform_secret("foo")).to eq hash_function.call("foo")
16
- end
17
- end
18
-
19
- describe "#restore_secret" do
20
- it "raises" do
21
- expect { subject.restore_secret(instance, :token) }.to raise_error(NotImplementedError)
22
- end
23
- end
24
-
25
- describe "#allows_restoring_secrets?" do
26
- it "does not allow it" do
27
- expect(subject.allows_restoring_secrets?).to eq false
28
- end
29
- end
30
-
31
- describe "validate_for" do
32
- it "allows for valid model" do
33
- expect(subject.validate_for(:application)).to eq true
34
- expect(subject.validate_for(:token)).to eq true
35
- end
36
-
37
- it "raises for invalid model" do
38
- expect { subject.validate_for(:wat) }.to raise_error(ArgumentError, /can not be used for wat/)
39
- end
40
- end
41
-
42
- describe "secret_matches?" do
43
- it "compares input with #transform_secret" do
44
- expect(subject.secret_matches?("input", "input")).to eq false
45
- expect(subject.secret_matches?("a", hash_function.call("a"))).to eq true
46
- end
47
- end
48
- end
@@ -1,49 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- describe Doorkeeper::Server do
6
- let(:fake_class) { double :fake_class }
7
-
8
- subject do
9
- described_class.new
10
- end
11
-
12
- describe ".authorization_request" do
13
- it "raises error when strategy does not match phase" do
14
- expect do
15
- subject.token_request(:code)
16
- end.to raise_error(Doorkeeper::Errors::InvalidTokenStrategy)
17
- end
18
-
19
- context "when only Authorization Code strategy is enabled" do
20
- before do
21
- allow(Doorkeeper.configuration)
22
- .to receive(:grant_flows)
23
- .and_return(["authorization_code"])
24
- end
25
-
26
- it "raises error when using the disabled Client Credentials strategy" do
27
- expect do
28
- subject.token_request(:client_credentials)
29
- end.to raise_error(Doorkeeper::Errors::InvalidTokenStrategy)
30
- end
31
- end
32
-
33
- it "builds the request with selected strategy" do
34
- stub_const "Doorkeeper::Request::Code", fake_class
35
- expect(fake_class).to receive(:new).with(subject)
36
- subject.authorization_request :code
37
- end
38
-
39
- it "builds the request with composite strategy name" do
40
- allow(Doorkeeper.configuration)
41
- .to receive(:authorization_response_types)
42
- .and_return(["id_token token"])
43
-
44
- stub_const "Doorkeeper::Request::IdTokenToken", fake_class
45
- expect(fake_class).to receive(:new).with(subject)
46
- subject.authorization_request "id_token token"
47
- end
48
- end
49
- end
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- describe Doorkeeper::StaleRecordsCleaner do
6
- let(:cleaner) { described_class.new(model) }
7
- let(:models_by_name) do
8
- {
9
- access_token: Doorkeeper::AccessToken,
10
- access_grant: Doorkeeper::AccessGrant,
11
- }
12
- end
13
-
14
- context "when ORM has no cleaner class" do
15
- it "raises an error" do
16
- allow_any_instance_of(Doorkeeper::Config).to receive(:orm).and_return("hibernate")
17
-
18
- expect do
19
- described_class.for(Doorkeeper::AccessToken)
20
- end.to raise_error(Doorkeeper::Errors::NoOrmCleaner, /has no cleaner/)
21
- end
22
- end
23
-
24
- %i[access_token access_grant].each do |model_name|
25
- context "(#{model_name})" do
26
- let(:model) { models_by_name.fetch(model_name) }
27
-
28
- describe "#clean_revoked" do
29
- subject { cleaner.clean_revoked }
30
-
31
- context "with revoked record" do
32
- before do
33
- FactoryBot.create model_name, revoked_at: Time.current - 1.minute
34
- end
35
-
36
- it "removes the record" do
37
- expect { subject }.to change { model.count }.to(0)
38
- end
39
- end
40
-
41
- context "with record revoked in the future" do
42
- before do
43
- FactoryBot.create model_name, revoked_at: Time.current + 1.minute
44
- end
45
-
46
- it "keeps the record" do
47
- expect { subject }.not_to(change { model.count })
48
- end
49
- end
50
-
51
- context "with unrevoked record" do
52
- before do
53
- FactoryBot.create model_name, revoked_at: nil
54
- end
55
-
56
- it "keeps the record" do
57
- expect { subject }.not_to(change { model.count })
58
- end
59
- end
60
- end
61
-
62
- describe "#clean_expired" do
63
- subject { cleaner.clean_expired(ttl) }
64
- let(:ttl) { 500 }
65
- let(:expiry_border) { ttl.seconds.ago }
66
-
67
- context "with record that is expired" do
68
- before do
69
- FactoryBot.create model_name, created_at: expiry_border - 1.minute
70
- end
71
-
72
- it "removes the record" do
73
- expect { subject }.to change { model.count }.to(0)
74
- end
75
- end
76
-
77
- context "with record that is not expired" do
78
- before do
79
- FactoryBot.create model_name, created_at: expiry_border + 1.minute
80
- end
81
-
82
- it "keeps the record" do
83
- expect { subject }.not_to(change { model.count })
84
- end
85
- end
86
- end
87
- end
88
- end
89
- end
@@ -1,161 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- describe Doorkeeper::AccessGrant do
6
- let(:client) { FactoryBot.build_stubbed(:application) }
7
- let(:clazz) { Doorkeeper::AccessGrant }
8
-
9
- subject { FactoryBot.build(:access_grant, application: client) }
10
-
11
- it { expect(subject).to be_valid }
12
-
13
- it_behaves_like "an accessible token"
14
- it_behaves_like "a revocable token"
15
- it_behaves_like "a unique token" do
16
- let(:factory_name) { :access_grant }
17
- end
18
-
19
- context "with hashing enabled" do
20
- let(:grant) { FactoryBot.create :access_grant }
21
- include_context "with token hashing enabled"
22
-
23
- it "holds a volatile plaintext token when created" do
24
- expect(grant.plaintext_token).to be_a(String)
25
- expect(grant.token)
26
- .to eq(hashed_or_plain_token_func.call(grant.plaintext_token))
27
-
28
- # Finder method only finds the hashed token
29
- loaded = clazz.find_by(token: grant.token)
30
- expect(loaded).to eq(grant)
31
- expect(loaded.plaintext_token).to be_nil
32
- expect(loaded.token).to eq(grant.token)
33
- end
34
-
35
- it "does not find_by plain text tokens" do
36
- expect(clazz.find_by(token: grant.plaintext_token)).to be_nil
37
- end
38
-
39
- describe "with having a plain text token" do
40
- let(:plain_text_token) { "plain text token" }
41
-
42
- before do
43
- # Assume we have a plain text token from before activating the option
44
- grant.update_column(:token, plain_text_token)
45
- end
46
-
47
- context "without fallback lookup" do
48
- it "does not provide lookups with either through by_token" do
49
- expect(clazz.by_token(plain_text_token)).to eq(nil)
50
- expect(clazz.by_token(grant.token)).to eq(nil)
51
-
52
- # And it does not touch the token
53
- grant.reload
54
- expect(grant.token).to eq(plain_text_token)
55
- end
56
- end
57
-
58
- context "with fallback lookup" do
59
- include_context "with token hashing and fallback lookup enabled"
60
-
61
- it "upgrades a plain token when falling back to it" do
62
- # Side-effect: This will automatically upgrade the token
63
- expect(clazz).to receive(:upgrade_fallback_value).and_call_original
64
- expect(clazz.by_token(plain_text_token))
65
- .to have_attributes(
66
- resource_owner_id: grant.resource_owner_id,
67
- application_id: grant.application_id,
68
- redirect_uri: grant.redirect_uri,
69
- expires_in: grant.expires_in,
70
- scopes: grant.scopes,
71
- )
72
-
73
- # Will find subsequently by hashing the token
74
- expect(clazz.by_token(plain_text_token))
75
- .to have_attributes(
76
- resource_owner_id: grant.resource_owner_id,
77
- application_id: grant.application_id,
78
- redirect_uri: grant.redirect_uri,
79
- expires_in: grant.expires_in,
80
- scopes: grant.scopes,
81
- )
82
-
83
- # Not all the ORM support :id PK
84
- expect(clazz.by_token(plain_text_token).id).to eq(grant.id) if grant.respond_to?(:id)
85
-
86
- # And it modifies the token value
87
- grant.reload
88
- expect(grant.token).not_to eq(plain_text_token)
89
- expect(clazz.find_by(token: plain_text_token)).to eq(nil)
90
- expect(clazz.find_by(token: grant.token)).not_to be_nil
91
- end
92
- end
93
- end
94
- end
95
-
96
- describe "validations" do
97
- it "is invalid without resource_owner_id" do
98
- subject.resource_owner_id = nil
99
- expect(subject).not_to be_valid
100
- end
101
-
102
- it "is invalid without application_id" do
103
- subject.application_id = nil
104
- expect(subject).not_to be_valid
105
- end
106
-
107
- it "is invalid without token" do
108
- subject.save
109
- subject.token = nil
110
- expect(subject).not_to be_valid
111
- end
112
-
113
- it "is invalid without expires_in" do
114
- subject.expires_in = nil
115
- expect(subject).not_to be_valid
116
- end
117
- end
118
-
119
- describe ".revoke_all_for" do
120
- let(:resource_owner) { double(id: 100) }
121
- let(:application) { FactoryBot.create :application }
122
- let(:default_attributes) do
123
- {
124
- application: application,
125
- resource_owner_id: resource_owner.id,
126
- }
127
- end
128
-
129
- it "revokes all tokens for given application and resource owner" do
130
- FactoryBot.create :access_grant, default_attributes
131
-
132
- described_class.revoke_all_for(application.id, resource_owner)
133
-
134
- described_class.all.each do |token|
135
- expect(token).to be_revoked
136
- end
137
- end
138
-
139
- it "matches application" do
140
- access_grant_for_different_app = FactoryBot.create(
141
- :access_grant,
142
- default_attributes.merge(application: FactoryBot.create(:application)),
143
- )
144
-
145
- described_class.revoke_all_for(application.id, resource_owner)
146
-
147
- expect(access_grant_for_different_app.reload).not_to be_revoked
148
- end
149
-
150
- it "matches resource owner" do
151
- access_grant_for_different_owner = FactoryBot.create(
152
- :access_grant,
153
- default_attributes.merge(resource_owner_id: 90),
154
- )
155
-
156
- described_class.revoke_all_for application.id, resource_owner
157
-
158
- expect(access_grant_for_different_owner.reload).not_to be_revoked
159
- end
160
- end
161
- end
@@ -1,622 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- module Doorkeeper
6
- describe AccessToken do
7
- let(:clazz) { Doorkeeper::AccessToken }
8
- subject { FactoryBot.build(:access_token) }
9
-
10
- it { expect(subject).to be_valid }
11
-
12
- it_behaves_like "an accessible token"
13
- it_behaves_like "a revocable token"
14
- it_behaves_like "a unique token" do
15
- let(:factory_name) { :access_token }
16
- end
17
-
18
- module CustomGeneratorArgs
19
- def self.generate; end
20
- end
21
-
22
- describe :generate_token do
23
- it "generates a token using the default method" do
24
- FactoryBot.create :access_token
25
-
26
- token = FactoryBot.create :access_token
27
- expect(token.token).to be_a(String)
28
- end
29
-
30
- context "with hashing enabled" do
31
- let(:token) { FactoryBot.create :access_token }
32
- include_context "with token hashing enabled"
33
-
34
- it "holds a volatile plaintext token when created" do
35
- expect(token.plaintext_token).to be_a(String)
36
- expect(token.token)
37
- .to eq(hashed_or_plain_token_func.call(token.plaintext_token))
38
-
39
- # Finder method only finds the hashed token
40
- loaded = clazz.find_by(token: token.token)
41
- expect(loaded).to eq(token)
42
- expect(loaded.plaintext_token).to be_nil
43
- expect(loaded.token).to eq(token.token)
44
- end
45
-
46
- it "does not find_by plain text tokens" do
47
- expect(clazz.find_by(token: token.plaintext_token)).to be_nil
48
- end
49
-
50
- describe "with having a plain text token" do
51
- let(:plain_text_token) { "plain text token" }
52
- let(:access_token) { FactoryBot.create :access_token }
53
-
54
- before do
55
- # Assume we have a plain text token from before activating the option
56
- access_token.update_column(:token, plain_text_token)
57
- end
58
-
59
- context "without fallback lookup" do
60
- it "does not provide lookups with either through by_token" do
61
- expect(clazz.by_token(plain_text_token)).to eq(nil)
62
- expect(clazz.by_token(access_token.token)).to eq(nil)
63
-
64
- # And it does not touch the token
65
- access_token.reload
66
- expect(access_token.token).to eq(plain_text_token)
67
- end
68
- end
69
-
70
- context "with fallback lookup" do
71
- include_context "with token hashing and fallback lookup enabled"
72
-
73
- it "upgrades a plain token when falling back to it" do
74
- # Side-effect: This will automatically upgrade the token
75
- expect(clazz).to receive(:upgrade_fallback_value).and_call_original
76
- expect(clazz.by_token(plain_text_token))
77
- .to have_attributes(
78
- resource_owner_id: access_token.resource_owner_id,
79
- application_id: access_token.application_id,
80
- scopes: access_token.scopes,
81
- )
82
-
83
- # Will find subsequently by hashing the token
84
- expect(clazz.by_token(plain_text_token))
85
- .to have_attributes(
86
- resource_owner_id: access_token.resource_owner_id,
87
- application_id: access_token.application_id,
88
- scopes: access_token.scopes,
89
- )
90
-
91
- # Not all the ORM support :id PK
92
- if access_token.respond_to?(:id)
93
- expect(clazz.by_token(plain_text_token).id).to eq(access_token.id)
94
- end
95
-
96
- # And it modifies the token value
97
- access_token.reload
98
- expect(access_token.token).not_to eq(plain_text_token)
99
- expect(clazz.find_by(token: plain_text_token)).to eq(nil)
100
- expect(clazz.find_by(token: access_token.token)).not_to be_nil
101
- end
102
- end
103
- end
104
- end
105
-
106
- it "generates a token using a custom object" do
107
- eigenclass = class << CustomGeneratorArgs; self; end
108
- eigenclass.class_eval do
109
- remove_method :generate
110
- end
111
- module CustomGeneratorArgs
112
- def self.generate(opts = {})
113
- "custom_generator_token_#{opts[:resource_owner_id]}"
114
- end
115
- end
116
-
117
- Doorkeeper.configure do
118
- orm DOORKEEPER_ORM
119
- access_token_generator "Doorkeeper::CustomGeneratorArgs"
120
- end
121
-
122
- token = FactoryBot.create :access_token
123
- expect(token.token).to match(/custom_generator_token_\d+/)
124
- end
125
-
126
- it "allows the custom generator to access the application details" do
127
- eigenclass = class << CustomGeneratorArgs; self; end
128
- eigenclass.class_eval do
129
- remove_method :generate
130
- end
131
-
132
- module CustomGeneratorArgs
133
- def self.generate(opts = {})
134
- "custom_generator_token_#{opts[:application].name}"
135
- end
136
- end
137
-
138
- Doorkeeper.configure do
139
- orm DOORKEEPER_ORM
140
- access_token_generator "Doorkeeper::CustomGeneratorArgs"
141
- end
142
-
143
- token = FactoryBot.create :access_token
144
- expect(token.token).to match(/custom_generator_token_Application \d+/)
145
- end
146
-
147
- it "allows the custom generator to access the scopes" do
148
- eigenclass = class << CustomGeneratorArgs; self; end
149
- eigenclass.class_eval do
150
- remove_method :generate
151
- end
152
- module CustomGeneratorArgs
153
- def self.generate(opts = {})
154
- "custom_generator_token_#{opts[:scopes].count}_#{opts[:scopes]}"
155
- end
156
- end
157
-
158
- Doorkeeper.configure do
159
- orm DOORKEEPER_ORM
160
- access_token_generator "Doorkeeper::CustomGeneratorArgs"
161
- end
162
-
163
- token = FactoryBot.create :access_token, scopes: "public write"
164
-
165
- expect(token.token).to eq "custom_generator_token_2_public write"
166
- end
167
-
168
- it "allows the custom generator to access the expiry length" do
169
- eigenclass = class << CustomGeneratorArgs; self; end
170
- eigenclass.class_eval do
171
- remove_method :generate
172
- end
173
- module CustomGeneratorArgs
174
- def self.generate(opts = {})
175
- "custom_generator_token_#{opts[:expires_in]}"
176
- end
177
- end
178
-
179
- Doorkeeper.configure do
180
- orm DOORKEEPER_ORM
181
- access_token_generator "Doorkeeper::CustomGeneratorArgs"
182
- end
183
-
184
- token = FactoryBot.create :access_token
185
- expect(token.token).to eq "custom_generator_token_7200"
186
- end
187
-
188
- it "allows the custom generator to access the created time" do
189
- module CustomGeneratorArgs
190
- def self.generate(opts = {})
191
- "custom_generator_token_#{opts[:created_at].to_i}"
192
- end
193
- end
194
-
195
- Doorkeeper.configure do
196
- orm DOORKEEPER_ORM
197
- access_token_generator "Doorkeeper::CustomGeneratorArgs"
198
- end
199
-
200
- token = FactoryBot.create :access_token
201
- created_at = token.created_at
202
- expect(token.token).to eq "custom_generator_token_#{created_at.to_i}"
203
- end
204
-
205
- it "raises an error if the custom object does not support generate" do
206
- module NoGenerate
207
- end
208
-
209
- Doorkeeper.configure do
210
- orm DOORKEEPER_ORM
211
- access_token_generator "Doorkeeper::NoGenerate"
212
- end
213
-
214
- expect { FactoryBot.create :access_token }.to(
215
- raise_error(Doorkeeper::Errors::UnableToGenerateToken),
216
- )
217
- end
218
-
219
- it "raises original error if something went wrong in custom generator" do
220
- eigenclass = class << CustomGeneratorArgs; self; end
221
- eigenclass.class_eval do
222
- remove_method :generate
223
- end
224
-
225
- module CustomGeneratorArgs
226
- def self.generate(_opts = {})
227
- raise LoadError, "custom behaviour"
228
- end
229
- end
230
-
231
- Doorkeeper.configure do
232
- orm DOORKEEPER_ORM
233
- access_token_generator "Doorkeeper::CustomGeneratorArgs"
234
- end
235
-
236
- expect { FactoryBot.create :access_token }.to(
237
- raise_error(LoadError),
238
- )
239
- end
240
-
241
- it "raises an error if the custom object does not exist" do
242
- Doorkeeper.configure do
243
- orm DOORKEEPER_ORM
244
- access_token_generator "Doorkeeper::NotReal"
245
- end
246
-
247
- expect { FactoryBot.create :access_token }.to(
248
- raise_error(Doorkeeper::Errors::TokenGeneratorNotFound, /NotReal/),
249
- )
250
- end
251
- end
252
-
253
- describe :refresh_token do
254
- it "has empty refresh token if it was not required" do
255
- token = FactoryBot.create :access_token
256
- expect(token.refresh_token).to be_nil
257
- end
258
-
259
- it "generates a refresh token if it was requested" do
260
- token = FactoryBot.create :access_token, use_refresh_token: true
261
- expect(token.refresh_token).not_to be_nil
262
- end
263
-
264
- it "is not valid if token exists" do
265
- token1 = FactoryBot.create :access_token, use_refresh_token: true
266
- token2 = FactoryBot.create :access_token, use_refresh_token: true
267
- token2.refresh_token = token1.refresh_token
268
- expect(token2).not_to be_valid
269
- end
270
-
271
- it "expects database to raise an error if refresh tokens are the same" do
272
- token1 = FactoryBot.create :access_token, use_refresh_token: true
273
- token2 = FactoryBot.create :access_token, use_refresh_token: true
274
- expect do
275
- token2.refresh_token = token1.refresh_token
276
- token2.save(validate: false)
277
- end.to raise_error(uniqueness_error)
278
- end
279
-
280
- context "with hashing enabled" do
281
- include_context "with token hashing enabled"
282
- let(:token) { FactoryBot.create :access_token, use_refresh_token: true }
283
-
284
- it "holds a volatile refresh token when created" do
285
- expect(token.plaintext_refresh_token).to be_a(String)
286
- expect(token.refresh_token)
287
- .to eq(hashed_or_plain_token_func.call(token.plaintext_refresh_token))
288
-
289
- # Finder method only finds the hashed token
290
- loaded = clazz.find_by(refresh_token: token.refresh_token)
291
- expect(loaded).to eq(token)
292
- expect(loaded.plaintext_refresh_token).to be_nil
293
- expect(loaded.refresh_token).to eq(token.refresh_token)
294
- end
295
-
296
- it "does not find_by plain text refresh tokens" do
297
- expect(clazz.find_by(refresh_token: token.plaintext_refresh_token)).to be_nil
298
- end
299
-
300
- describe "with having a plain text token" do
301
- let(:plain_refresh_token) { "plain refresh token" }
302
- let(:access_token) { FactoryBot.create :access_token }
303
-
304
- before do
305
- # Assume we have a plain text token from before activating the option
306
- access_token.update_column(:refresh_token, plain_refresh_token)
307
- end
308
-
309
- context "without fallback lookup" do
310
- it "does not provide lookups with either through by_token" do
311
- expect(clazz.by_refresh_token(plain_refresh_token)).to eq(nil)
312
- expect(clazz.by_refresh_token(access_token.refresh_token)).to eq(nil)
313
-
314
- # And it does not touch the token
315
- access_token.reload
316
- expect(access_token.refresh_token).to eq(plain_refresh_token)
317
- end
318
- end
319
-
320
- context "with fallback lookup" do
321
- include_context "with token hashing and fallback lookup enabled"
322
-
323
- it "upgrades a plain token when falling back to it" do
324
- # Side-effect: This will automatically upgrade the token
325
- expect(clazz).to receive(:upgrade_fallback_value).and_call_original
326
- expect(clazz.by_refresh_token(plain_refresh_token))
327
- .to have_attributes(
328
- token: access_token.token,
329
- resource_owner_id: access_token.resource_owner_id,
330
- application_id: access_token.application_id,
331
- )
332
-
333
- # Will find subsequently by hashing the token
334
- expect(clazz.by_refresh_token(plain_refresh_token))
335
- .to have_attributes(
336
- token: access_token.token,
337
- resource_owner_id: access_token.resource_owner_id,
338
- application_id: access_token.application_id,
339
- )
340
-
341
- # Not all the ORM support :id PK
342
- if access_token.respond_to?(:id)
343
- expect(clazz.by_refresh_token(plain_refresh_token).id).to eq(access_token.id)
344
- end
345
-
346
- # And it modifies the token value
347
- access_token.reload
348
- expect(access_token.refresh_token).not_to eq(plain_refresh_token)
349
- expect(clazz.find_by(refresh_token: plain_refresh_token)).to eq(nil)
350
- expect(clazz.find_by(refresh_token: access_token.refresh_token)).not_to be_nil
351
- end
352
- end
353
- end
354
- end
355
- end
356
-
357
- describe "validations" do
358
- it "is valid without resource_owner_id" do
359
- # For client credentials flow
360
- subject.resource_owner_id = nil
361
- expect(subject).to be_valid
362
- end
363
-
364
- it "is valid without application_id" do
365
- # For resource owner credentials flow
366
- subject.application_id = nil
367
- expect(subject).to be_valid
368
- end
369
- end
370
-
371
- describe "#same_credential?" do
372
- context "with default parameters" do
373
- let(:resource_owner_id) { 100 }
374
- let(:application) { FactoryBot.create :application }
375
- let(:default_attributes) do
376
- { application: application, resource_owner_id: resource_owner_id }
377
- end
378
- let(:access_token1) { FactoryBot.create :access_token, default_attributes }
379
-
380
- context "the second token has the same owner and same app" do
381
- let(:access_token2) { FactoryBot.create :access_token, default_attributes }
382
- it "success" do
383
- expect(access_token1.same_credential?(access_token2)).to be_truthy
384
- end
385
- end
386
-
387
- context "the second token has same owner and different app" do
388
- let(:other_application) { FactoryBot.create :application }
389
- let(:access_token2) do
390
- FactoryBot.create :access_token,
391
- application: other_application,
392
- resource_owner_id: resource_owner_id
393
- end
394
-
395
- it "fail" do
396
- expect(access_token1.same_credential?(access_token2)).to be_falsey
397
- end
398
- end
399
-
400
- context "the second token has different owner and different app" do
401
- let(:other_application) { FactoryBot.create :application }
402
- let(:access_token2) do
403
- FactoryBot.create :access_token, application: other_application, resource_owner_id: 42
404
- end
405
-
406
- it "fail" do
407
- expect(access_token1.same_credential?(access_token2)).to be_falsey
408
- end
409
- end
410
-
411
- context "the second token has different owner and same app" do
412
- let(:access_token2) do
413
- FactoryBot.create :access_token, application: application, resource_owner_id: 42
414
- end
415
-
416
- it "fail" do
417
- expect(access_token1.same_credential?(access_token2)).to be_falsey
418
- end
419
- end
420
- end
421
- end
422
-
423
- describe "#acceptable?" do
424
- context "a token that is not accessible" do
425
- let(:token) { FactoryBot.create(:access_token, created_at: 6.hours.ago) }
426
-
427
- it "should return false" do
428
- expect(token.acceptable?(nil)).to be false
429
- end
430
- end
431
-
432
- context "a token that has the incorrect scopes" do
433
- let(:token) { FactoryBot.create(:access_token) }
434
-
435
- it "should return false" do
436
- expect(token.acceptable?(["public"])).to be false
437
- end
438
- end
439
-
440
- context "a token is acceptable with the correct scopes" do
441
- let(:token) do
442
- token = FactoryBot.create(:access_token)
443
- token[:scopes] = "public"
444
- token
445
- end
446
-
447
- it "should return true" do
448
- expect(token.acceptable?(["public"])).to be true
449
- end
450
- end
451
- end
452
-
453
- describe ".revoke_all_for" do
454
- let(:resource_owner) { double(id: 100) }
455
- let(:application) { FactoryBot.create :application }
456
- let(:default_attributes) do
457
- { application: application, resource_owner_id: resource_owner.id }
458
- end
459
-
460
- it "revokes all tokens for given application and resource owner" do
461
- FactoryBot.create :access_token, default_attributes
462
- AccessToken.revoke_all_for application.id, resource_owner
463
- AccessToken.all.each do |token|
464
- expect(token).to be_revoked
465
- end
466
- end
467
-
468
- it "matches application" do
469
- access_token_for_different_app = FactoryBot.create(
470
- :access_token,
471
- default_attributes.merge(application: FactoryBot.create(:application)),
472
- )
473
-
474
- AccessToken.revoke_all_for application.id, resource_owner
475
-
476
- expect(access_token_for_different_app.reload).not_to be_revoked
477
- end
478
-
479
- it "matches resource owner" do
480
- access_token_for_different_owner = FactoryBot.create(
481
- :access_token,
482
- default_attributes.merge(resource_owner_id: 90),
483
- )
484
-
485
- AccessToken.revoke_all_for application.id, resource_owner
486
-
487
- expect(access_token_for_different_owner.reload).not_to be_revoked
488
- end
489
- end
490
-
491
- describe ".matching_token_for" do
492
- let(:resource_owner_id) { 100 }
493
- let(:application) { FactoryBot.create :application }
494
- let(:scopes) { Doorkeeper::OAuth::Scopes.from_string("public write") }
495
- let(:default_attributes) do
496
- {
497
- application: application,
498
- resource_owner_id: resource_owner_id,
499
- scopes: scopes.to_s,
500
- }
501
- end
502
-
503
- before do
504
- default_scopes_exist(*scopes.all)
505
- end
506
-
507
- it "returns only one token" do
508
- token = FactoryBot.create :access_token, default_attributes
509
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
510
- expect(last_token).to eq(token)
511
- end
512
-
513
- it "accepts resource owner as object" do
514
- resource_owner = double(to_key: true, id: 100)
515
- token = FactoryBot.create :access_token, default_attributes
516
- last_token = AccessToken.matching_token_for(application, resource_owner, scopes)
517
- expect(last_token).to eq(token)
518
- end
519
-
520
- it "accepts nil as resource owner" do
521
- token = FactoryBot.create :access_token, default_attributes.merge(resource_owner_id: nil)
522
- last_token = AccessToken.matching_token_for(application, nil, scopes)
523
- expect(last_token).to eq(token)
524
- end
525
-
526
- it "excludes revoked tokens" do
527
- FactoryBot.create :access_token, default_attributes.merge(revoked_at: 1.day.ago)
528
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
529
- expect(last_token).to be_nil
530
- end
531
-
532
- it "excludes tokens with a different application" do
533
- FactoryBot.create :access_token, default_attributes.merge(application: FactoryBot.create(:application))
534
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
535
- expect(last_token).to be_nil
536
- end
537
-
538
- it "excludes tokens with a different resource owner" do
539
- FactoryBot.create :access_token, default_attributes.merge(resource_owner_id: 2)
540
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
541
- expect(last_token).to be_nil
542
- end
543
-
544
- it "excludes tokens with fewer scopes" do
545
- FactoryBot.create :access_token, default_attributes.merge(scopes: "public")
546
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
547
- expect(last_token).to be_nil
548
- end
549
-
550
- it "excludes tokens with different scopes" do
551
- FactoryBot.create :access_token, default_attributes.merge(scopes: "public email")
552
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
553
- expect(last_token).to be_nil
554
- end
555
-
556
- it "excludes tokens with additional scopes" do
557
- FactoryBot.create :access_token, default_attributes.merge(scopes: "public write email")
558
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
559
- expect(last_token).to be_nil
560
- end
561
-
562
- it "excludes tokens with scopes that are not present in server scopes" do
563
- FactoryBot.create :access_token, default_attributes.merge(
564
- application: application, scopes: "public read",
565
- )
566
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
567
- expect(last_token).to be_nil
568
- end
569
-
570
- it "excludes tokens with scopes that are not present in application scopes" do
571
- application = FactoryBot.create :application, scopes: "private read"
572
- FactoryBot.create :access_token, default_attributes.merge(
573
- application: application,
574
- )
575
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
576
- expect(last_token).to be_nil
577
- end
578
-
579
- it "does not match token if empty scope requested and token/app scopes present" do
580
- application = FactoryBot.create :application, scopes: "sample:scope"
581
- app_params = {
582
- application_id: application.id, scopes: "sample:scope",
583
- resource_owner_id: 100,
584
- }
585
- FactoryBot.create :access_token, app_params
586
- empty_scopes = Doorkeeper::OAuth::Scopes.from_string("")
587
- last_token = AccessToken.matching_token_for(application, 100, empty_scopes)
588
- expect(last_token).to be_nil
589
- end
590
-
591
- it "matches token if empty scope requested and no token scopes present" do
592
- empty_scopes = Doorkeeper::OAuth::Scopes.from_string("")
593
- token = FactoryBot.create :access_token, default_attributes.merge(scopes: empty_scopes)
594
- last_token = AccessToken.matching_token_for(application, 100, empty_scopes)
595
- expect(last_token).to eq(token)
596
- end
597
-
598
- it "returns the last matching token" do
599
- FactoryBot.create :access_token, default_attributes.merge(created_at: 1.day.ago)
600
- matching_token = FactoryBot.create :access_token, default_attributes
601
- FactoryBot.create :access_token, default_attributes.merge(scopes: "public")
602
-
603
- last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
604
- expect(last_token).to eq(matching_token)
605
- end
606
- end
607
-
608
- describe "#as_json" do
609
- it "returns as_json hash" do
610
- token = FactoryBot.create :access_token
611
- token_hash = {
612
- resource_owner_id: token.resource_owner_id,
613
- scope: token.scopes,
614
- expires_in: token.expires_in_seconds,
615
- application: { uid: token.application.uid },
616
- created_at: token.created_at.to_i,
617
- }
618
- expect(token.as_json).to eq token_hash
619
- end
620
- end
621
- end
622
- end