doorkeeper-sequel 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +13 -0
  6. data/.travis.yml +24 -0
  7. data/CHANGELOG.md +24 -0
  8. data/Gemfile +23 -0
  9. data/Gemfile.lock +172 -0
  10. data/LICENSE +21 -0
  11. data/README.md +76 -0
  12. data/Rakefile +56 -0
  13. data/config/locales/en.yml +16 -0
  14. data/doorkeeper-sequel.gemspec +32 -0
  15. data/gemfiles/rails-4.2.gemfile +11 -0
  16. data/gemfiles/rails-5.0.gemfile +11 -0
  17. data/lib/doorkeeper/orm/sequel/access_grant.rb +9 -0
  18. data/lib/doorkeeper/orm/sequel/access_token.rb +32 -0
  19. data/lib/doorkeeper/orm/sequel/application.rb +18 -0
  20. data/lib/doorkeeper/orm/sequel/models/access_grant_mixin.rb +50 -0
  21. data/lib/doorkeeper/orm/sequel/models/access_token_mixin.rb +163 -0
  22. data/lib/doorkeeper/orm/sequel/models/application_mixin.rb +70 -0
  23. data/lib/doorkeeper/orm/sequel/models/concerns/ownership.rb +19 -0
  24. data/lib/doorkeeper/orm/sequel/models/concerns/sequel_compat.rb +40 -0
  25. data/lib/doorkeeper/orm/sequel/validators/redirect_uri_validator.rb +49 -0
  26. data/lib/doorkeeper/orm/sequel.rb +18 -0
  27. data/lib/doorkeeper-sequel/gem_version.rb +13 -0
  28. data/lib/doorkeeper-sequel/version.rb +7 -0
  29. data/lib/doorkeeper-sequel.rb +18 -0
  30. data/lib/generators/doorkeeper/sequel/application_owner_generator.rb +23 -0
  31. data/lib/generators/doorkeeper/sequel/migration_generator.rb +23 -0
  32. data/lib/generators/doorkeeper/sequel/previous_refresh_token_generator.rb +23 -0
  33. data/lib/generators/doorkeeper/sequel/templates/add_owner_to_application.rb +9 -0
  34. data/lib/generators/doorkeeper/sequel/templates/add_previous_refresh_token_to_access_tokens.rb +7 -0
  35. data/lib/generators/doorkeeper/sequel/templates/migration.rb +59 -0
  36. data/spec/controllers/application_metal_controller.rb +10 -0
  37. data/spec/controllers/applications_controller_spec.rb +58 -0
  38. data/spec/controllers/authorizations_controller_spec.rb +189 -0
  39. data/spec/controllers/protected_resources_controller_spec.rb +300 -0
  40. data/spec/controllers/token_info_controller_spec.rb +52 -0
  41. data/spec/controllers/tokens_controller_spec.rb +88 -0
  42. data/spec/dummy/Rakefile +7 -0
  43. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  44. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +7 -0
  45. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +12 -0
  46. data/spec/dummy/app/controllers/home_controller.rb +17 -0
  47. data/spec/dummy/app/controllers/metal_controller.rb +11 -0
  48. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +11 -0
  49. data/spec/dummy/app/helpers/application_helper.rb +5 -0
  50. data/spec/dummy/app/models/user.rb +11 -0
  51. data/spec/dummy/app/views/home/index.html.erb +0 -0
  52. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  53. data/spec/dummy/config/application.rb +29 -0
  54. data/spec/dummy/config/boot.rb +9 -0
  55. data/spec/dummy/config/database.yml +15 -0
  56. data/spec/dummy/config/environment.rb +5 -0
  57. data/spec/dummy/config/environments/development.rb +29 -0
  58. data/spec/dummy/config/environments/production.rb +62 -0
  59. data/spec/dummy/config/environments/test.rb +44 -0
  60. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  61. data/spec/dummy/config/initializers/db.rb +74 -0
  62. data/spec/dummy/config/initializers/doorkeeper.rb +96 -0
  63. data/spec/dummy/config/initializers/secret_token.rb +9 -0
  64. data/spec/dummy/config/initializers/session_store.rb +8 -0
  65. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  66. data/spec/dummy/config/locales/doorkeeper.en.yml +5 -0
  67. data/spec/dummy/config/routes.rb +52 -0
  68. data/spec/dummy/config.ru +4 -0
  69. data/spec/dummy/db/migrate/20111122132257_create_users.rb +9 -0
  70. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +5 -0
  71. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +60 -0
  72. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +7 -0
  73. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +11 -0
  74. data/spec/dummy/db/schema.rb +67 -0
  75. data/spec/dummy/log/test.log +19813 -0
  76. data/spec/dummy/public/404.html +26 -0
  77. data/spec/dummy/public/422.html +26 -0
  78. data/spec/dummy/public/500.html +26 -0
  79. data/spec/dummy/public/favicon.ico +0 -0
  80. data/spec/dummy/script/rails +6 -0
  81. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-T/-TZF6Ae6YipbyKuHghb9wlTx4_b9itbSHRc_2PmqjiU.cache +1 -0
  82. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/0p/0pa3wNbGHqFC6gxrMvdOJiP6gPwFv9VJ_npjEfRWxAE.cache +1 -0
  83. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2e/2eYh115US2lIRhM2KTEaJFa6aV_cX8iv6JAdjuq0Uio.cache +1 -0
  84. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3P/3PoguHEOEeItUjmwC74MWLLP-_Ijow7798bF5U6K2dw.cache +1 -0
  85. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6b/6b0anrSo7Fvoc05t4Ca0zZmfS_cpERy1DsG3ea6lBOg.cache +0 -0
  86. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/BA/BAC3ZaGoeZ9Od-kKg-UQYelvRgsCa0H72-52nLdcTNw.cache +1 -0
  87. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Bw/Bw6Nimjvy5Yv1AYbZb1t-v0eMNhv-bhwBzR-b5mY7FU.cache +0 -0
  88. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Fq/FqQWjMAz8yjZQlMC_dUsztaOxGruI2IXyGAAUF9SvQ0.cache +1 -0
  89. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/J_/J_D9clwKidN28hnVB1O3zEfKDwg90Usdb5ToKiPq_aw.cache +0 -0
  90. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ji/JitNKkP1dYdu9ObSdIkkEAsiFxEmRO5oy1UIyhT_hYs.cache +0 -0
  91. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Jq/JqTLVvnY2AgGkHftWPwqt_HkbwhYRsmgHxk37VqKJAY.cache +0 -0
  92. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QX/QXcp8DweOJ6BfMedGMfeHvVXv2hjDIleln1LSJk7vOE.cache +2 -0
  93. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Qy/Qy1ldbz6vKa_fv4E4ByxWslKFoV1qReQR5DKJ525z88.cache +1 -0
  94. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rl/RlCJ_X5xFsE3VBDhkYrY7r_R6sMgiAc03cT8nr7Q2vY.cache +0 -0
  95. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ta/TaYxNn81MhqC3DnMC6_y_Q7xap5Ntn4ggFo94EUaiak.cache +0 -0
  96. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Wq/WqbLVKOcTMZtttygYt_ncr1mGIDrzevSTaPGNmzV1D8.cache +1 -0
  97. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/YF/YF60qiQ28QMoYDrLmrbHWZr7X7bl5MxVPR5QrrVCFak.cache +1 -0
  98. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Yf/YfJJZvm_NONHd4eCasDibCcRapZ_WYIO5MUxSUUbYFk.cache +0 -0
  99. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Z0/Z0e47cT2a-21U-w-3gkbgqC3o5jWnEzOB8vW06aJH1E.cache +0 -0
  100. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_u/_uy-z8SVnhffUNelRxbPDL2aAUPb_GbqREXVsfy8uGc.cache +0 -0
  101. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/dL/dL7SLUWUIeVdyA1UuH-rvif0nzesOar3LdEtqzdb4bE.cache +0 -0
  102. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/f8/f8WT8jqR1qNIdQaRDpXbyLN7E5AWkbYFBwdh9Ozk7gk.cache +1 -0
  103. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hk/hk2YB6skvc72qL4IzzQKU8Emyfe5vARjoD1bvQTw4zE.cache +1 -0
  104. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/iO/iOpDp_7ZvBNO5WIpTmqNewUl9bB2satqXWulyNvAaX8.cache +0 -0
  105. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ii/iiJRBZIsxKiwyzU_Z7UtQeUTXMRJRPTreTKRvAWO7_8.cache +1 -0
  106. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/mj/mjuMepngMLrtgilLlJ9oTTSqoGO1YUww1rXphQ1pOm4.cache +0 -0
  107. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/qo/qo6SpT75QykYB63Aqq5bgzpXyNU1Y4dGFvCCJgoWQpE.cache +1 -0
  108. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sp/sprzBMBliJDI__s-0D3q82tn1MpBkFV0N651hTr3XE8.cache +1 -0
  109. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/tM/tM6A7CR8QluP_u4u59vN1GjSZGNqNH3TXkkNzb9EPXA.cache +0 -0
  110. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/vO/vOXN0mER62j4JiPpMTSVS7MMqs0067cZx14vD5B8qiQ.cache +0 -0
  111. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zz/zzlQ_kom0liFOvGYDcjtVw6yAHOyA-bbzP8f0e_Tq1A.cache +1 -0
  112. data/spec/factories.rb +28 -0
  113. data/spec/generators/application_owner_generator_spec.rb +20 -0
  114. data/spec/generators/migration_generator_spec.rb +20 -0
  115. data/spec/generators/previous_refresh_token_generator_spec.rb +20 -0
  116. data/spec/generators/templates/routes.rb +3 -0
  117. data/spec/generators/tmp/dummy/db/migrate/20161012132809_create_doorkeeper_tables.rb +59 -0
  118. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +24 -0
  119. data/spec/lib/config_spec.rb +334 -0
  120. data/spec/lib/doorkeeper_spec.rb +28 -0
  121. data/spec/lib/models/expirable_spec.rb +51 -0
  122. data/spec/lib/models/revocable_spec.rb +59 -0
  123. data/spec/lib/models/scopes_spec.rb +43 -0
  124. data/spec/lib/oauth/authorization/uri_builder_spec.rb +42 -0
  125. data/spec/lib/oauth/authorization_code_request_spec.rb +80 -0
  126. data/spec/lib/oauth/client/credentials_spec.rb +47 -0
  127. data/spec/lib/oauth/client/methods_spec.rb +54 -0
  128. data/spec/lib/oauth/client_credentials/creator_spec.rb +44 -0
  129. data/spec/lib/oauth/client_credentials/issuer_spec.rb +86 -0
  130. data/spec/lib/oauth/client_credentials/validation_spec.rb +54 -0
  131. data/spec/lib/oauth/client_credentials_integration_spec.rb +27 -0
  132. data/spec/lib/oauth/client_credentials_request_spec.rb +104 -0
  133. data/spec/lib/oauth/client_spec.rb +39 -0
  134. data/spec/lib/oauth/code_request_spec.rb +45 -0
  135. data/spec/lib/oauth/code_response_spec.rb +34 -0
  136. data/spec/lib/oauth/error_response_spec.rb +61 -0
  137. data/spec/lib/oauth/error_spec.rb +23 -0
  138. data/spec/lib/oauth/forbidden_token_response_spec.rb +23 -0
  139. data/spec/lib/oauth/helpers/scope_checker_spec.rb +64 -0
  140. data/spec/lib/oauth/helpers/unique_token_spec.rb +20 -0
  141. data/spec/lib/oauth/helpers/uri_checker_spec.rb +104 -0
  142. data/spec/lib/oauth/invalid_token_response_spec.rb +28 -0
  143. data/spec/lib/oauth/password_access_token_request_spec.rb +90 -0
  144. data/spec/lib/oauth/pre_authorization_spec.rb +155 -0
  145. data/spec/lib/oauth/refresh_token_request_spec.rb +154 -0
  146. data/spec/lib/oauth/scopes_spec.rb +122 -0
  147. data/spec/lib/oauth/token_request_spec.rb +98 -0
  148. data/spec/lib/oauth/token_response_spec.rb +85 -0
  149. data/spec/lib/oauth/token_spec.rb +116 -0
  150. data/spec/lib/request/strategy_spec.rb +53 -0
  151. data/spec/lib/server_spec.rb +52 -0
  152. data/spec/models/doorkeeper/access_grant_spec.rb +36 -0
  153. data/spec/models/doorkeeper/access_token_spec.rb +394 -0
  154. data/spec/models/doorkeeper/application_spec.rb +179 -0
  155. data/spec/requests/applications/applications_request_spec.rb +94 -0
  156. data/spec/requests/applications/authorized_applications_spec.rb +30 -0
  157. data/spec/requests/endpoints/authorization_spec.rb +72 -0
  158. data/spec/requests/endpoints/token_spec.rb +64 -0
  159. data/spec/requests/flows/authorization_code_errors_spec.rb +66 -0
  160. data/spec/requests/flows/authorization_code_spec.rb +156 -0
  161. data/spec/requests/flows/client_credentials_spec.rb +58 -0
  162. data/spec/requests/flows/implicit_grant_errors_spec.rb +32 -0
  163. data/spec/requests/flows/implicit_grant_spec.rb +61 -0
  164. data/spec/requests/flows/password_spec.rb +115 -0
  165. data/spec/requests/flows/refresh_token_spec.rb +174 -0
  166. data/spec/requests/flows/revoke_token_spec.rb +157 -0
  167. data/spec/requests/flows/skip_authorization_spec.rb +59 -0
  168. data/spec/requests/protected_resources/metal_spec.rb +14 -0
  169. data/spec/requests/protected_resources/private_api_spec.rb +81 -0
  170. data/spec/routing/custom_controller_routes_spec.rb +71 -0
  171. data/spec/routing/default_routes_spec.rb +35 -0
  172. data/spec/routing/scoped_routes_spec.rb +31 -0
  173. data/spec/spec_helper.rb +2 -0
  174. data/spec/spec_helper_integration.rb +50 -0
  175. data/spec/stubs/config/application.rb +29 -0
  176. data/spec/stubs/config/initializers/db.rb +74 -0
  177. data/spec/stubs/generators/application_owner_generator_spec.rb +20 -0
  178. data/spec/stubs/generators/migration_generator_spec.rb +20 -0
  179. data/spec/stubs/generators/previous_refresh_token_generator_spec.rb +20 -0
  180. data/spec/stubs/generators/tmp/dummy/db/migrate/20161012132810_add_owner_to_application.rb +9 -0
  181. data/spec/stubs/models/user.rb +11 -0
  182. data/spec/stubs/spec_helper_integration.rb +50 -0
  183. data/spec/stubs/support/sequel.rb +0 -0
  184. data/spec/support/dependencies/factory_girl.rb +2 -0
  185. data/spec/support/helpers/access_token_request_helper.rb +11 -0
  186. data/spec/support/helpers/authorization_request_helper.rb +41 -0
  187. data/spec/support/helpers/config_helper.rb +9 -0
  188. data/spec/support/helpers/model_helper.rb +67 -0
  189. data/spec/support/helpers/request_spec_helper.rb +76 -0
  190. data/spec/support/helpers/url_helper.rb +55 -0
  191. data/spec/support/http_method_shim.rb +24 -0
  192. data/spec/support/orm/active_record.rb +3 -0
  193. data/spec/support/orm/sequel.rb +0 -0
  194. data/spec/support/shared/controllers_shared_context.rb +69 -0
  195. data/spec/support/shared/models_shared_examples.rb +52 -0
  196. data/spec/validators/redirect_uri_validator_spec.rb +78 -0
  197. metadata +570 -0
@@ -0,0 +1,29 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require "rails"
4
+
5
+ %w(
6
+ action_controller
7
+ action_view
8
+ action_mailer
9
+ active_job
10
+ rails/test_unit
11
+ sprockets
12
+ ).each do |framework|
13
+ begin
14
+ require "#{framework}/railtie"
15
+ rescue LoadError
16
+ end
17
+ end
18
+
19
+ Bundler.require(*Rails.groups)
20
+
21
+ require 'yaml'
22
+
23
+ module Dummy
24
+ class Application < Rails::Application
25
+ # Settings in config/environments/* take precedence over those specified here.
26
+ # Application configuration should go into files in config/initializers
27
+ # -- all .rb files in that directory are automatically loaded.
28
+ end
29
+ end
@@ -0,0 +1,74 @@
1
+ # SQLite memory database
2
+ DB = if defined?(JRUBY_VERSION)
3
+ Sequel.connect('jdbc:sqlite::memory:')
4
+ else
5
+ Sequel.sqlite
6
+ end
7
+
8
+ DB.create_table :oauth_applications do
9
+ primary_key :id
10
+
11
+ column :name, String, size: 255, null: false
12
+ column :uid, String, size: 255, null: false, index: { unique: true }
13
+ column :secret, String, size: 255, null: false
14
+
15
+ column :scopes, String, size: 255, null: false, default: ''
16
+ column :redirect_uri, String
17
+
18
+ column :created_at, DateTime
19
+ column :updated_at, DateTime
20
+
21
+ column :owner_id, Integer
22
+ column :owner_type, String
23
+ index [:owner_id, :owner_type]
24
+ end
25
+
26
+ DB.create_table :oauth_access_grants do
27
+ primary_key :id
28
+ column :application_id, Integer
29
+
30
+ column :resource_owner_id, Integer, null: false
31
+
32
+ column :token, String, size: 255, null: false, index: { unique: true }
33
+ column :expires_in, Integer, null: false
34
+ column :redirect_uri, String, null: false
35
+ column :created_at, DateTime, null: false
36
+ column :revoked_at, DateTime
37
+ column :scopes, String, size: 255
38
+ end
39
+
40
+ DB.create_table :oauth_access_tokens do
41
+ primary_key :id
42
+ column :application_id, Integer
43
+
44
+ column :resource_owner_id, Integer, index: true
45
+
46
+ # If you use a custom token generator you may need to change this column
47
+ # from string to text, so that it accepts tokens larger than 255
48
+ # characters. More info on custom token generators in:
49
+ # https://github.com/doorkeeper-gem/doorkeeper/tree/v3.0.0.rc1#custom-access-token-generator
50
+ #
51
+ # column :token, String, null: false
52
+ column :token, String, size: 255, null: false, index: { unique: true }
53
+
54
+ column :refresh_token, String, size: 255, index: { unique: true }
55
+ # If there is a previous_refresh_token column,
56
+ # refresh tokens will be revoked after a related access token is used.
57
+ # If there is no previous_refresh_token column,
58
+ # previous tokens are revoked as soon as a new access token is created.
59
+ # Comment out this line if you'd rather have refresh tokens
60
+ # instantly revoked.
61
+ column :previous_refresh_token, String, size: 255, null: false, default: ''
62
+ column :expires_in, Integer
63
+ column :revoked_at, DateTime
64
+ column :created_at, DateTime, null: false
65
+ column :scopes, String, size: 255
66
+ end
67
+
68
+ DB.create_table :users do
69
+ primary_key :id
70
+ column :name, String, size: 255
71
+ column :created_at, DateTime
72
+ column :updated_at, DateTime
73
+ column :password, String, size: 255
74
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper_integration'
2
+ require 'generators/doorkeeper/sequel/application_owner_generator'
3
+
4
+ describe 'Doorkeeper::Sequel::ApplicationOwnerGenerator' do
5
+ include GeneratorSpec::TestCase
6
+
7
+ tests Doorkeeper::Sequel::ApplicationOwnerGenerator
8
+ destination ::File.expand_path('../tmp/dummy', __FILE__)
9
+
10
+ describe 'after running the generator' do
11
+ before :each do
12
+ prepare_destination
13
+ run_generator
14
+ end
15
+
16
+ it 'creates a migration' do
17
+ assert_migration 'db/migrate/add_owner_to_application.rb'
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper_integration'
2
+ require 'generators/doorkeeper/sequel/migration_generator'
3
+
4
+ describe 'Doorkeeper::Sequel::MigrationGenerator' do
5
+ include GeneratorSpec::TestCase
6
+
7
+ tests Doorkeeper::Sequel::MigrationGenerator
8
+ destination ::File.expand_path('../tmp/dummy', __FILE__)
9
+
10
+ describe 'after running the generator' do
11
+ before :each do
12
+ prepare_destination
13
+ run_generator
14
+ end
15
+
16
+ it 'creates a migration' do
17
+ assert_migration 'db/migrate/create_doorkeeper_tables.rb'
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper_integration'
2
+ require 'generators/doorkeeper/sequel/previous_refresh_token_generator'
3
+
4
+ describe 'Doorkeeper::Sequel::PreviousRefreshTokenGenerator' do
5
+ include GeneratorSpec::TestCase
6
+
7
+ tests Doorkeeper::Sequel::PreviousRefreshTokenGenerator
8
+ destination ::File.expand_path('../tmp/dummy', __FILE__)
9
+
10
+ describe 'after running the generator' do
11
+ before :each do
12
+ prepare_destination
13
+ run_generator
14
+ end
15
+
16
+ it 'creates a migration' do
17
+ assert_migration 'db/migrate/add_previous_refresh_token_to_access_tokens.rb'
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ Sequel.migration do
2
+ change do
3
+ alter_table(:oauth_applications) do
4
+ add_column :owner_id, Integer, null: true
5
+ add_column :owner_type, String, null: true
6
+ add_index [:owner_id, :owner_type]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class User < Sequel::Model
2
+ class << self
3
+ def authenticate!(name, password)
4
+ User.where(name: name, password: password).first
5
+ end
6
+
7
+ def create!(values = {}, &block)
8
+ new(values, &block).save(raise_on_failure: true)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,50 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ DOORKEEPER_ORM = :sequel
4
+
5
+ $LOAD_PATH.unshift File.dirname(__FILE__)
6
+
7
+ require 'capybara/rspec'
8
+ require 'dummy/config/environment'
9
+ require 'rspec/rails'
10
+ require 'generator_spec/test_case'
11
+ require 'timecop'
12
+
13
+ # Load JRuby SQLite3 if in that platform
14
+ begin
15
+ require 'jdbc/sqlite3'
16
+ Jdbc::SQLite3.load_driver
17
+ rescue LoadError
18
+ end
19
+
20
+ Rails.logger.info "====> Doorkeeper.orm = #{Doorkeeper.configuration.orm.inspect}"
21
+ Rails.logger.info "====> Rails version: #{Rails.version}"
22
+ Rails.logger.info "====> Ruby version: #{RUBY_VERSION}"
23
+
24
+ require "support/orm/#{DOORKEEPER_ORM}"
25
+
26
+ ENGINE_RAILS_ROOT = File.join(File.dirname(__FILE__), '../')
27
+
28
+ Dir["#{File.dirname(__FILE__)}/support/{dependencies,helpers,shared}/*.rb"].each { |f| require f }
29
+
30
+ # Remove after dropping support of Rails 4.2
31
+ require "#{File.dirname(__FILE__)}/support/http_method_shim.rb"
32
+
33
+ RSpec.configure do |config|
34
+ config.infer_spec_type_from_file_location!
35
+ config.mock_with :rspec
36
+
37
+ config.infer_base_class_for_anonymous_controllers = false
38
+
39
+ config.include RSpec::Rails::RequestExampleGroup, type: :request
40
+
41
+ config.before do
42
+ Doorkeeper.configure { orm DOORKEEPER_ORM }
43
+ end
44
+
45
+ config.around(:each) do |example|
46
+ DB.transaction(rollback: :always, auto_savepoint: true) { example.run }
47
+ end
48
+
49
+ config.order = 'random'
50
+ end
File without changes
@@ -0,0 +1,2 @@
1
+ require 'factory_girl'
2
+ FactoryGirl.find_definitions
@@ -0,0 +1,11 @@
1
+ module AccessTokenRequestHelper
2
+ def client_is_authorized(client, resource_owner, access_token_attributes = {})
3
+ attributes = {
4
+ application: client,
5
+ resource_owner_id: resource_owner.id
6
+ }.merge(access_token_attributes)
7
+ FactoryGirl.create(:access_token, attributes)
8
+ end
9
+ end
10
+
11
+ RSpec.configuration.send :include, AccessTokenRequestHelper
@@ -0,0 +1,41 @@
1
+ module AuthorizationRequestHelper
2
+ def resource_owner_is_authenticated(resource_owner = nil)
3
+ resource_owner ||= User.create!(name: 'Joe', password: 'sekret')
4
+ Doorkeeper.configuration.instance_variable_set(:@authenticate_resource_owner, proc { resource_owner })
5
+ end
6
+
7
+ def resource_owner_is_not_authenticated
8
+ Doorkeeper.configuration.instance_variable_set(:@authenticate_resource_owner, proc { redirect_to('/sign_in') })
9
+ end
10
+
11
+ def default_scopes_exist(*scopes)
12
+ Doorkeeper.configuration.instance_variable_set(:@default_scopes, Doorkeeper::OAuth::Scopes.from_array(scopes))
13
+ end
14
+
15
+ def optional_scopes_exist(*scopes)
16
+ Doorkeeper.configuration.instance_variable_set(:@optional_scopes, Doorkeeper::OAuth::Scopes.from_array(scopes))
17
+ end
18
+
19
+ def client_should_be_authorized(client)
20
+ expect(client.access_grants.size).to eq(1)
21
+ end
22
+
23
+ def client_should_not_be_authorized(client)
24
+ expect(client.size).to eq(0)
25
+ end
26
+
27
+ def i_should_be_on_client_callback(client)
28
+ expect(client.redirect_uri).to eq("#{current_uri.scheme}://#{current_uri.host}#{current_uri.path}")
29
+ end
30
+
31
+ def allowing_forgery_protection(&block)
32
+ _original_value = ActionController::Base.allow_forgery_protection
33
+ ActionController::Base.allow_forgery_protection = true
34
+
35
+ block.call
36
+ ensure
37
+ ActionController::Base.allow_forgery_protection = _original_value
38
+ end
39
+ end
40
+
41
+ RSpec.configuration.send :include, AuthorizationRequestHelper
@@ -0,0 +1,9 @@
1
+ module ConfigHelper
2
+ def config_is_set(setting, value = nil, &block)
3
+ setting_ivar = "@#{setting}"
4
+ value = block_given? ? block : value
5
+ Doorkeeper.configuration.instance_variable_set(setting_ivar, value)
6
+ end
7
+ end
8
+
9
+ RSpec.configuration.send :include, ConfigHelper
@@ -0,0 +1,67 @@
1
+ module ModelHelper
2
+ def client_exists(client_attributes = {})
3
+ @client = FactoryGirl.create(:application, client_attributes)
4
+ end
5
+
6
+ def create_resource_owner
7
+ @resource_owner = User.create!(name: 'Joe', password: 'sekret')
8
+ end
9
+
10
+ def authorization_code_exists(options = {})
11
+ @authorization = FactoryGirl.create(:access_grant, options)
12
+ end
13
+
14
+ def access_grant_should_exist_for(client, resource_owner)
15
+ grant = Doorkeeper::AccessGrant.first
16
+
17
+ expect(grant.application).to have_attributes(id: client.id).
18
+ and(be_instance_of(Doorkeeper::Application))
19
+
20
+ expect(grant.resource_owner_id).to eq(resource_owner.id)
21
+ end
22
+
23
+ def access_token_should_exist_for(client, resource_owner)
24
+ token = Doorkeeper::AccessToken.first
25
+
26
+ expect(token.application).to have_attributes(id: client.id).
27
+ and(be_instance_of(Doorkeeper::Application))
28
+
29
+ expect(token.resource_owner_id).to eq(resource_owner.id)
30
+ end
31
+
32
+ def access_grant_should_not_exist
33
+ expect(Doorkeeper::AccessGrant.all).to be_empty
34
+ end
35
+
36
+ def access_token_should_not_exist
37
+ expect(Doorkeeper::AccessToken.all).to be_empty
38
+ end
39
+
40
+ def access_grant_should_have_scopes(*args)
41
+ grant = Doorkeeper::AccessGrant.first
42
+ expect(grant.scopes).to eq(Doorkeeper::OAuth::Scopes.from_array(args))
43
+ end
44
+
45
+ def access_token_should_have_scopes(*args)
46
+ grant = Doorkeeper::AccessToken.last
47
+ expect(grant.scopes).to eq(Doorkeeper::OAuth::Scopes.from_array(args))
48
+ end
49
+
50
+ def uniqueness_error
51
+ case DOORKEEPER_ORM
52
+ when :active_record
53
+ ActiveRecord::RecordNotUnique
54
+ when :sequel
55
+ error_classes = [Sequel::UniqueConstraintViolation, Sequel::ValidationFailed]
56
+ proc { |error| expect(error.class).to be_in(error_classes) }
57
+ when :mongo_mapper
58
+ MongoMapper::DocumentNotValid
59
+ when /mongoid/
60
+ Mongoid::Errors::Validations
61
+ else
62
+ raise "'#{DOORKEEPER_ORM}' ORM is not supported!"
63
+ end
64
+ end
65
+ end
66
+
67
+ RSpec.configuration.send :include, ModelHelper
@@ -0,0 +1,76 @@
1
+ module RequestSpecHelper
2
+ def i_should_see(content)
3
+ expect(page).to have_content(content)
4
+ end
5
+
6
+ def i_should_not_see(content)
7
+ expect(page).to have_no_content(content)
8
+ end
9
+
10
+ def i_should_be_on(path)
11
+ expect(current_path).to eq(path)
12
+ end
13
+
14
+ def url_should_have_param(param, value)
15
+ expect(current_params[param]).to eq(value)
16
+ end
17
+
18
+ def url_should_not_have_param(param)
19
+ expect(current_params).not_to have_key(param)
20
+ end
21
+
22
+ def current_params
23
+ Rack::Utils.parse_query(current_uri.query)
24
+ end
25
+
26
+ def current_uri
27
+ URI.parse(page.current_url)
28
+ end
29
+
30
+ def should_have_header(header, value)
31
+ expect(headers[header]).to eq(value)
32
+ end
33
+
34
+ def with_access_token_header(token)
35
+ with_header 'Authorization', "Bearer #{token}"
36
+ end
37
+
38
+ def with_header(header, value)
39
+ page.driver.header header, value
40
+ end
41
+
42
+ def basic_auth_header_for_client(client)
43
+ ActionController::HttpAuthentication::Basic.encode_credentials client.uid, client.secret
44
+ end
45
+
46
+ def should_have_json(key, value)
47
+ expect(JSON.parse(response.body).fetch(key)).to eq(value)
48
+ end
49
+
50
+ def should_have_json_within(key, value, range)
51
+ expect(JSON.parse(response.body).fetch(key)).to be_within(range).of(value)
52
+ end
53
+
54
+ def should_not_have_json(key)
55
+ expect(JSON.parse(response.body)).not_to have_key(key)
56
+ end
57
+
58
+ def sign_in
59
+ visit '/'
60
+ click_on 'Sign in'
61
+ end
62
+
63
+ def i_should_see_translated_error_message(key)
64
+ i_should_see translated_error_message(key)
65
+ end
66
+
67
+ def translated_error_message(key)
68
+ I18n.translate key, scope: [:doorkeeper, :errors, :messages]
69
+ end
70
+
71
+ def response_status_should_be(status)
72
+ expect(page.driver.response.status.to_i).to eq(status)
73
+ end
74
+ end
75
+
76
+ RSpec.configuration.send :include, RequestSpecHelper
@@ -0,0 +1,55 @@
1
+ module UrlHelper
2
+ def token_endpoint_url(options = {})
3
+ parameters = {
4
+ code: options[:code],
5
+ client_id: options[:client_id] || (options[:client] ? options[:client].uid : nil),
6
+ client_secret: options[:client_secret] || (options[:client] ? options[:client].secret : nil),
7
+ redirect_uri: options[:redirect_uri] || (options[:client] ? options[:client].redirect_uri : nil),
8
+ grant_type: options[:grant_type] || 'authorization_code'
9
+ }
10
+ "/oauth/token?#{build_query(parameters)}"
11
+ end
12
+
13
+ def password_token_endpoint_url(options = {})
14
+ parameters = {
15
+ code: options[:code],
16
+ client_id: options[:client_id] || (options[:client] ? options[:client].uid : nil),
17
+ client_secret: options[:client_secret] || (options[:client] ? options[:client].secret : nil),
18
+ username: options[:resource_owner_username] || (options[:resource_owner] ? options[:resource_owner].name : nil),
19
+ password: options[:resource_owner_password] || (options[:resource_owner] ? options[:resource_owner].password : nil),
20
+ grant_type: 'password'
21
+ }
22
+ "/oauth/token?#{build_query(parameters)}"
23
+ end
24
+
25
+ def authorization_endpoint_url(options = {})
26
+ parameters = {
27
+ client_id: options[:client_id] || options[:client].uid,
28
+ redirect_uri: options[:redirect_uri] || options[:client].redirect_uri,
29
+ response_type: options[:response_type] || 'code',
30
+ scope: options[:scope],
31
+ state: options[:state]
32
+ }.reject { |k, v| v.blank? }
33
+ "/oauth/authorize?#{build_query(parameters)}"
34
+ end
35
+
36
+ def refresh_token_endpoint_url(options = {})
37
+ parameters = {
38
+ refresh_token: options[:refresh_token],
39
+ client_id: options[:client_id] || options[:client].uid,
40
+ client_secret: options[:client_secret] || options[:client].secret,
41
+ grant_type: options[:grant_type] || 'refresh_token'
42
+ }
43
+ "/oauth/token?#{build_query(parameters)}"
44
+ end
45
+
46
+ def revocation_token_endpoint_url
47
+ '/oauth/revoke'
48
+ end
49
+
50
+ def build_query(hash)
51
+ Rack::Utils.build_query(hash)
52
+ end
53
+ end
54
+
55
+ RSpec.configuration.send :include, UrlHelper
@@ -0,0 +1,24 @@
1
+ # Rails 5 deprecates calling HTTP action methods with positional arguments
2
+ # in favor of keyword arguments. However, the keyword argument form is only
3
+ # supported in Rails 5+. Since we support back to 4, we need some sort of shim
4
+ # to avoid super noisy deprecations when running tests.
5
+ module HTTPMethodShim
6
+ def get(path, params = nil, headers = nil)
7
+ super(path, params: params, headers: headers)
8
+ end
9
+
10
+ def post(path, params = nil, headers = nil)
11
+ super(path, params: params, headers: headers)
12
+ end
13
+
14
+ def put(path, params = nil, headers = nil)
15
+ super(path, params: params, headers: headers)
16
+ end
17
+ end
18
+
19
+ if ::Rails::VERSION::MAJOR >= 5
20
+ RSpec.configure do |config|
21
+ config.include HTTPMethodShim, type: :controller
22
+ config.include HTTPMethodShim, type: :request
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ # load schema to in memory sqlite
2
+ ActiveRecord::Migration.verbose = false
3
+ load Rails.root + 'db/schema.rb'
File without changes
@@ -0,0 +1,69 @@
1
+ shared_context 'valid token', token: :valid do
2
+ let :token_string do
3
+ '1A2B3C4D'
4
+ end
5
+
6
+ let :token do
7
+ double(Doorkeeper::AccessToken,
8
+ accessible?: true, includes_scope?: true, acceptable?: true,
9
+ previous_refresh_token: "", revoke_previous_refresh_token!: true)
10
+ end
11
+
12
+ before :each do
13
+ allow(
14
+ Doorkeeper::AccessToken
15
+ ).to receive(:by_token).with(token_string).and_return(token)
16
+ end
17
+ end
18
+
19
+ shared_context 'invalid token', token: :invalid do
20
+ let :token_string do
21
+ '1A2B3C4D'
22
+ end
23
+
24
+ let :token do
25
+ double(Doorkeeper::AccessToken,
26
+ accessible?: false, revoked?: false, expired?: false,
27
+ includes_scope?: false, acceptable?: false,
28
+ previous_refresh_token: "", revoke_previous_refresh_token!: true)
29
+ end
30
+
31
+ before :each do
32
+ allow(
33
+ Doorkeeper::AccessToken
34
+ ).to receive(:by_token).with(token_string).and_return(token)
35
+ end
36
+ end
37
+
38
+ shared_context 'authenticated resource owner' do
39
+ before do
40
+ user = double(:resource, id: 1)
41
+ allow(Doorkeeper.configuration).to receive(:authenticate_resource_owner) { proc { user } }
42
+ end
43
+ end
44
+
45
+ shared_context 'not authenticated resource owner' do
46
+ before do
47
+ allow(Doorkeeper.configuration).to receive(:authenticate_resource_owner) { proc { redirect_to '/' } }
48
+ end
49
+ end
50
+
51
+ shared_context 'valid authorization request' do
52
+ let :authorization do
53
+ double(:authorization, valid?: true, authorize: true, success_redirect_uri: 'http://something.com/cb?code=token')
54
+ end
55
+
56
+ before do
57
+ allow(controller).to receive(:authorization) { authorization }
58
+ end
59
+ end
60
+
61
+ shared_context 'invalid authorization request' do
62
+ let :authorization do
63
+ double(:authorization, valid?: false, authorize: false, redirect_on_error?: false)
64
+ end
65
+
66
+ before do
67
+ allow(controller).to receive(:authorization) { authorization }
68
+ end
69
+ end
@@ -0,0 +1,52 @@
1
+ shared_examples 'an accessible token' do
2
+ describe :accessible? do
3
+ it 'is accessible if token is not expired' do
4
+ allow(subject).to receive(:expired?).and_return(false)
5
+ should be_accessible
6
+ end
7
+
8
+ it 'is not accessible if token is expired' do
9
+ allow(subject).to receive(:expired?).and_return(true)
10
+ should_not be_accessible
11
+ end
12
+ end
13
+ end
14
+
15
+ shared_examples 'a revocable token' do
16
+ describe :accessible? do
17
+ before { subject.save! }
18
+
19
+ it 'is accessible if token is not revoked' do
20
+ expect(subject).to be_accessible
21
+ end
22
+
23
+ it 'is not accessible if token is revoked' do
24
+ subject.revoke
25
+ expect(subject).not_to be_accessible
26
+ end
27
+ end
28
+ end
29
+
30
+ shared_examples 'a unique token' do
31
+ describe :token do
32
+ it 'is generated before validation' do
33
+ expect { subject.valid? }.to change { subject.token }.from(nil)
34
+ end
35
+
36
+ it 'is not valid if token exists' do
37
+ token1 = FactoryGirl.create factory_name
38
+ token2 = FactoryGirl.create factory_name
39
+ token2.token = token1.token
40
+ expect(token2).not_to be_valid
41
+ end
42
+
43
+ it 'expects database to throw an error when tokens are the same' do
44
+ token1 = FactoryGirl.create factory_name
45
+ token2 = FactoryGirl.create factory_name
46
+ token2.token = token1.token
47
+ expect do
48
+ token2.save!(validate: false)
49
+ end.to raise_error(uniqueness_error)
50
+ end
51
+ end
52
+ end