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,163 @@
1
+ module Doorkeeper
2
+ module Orm
3
+ module Sequel
4
+ module AccessTokenMixin
5
+ extend ActiveSupport::Concern
6
+
7
+ include SequelCompat
8
+ include OAuth::Helpers
9
+ include Models::Expirable
10
+ include Models::Revocable
11
+ include Models::Accessible
12
+ include Models::Scopes
13
+
14
+ included do
15
+ plugin :validation_helpers
16
+ plugin :timestamps
17
+
18
+ many_to_one :application, class: 'Doorkeeper::Application'
19
+
20
+ attr_writer :use_refresh_token
21
+
22
+ set_allowed_columns :application_id, :resource_owner_id, :expires_in,
23
+ :scopes, :use_refresh_token, :previous_refresh_token
24
+
25
+ def before_validation
26
+ if new?
27
+ generate_token
28
+ generate_refresh_token if use_refresh_token?
29
+ end
30
+
31
+ super
32
+ end
33
+
34
+ def validate
35
+ super
36
+ validates_presence [:token]
37
+ validates_unique [:token]
38
+
39
+ validates_unique [:refresh_token] if use_refresh_token?
40
+ end
41
+
42
+ def application_id?
43
+ application_id.present?
44
+ end
45
+ end
46
+
47
+ module ClassMethods
48
+ def by_token(token)
49
+ find(token: token.to_s)
50
+ end
51
+
52
+ def by_refresh_token(refresh_token)
53
+ find(refresh_token: refresh_token.to_s)
54
+ end
55
+
56
+ def revoke_all_for(application_id, resource_owner)
57
+ where(application_id: application_id,
58
+ resource_owner_id: resource_owner.id,
59
+ revoked_at: nil)
60
+ .each(&:revoke)
61
+ end
62
+
63
+ def matching_token_for(application, resource_owner_or_id, scopes)
64
+ resource_owner_id = if resource_owner_or_id.respond_to?(:to_key)
65
+ resource_owner_or_id.id
66
+ else
67
+ resource_owner_or_id
68
+ end
69
+ token = last_authorized_token_for(application.try(:id), resource_owner_id)
70
+ if token && scopes_match?(token.scopes, scopes, application.try(:scopes))
71
+ token
72
+ end
73
+ end
74
+
75
+ def scopes_match?(token_scopes, param_scopes, app_scopes)
76
+ (!token_scopes.present? && !param_scopes.present?) ||
77
+ Doorkeeper::OAuth::Helpers::ScopeChecker.match?(
78
+ token_scopes.to_s,
79
+ param_scopes,
80
+ app_scopes
81
+ )
82
+ end
83
+
84
+ def find_or_create_for(application, resource_owner_id, scopes, expires_in, use_refresh_token)
85
+ if Doorkeeper.configuration.reuse_access_token
86
+ access_token = matching_token_for(application, resource_owner_id, scopes)
87
+ if access_token && !access_token.expired?
88
+ return access_token
89
+ end
90
+ end
91
+
92
+ create!(
93
+ application_id: application.try(:id),
94
+ resource_owner_id: resource_owner_id,
95
+ scopes: scopes.to_s,
96
+ expires_in: expires_in,
97
+ use_refresh_token: use_refresh_token
98
+ )
99
+ end
100
+
101
+ def last_authorized_token_for(application_id, resource_owner_id)
102
+ where(application_id: application_id,
103
+ resource_owner_id: resource_owner_id,
104
+ revoked_at: nil)
105
+ .send(order_method, created_at_desc)
106
+ .first
107
+ end
108
+ end
109
+
110
+ def token_type
111
+ 'bearer'
112
+ end
113
+
114
+ def use_refresh_token?
115
+ !!@use_refresh_token
116
+ end
117
+
118
+ def as_json(_options = {})
119
+ {
120
+ resource_owner_id: resource_owner_id,
121
+ scopes: scopes,
122
+ expires_in_seconds: expires_in_seconds,
123
+ application: { uid: application.try(:uid) },
124
+ created_at: created_at.to_i
125
+ }
126
+ end
127
+
128
+ # It indicates whether the tokens have the same credential
129
+ def same_credential?(access_token)
130
+ application_id == access_token.application_id &&
131
+ resource_owner_id == access_token.resource_owner_id
132
+ end
133
+
134
+ def acceptable?(scopes)
135
+ accessible? && includes_scope?(*scopes)
136
+ end
137
+
138
+ private
139
+
140
+ def generate_refresh_token
141
+ self[:refresh_token] = UniqueToken.generate
142
+ end
143
+
144
+ def generate_token
145
+ self[:created_at] ||= Time.now.utc
146
+
147
+ generator = Doorkeeper.configuration.access_token_generator.constantize
148
+ self[:token] = generator.generate(
149
+ resource_owner_id: resource_owner_id,
150
+ scopes: scopes,
151
+ application: application,
152
+ expires_in: expires_in,
153
+ created_at: created_at
154
+ )
155
+ rescue NoMethodError
156
+ raise Errors::UnableToGenerateToken, "#{generator} does not respond to `.generate`."
157
+ rescue NameError
158
+ raise Errors::TokenGeneratorNotFound, "#{generator} not found"
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,70 @@
1
+ require_relative '../validators/redirect_uri_validator'
2
+
3
+ module Doorkeeper
4
+ module Orm
5
+ module Sequel
6
+ module ApplicationMixin
7
+ extend ActiveSupport::Concern
8
+
9
+ include SequelCompat
10
+ include OAuth::Helpers
11
+ include Models::Scopes
12
+ include Doorkeeper::Orm::Sequel::RedirectUriValidator
13
+
14
+ included do
15
+ plugin :validation_helpers
16
+ plugin :timestamps
17
+ plugin :association_dependencies
18
+
19
+ one_to_many :access_grants, class: 'Doorkeeper::AccessGrant'
20
+ one_to_many :access_tokens, class: 'Doorkeeper::AccessToken'
21
+
22
+ add_association_dependencies access_grants: :delete, access_tokens: :delete
23
+
24
+ set_allowed_columns :name, :redirect_uri, :scopes
25
+
26
+ def before_validation
27
+ generate_uid
28
+ generate_secret
29
+ super
30
+ end
31
+
32
+ def validate
33
+ super
34
+ validates_presence [:name, :secret, :uid]
35
+ validates_unique [:uid]
36
+ validates_redirect_uri :redirect_uri
37
+
38
+ if respond_to?(:validate_owner?)
39
+ validates_presence [:owner_id] if validate_owner?
40
+ end
41
+ end
42
+ end
43
+
44
+ module ClassMethods
45
+ def by_uid_and_secret(uid, secret)
46
+ find(uid: uid.to_s, secret: secret.to_s)
47
+ end
48
+
49
+ def by_uid(uid)
50
+ find(uid: uid.to_s)
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def has_scopes?
57
+ Doorkeeper::Application.columns.include?('scopes')
58
+ end
59
+
60
+ def generate_uid
61
+ self.uid = UniqueToken.generate if uid.blank? && new?
62
+ end
63
+
64
+ def generate_secret
65
+ self.secret = UniqueToken.generate if secret.blank? && new?
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,19 @@
1
+ module Doorkeeper
2
+ module Orm
3
+ module Sequel
4
+ module Ownership
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ plugin :polymorphic
9
+
10
+ many_to_one :owner, polymorphic: true
11
+
12
+ def validate_owner?
13
+ Doorkeeper.configuration.confirm_application_owner?
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,40 @@
1
+ module Doorkeeper
2
+ module Orm
3
+ module Sequel
4
+ module SequelCompat
5
+ extend ActiveSupport::Concern
6
+
7
+ # ActiveRecord methods used by Doorkeeper outside the ORM.
8
+ # Should be extracted at the architectural level.
9
+ included do
10
+ plugin :active_model
11
+
12
+ self.raise_on_save_failure = false
13
+
14
+ def update_attribute(column, value)
15
+ self[column] = value
16
+ save(columns: [column.to_sym], validate: false)
17
+ end
18
+
19
+ def update_attributes(*args)
20
+ update(*args)
21
+ end
22
+
23
+ def save!(*)
24
+ save(raise_on_failure: true)
25
+ end
26
+
27
+ def transaction(opts = {}, &block)
28
+ db.transaction(opts, &block)
29
+ end
30
+ end
31
+
32
+ module ClassMethods
33
+ def create!(values = {}, &block)
34
+ new(values, &block).save(raise_on_failure: true)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,49 @@
1
+ module Doorkeeper
2
+ module Orm
3
+ module Sequel
4
+ module RedirectUriValidator
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ def validates_redirect_uri(attribute)
9
+ value = self[attribute]
10
+
11
+ if value.blank?
12
+ errors.add(attribute, I18n.t(:blank, scope: redirect_uri_errors))
13
+ else
14
+ value.split.each do |val|
15
+ uri = ::URI.parse(val)
16
+ return true if native_redirect_uri?(uri)
17
+ errors.add(attribute, I18n.t(:fragment_present, scope: redirect_uri_errors)) unless uri.fragment.nil?
18
+ errors.add(attribute, I18n.t(:relative_uri, scope: redirect_uri_errors)) if uri.scheme.nil? || uri.host.nil?
19
+ errors.add(attribute, I18n.t(:secured_uri, scope: redirect_uri_errors)) if invalid_ssl_uri?(uri)
20
+ end
21
+ end
22
+ rescue URI::InvalidURIError
23
+ errors.add(attribute, I18n.t(:invalid_uri, scope: redirect_uri_errors))
24
+ end
25
+
26
+ private
27
+
28
+ def native_redirect_uri?(uri)
29
+ native_redirect_uri.present? && uri.to_s == native_redirect_uri.to_s
30
+ end
31
+
32
+ def invalid_ssl_uri?(uri)
33
+ forces_ssl = Doorkeeper.configuration.force_ssl_in_redirect_uri
34
+ forces_ssl && uri.try(:scheme) == 'http'
35
+ end
36
+
37
+ def native_redirect_uri
38
+ Doorkeeper.configuration.native_redirect_uri
39
+ end
40
+
41
+ # TODO: plugin? Merge to DEFAULT_OPTIONS?
42
+ def redirect_uri_errors
43
+ 'sequel.errors.models.doorkeeper/application.attributes.redirect_uri'
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ module Doorkeeper
2
+ module Orm
3
+ module Sequel
4
+ def self.initialize_models!
5
+ require 'doorkeeper/orm/sequel/models/concerns/sequel_compat'
6
+ require 'doorkeeper/orm/sequel/access_grant'
7
+ require 'doorkeeper/orm/sequel/access_token'
8
+ require 'doorkeeper/orm/sequel/application'
9
+ end
10
+
11
+ def self.initialize_application_owner!
12
+ require 'doorkeeper/orm/sequel/models/concerns/ownership'
13
+
14
+ Doorkeeper::Application.send :include, Doorkeeper::Orm::Sequel::Ownership
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module DoorkeeperSequel
2
+ def self.gem_version
3
+ Gem::Version.new VERSION::STRING
4
+ end
5
+
6
+ module VERSION
7
+ MAJOR = 1
8
+ MINOR = 2
9
+ TINY = 1
10
+
11
+ STRING = [MAJOR, MINOR, TINY].compact.join('.')
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ require_relative 'gem_version'
2
+
3
+ module DoorkeeperSequel
4
+ def self.version
5
+ gem_version
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ require 'doorkeeper-sequel/version'
2
+
3
+ require 'doorkeeper'
4
+
5
+ require 'doorkeeper/orm/sequel'
6
+
7
+ module DoorkeeperSequel
8
+ def load_locales
9
+ locales_dir = File.expand_path('../../config/locales', __FILE__)
10
+ locales = Dir[File.join(locales_dir, '*.yml')]
11
+
12
+ I18n.load_path |= locales
13
+ end
14
+
15
+ module_function :load_locales
16
+ end
17
+
18
+ DoorkeeperSequel.load_locales
@@ -0,0 +1,23 @@
1
+ module Doorkeeper
2
+ module Sequel
3
+ class ApplicationOwnerGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ desc 'Provide support for client application ownership.'
7
+
8
+ def install
9
+ copy_file 'add_owner_to_application.rb', migration_file_name
10
+ end
11
+
12
+ private
13
+
14
+ def migration_file_name
15
+ "db/migrate/#{migration_timestamp}_add_owner_to_application.rb"
16
+ end
17
+
18
+ def migration_timestamp
19
+ Time.current.strftime('%Y%m%d%H%M%S')
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module Doorkeeper
2
+ module Sequel
3
+ class MigrationGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ desc 'Installs Doorkeeper Sequel migration file.'
7
+
8
+ def install
9
+ copy_file 'migration.rb', migration_file_name
10
+ end
11
+
12
+ private
13
+
14
+ def migration_file_name
15
+ "db/migrate/#{migration_timestamp}_create_doorkeeper_tables.rb"
16
+ end
17
+
18
+ def migration_timestamp
19
+ Time.current.strftime('%Y%m%d%H%M%S')
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module Doorkeeper
2
+ module Sequel
3
+ class PreviousRefreshTokenGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ desc 'Support revoke refresh token on access token use'
7
+
8
+ def install
9
+ copy_file 'add_previous_refresh_token_to_access_tokens.rb', migration_file_name
10
+ end
11
+
12
+ private
13
+
14
+ def migration_file_name
15
+ "db/migrate/#{migration_timestamp}_add_previous_refresh_token_to_access_tokens.rb"
16
+ end
17
+
18
+ def migration_timestamp
19
+ Time.current.strftime('%Y%m%d%H%M%S')
20
+ end
21
+ end
22
+ end
23
+ 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,7 @@
1
+ Sequel.migration do
2
+ change do
3
+ alter_table(:oauth_access_tokens) do
4
+ add_column :previous_refresh_token, String, default: '', null: false
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,59 @@
1
+ Sequel.migration do
2
+ change do
3
+ create_table :oauth_applications do
4
+ primary_key :id
5
+
6
+ column :name, String, size: 255, null: false
7
+ column :uid, String, size: 255, null: false, index: { unique: true }
8
+ column :secret, String, size: 255, null: false
9
+
10
+ column :scopes, String, size: 255, null: false, default: ''
11
+ column :redirect_uri, String
12
+
13
+ column :created_at, DateTime
14
+ column :updated_at, DateTime
15
+ end
16
+
17
+ create_table :oauth_access_grants do
18
+ primary_key :id
19
+ foreign_key :application_id, :oauth_applications, null: false, on_delete: :cascade
20
+
21
+ column :resource_owner_id, Integer, null: false
22
+
23
+ column :token, String, size: 255, null: false, index: { unique: true }
24
+ column :expires_in, Integer, null: false
25
+ column :redirect_uri, String, null: false
26
+ column :created_at, DateTime, null: false
27
+ column :revoked_at, DateTime
28
+ column :scopes, String, size: 255
29
+ end
30
+
31
+ create_table :oauth_access_tokens do
32
+ primary_key :id
33
+ foreign_key :application_id, :oauth_applications, null: false, on_delete: :cascade
34
+
35
+ column :resource_owner_id, Integer, index: true
36
+
37
+ # If you use a custom token generator you may need to change this column
38
+ # from string to text, so that it accepts tokens larger than 255
39
+ # characters. More info on custom token generators in:
40
+ # https://github.com/doorkeeper-gem/doorkeeper/tree/v3.0.0.rc1#custom-access-token-generator
41
+ #
42
+ # column :token, String, null: false
43
+ column :token, String, size: 255, null: false, index: { unique: true }
44
+
45
+ column :refresh_token, String, size: 255, index: { unique: true }
46
+ # If there is a previous_refresh_token column,
47
+ # refresh tokens will be revoked after a related access token is used.
48
+ # If there is no previous_refresh_token column,
49
+ # previous tokens are revoked as soon as a new access token is created.
50
+ # Comment out this line if you'd rather have refresh tokens
51
+ # instantly revoked.
52
+ column :previous_refresh_token, String, size: 255, null: false, default: ''
53
+ column :expires_in, Integer
54
+ column :revoked_at, DateTime
55
+ column :created_at, DateTime, null: false
56
+ column :scopes, String, size: 255
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,10 @@
1
+ require "spec_helper_integration"
2
+
3
+ describe Doorkeeper::ApplicationMetalController do
4
+ it "lazy run hooks" do
5
+ i = 0
6
+ ActiveSupport.on_load(:doorkeeper_metal_controller) { i += 1 }
7
+
8
+ expect(i).to eq 1
9
+ end
10
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper_integration'
2
+
3
+ module Doorkeeper
4
+ describe ApplicationsController do
5
+ context 'when admin is not authenticated' do
6
+ before do
7
+ allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(proc do
8
+ redirect_to main_app.root_url
9
+ end)
10
+ end
11
+
12
+ it 'redirects as set in Doorkeeper.authenticate_admin' do
13
+ get :index
14
+ expect(response).to redirect_to(controller.main_app.root_url)
15
+ end
16
+
17
+ it 'does not create application' do
18
+ expect do
19
+ post :create, doorkeeper_application: {
20
+ name: 'Example',
21
+ redirect_uri: 'https://example.com' }
22
+ end.to_not change { Doorkeeper::Application.count }
23
+ end
24
+ end
25
+
26
+ context 'when admin is authenticated' do
27
+ before do
28
+ allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(arg) { true })
29
+ end
30
+
31
+ it 'creates application' do
32
+ expect do
33
+ post :create, doorkeeper_application: {
34
+ name: 'Example',
35
+ redirect_uri: 'https://example.com' }
36
+ end.to change { Doorkeeper::Application.count }.by(1)
37
+ expect(response).to be_redirect
38
+ end
39
+
40
+ it 'does not allow mass assignment of uid or secret' do
41
+ application = FactoryGirl.create(:application)
42
+ put :update, id: application.id, doorkeeper_application: {
43
+ uid: '1A2B3C4D',
44
+ secret: '1A2B3C4D' }
45
+
46
+ expect(application.reload.uid).not_to eq '1A2B3C4D'
47
+ end
48
+
49
+ it 'updates application' do
50
+ application = FactoryGirl.create(:application)
51
+ put :update, id: application.id, doorkeeper_application: {
52
+ name: 'Example',
53
+ redirect_uri: 'https://example.com' }
54
+ expect(application.reload.name).to eq 'Example'
55
+ end
56
+ end
57
+ end
58
+ end