super-smart-kit 0.0.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 (149) hide show
  1. checksums.yaml +7 -0
  2. data/doorkeeper-5.9.3/CHANGELOG.md +1208 -0
  3. data/doorkeeper-5.9.3/MIT-LICENSE +20 -0
  4. data/doorkeeper-5.9.3/README.md +186 -0
  5. data/doorkeeper-5.9.3/app/assets/stylesheets/doorkeeper/admin/application.css +10 -0
  6. data/doorkeeper-5.9.3/app/assets/stylesheets/doorkeeper/application.css +64 -0
  7. data/doorkeeper-5.9.3/app/controllers/doorkeeper/application_controller.rb +14 -0
  8. data/doorkeeper-5.9.3/app/controllers/doorkeeper/application_metal_controller.rb +13 -0
  9. data/doorkeeper-5.9.3/app/controllers/doorkeeper/applications_controller.rb +99 -0
  10. data/doorkeeper-5.9.3/app/controllers/doorkeeper/authorizations_controller.rb +164 -0
  11. data/doorkeeper-5.9.3/app/controllers/doorkeeper/authorized_applications_controller.rb +33 -0
  12. data/doorkeeper-5.9.3/app/controllers/doorkeeper/token_info_controller.rb +25 -0
  13. data/doorkeeper-5.9.3/app/controllers/doorkeeper/tokens_controller.rb +180 -0
  14. data/doorkeeper-5.9.3/app/helpers/doorkeeper/dashboard_helper.rb +21 -0
  15. data/doorkeeper-5.9.3/app/views/doorkeeper/applications/_delete_form.html.erb +6 -0
  16. data/doorkeeper-5.9.3/app/views/doorkeeper/applications/_form.html.erb +59 -0
  17. data/doorkeeper-5.9.3/app/views/doorkeeper/applications/edit.html.erb +5 -0
  18. data/doorkeeper-5.9.3/app/views/doorkeeper/applications/index.html.erb +38 -0
  19. data/doorkeeper-5.9.3/app/views/doorkeeper/applications/new.html.erb +5 -0
  20. data/doorkeeper-5.9.3/app/views/doorkeeper/applications/show.html.erb +63 -0
  21. data/doorkeeper-5.9.3/app/views/doorkeeper/authorizations/error.html.erb +9 -0
  22. data/doorkeeper-5.9.3/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
  23. data/doorkeeper-5.9.3/app/views/doorkeeper/authorizations/new.html.erb +46 -0
  24. data/doorkeeper-5.9.3/app/views/doorkeeper/authorizations/show.html.erb +7 -0
  25. data/doorkeeper-5.9.3/app/views/doorkeeper/authorized_applications/_delete_form.html.erb +4 -0
  26. data/doorkeeper-5.9.3/app/views/doorkeeper/authorized_applications/index.html.erb +24 -0
  27. data/doorkeeper-5.9.3/app/views/layouts/doorkeeper/admin.html.erb +39 -0
  28. data/doorkeeper-5.9.3/app/views/layouts/doorkeeper/application.html.erb +23 -0
  29. data/doorkeeper-5.9.3/config/locales/en.yml +155 -0
  30. data/doorkeeper-5.9.3/lib/doorkeeper/config/abstract_builder.rb +28 -0
  31. data/doorkeeper-5.9.3/lib/doorkeeper/config/option.rb +82 -0
  32. data/doorkeeper-5.9.3/lib/doorkeeper/config/validations.rb +65 -0
  33. data/doorkeeper-5.9.3/lib/doorkeeper/config.rb +721 -0
  34. data/doorkeeper-5.9.3/lib/doorkeeper/engine.rb +38 -0
  35. data/doorkeeper-5.9.3/lib/doorkeeper/errors.rb +85 -0
  36. data/doorkeeper-5.9.3/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  37. data/doorkeeper-5.9.3/lib/doorkeeper/grant_flow/flow.rb +44 -0
  38. data/doorkeeper-5.9.3/lib/doorkeeper/grant_flow/registry.rb +50 -0
  39. data/doorkeeper-5.9.3/lib/doorkeeper/grant_flow.rb +45 -0
  40. data/doorkeeper-5.9.3/lib/doorkeeper/grape/authorization_decorator.rb +19 -0
  41. data/doorkeeper-5.9.3/lib/doorkeeper/grape/helpers.rb +58 -0
  42. data/doorkeeper-5.9.3/lib/doorkeeper/helpers/controller.rb +91 -0
  43. data/doorkeeper-5.9.3/lib/doorkeeper/models/access_grant_mixin.rb +124 -0
  44. data/doorkeeper-5.9.3/lib/doorkeeper/models/access_token_mixin.rb +526 -0
  45. data/doorkeeper-5.9.3/lib/doorkeeper/models/application_mixin.rb +96 -0
  46. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/accessible.rb +15 -0
  47. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/expirable.rb +36 -0
  48. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +96 -0
  49. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/orderable.rb +15 -0
  50. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/ownership.rb +18 -0
  51. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb +29 -0
  52. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  53. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/reusable.rb +19 -0
  54. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/revocable.rb +31 -0
  55. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/scopes.rb +27 -0
  56. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/secret_storable.rb +106 -0
  57. data/doorkeeper-5.9.3/lib/doorkeeper/models/concerns/write_to_primary.rb +57 -0
  58. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/authorization/code.rb +76 -0
  59. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/authorization/context.rb +17 -0
  60. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/authorization/token.rb +100 -0
  61. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/authorization/uri_builder.rb +33 -0
  62. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/authorization_code_request.rb +125 -0
  63. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/base_request.rb +68 -0
  64. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/base_response.rb +31 -0
  65. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/client/credentials.rb +34 -0
  66. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/client.rb +28 -0
  67. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/client_credentials/creator.rb +57 -0
  68. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/client_credentials/issuer.rb +48 -0
  69. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/client_credentials/validator.rb +55 -0
  70. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/client_credentials_request.rb +46 -0
  71. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/code_request.rb +25 -0
  72. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/code_response.rb +51 -0
  73. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/error.rb +16 -0
  74. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/error_response.rb +121 -0
  75. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/forbidden_token_response.rb +31 -0
  76. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/helpers/scope_checker.rb +50 -0
  77. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/helpers/unique_token.rb +30 -0
  78. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/helpers/uri_checker.rb +83 -0
  79. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  80. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/invalid_request_response.rb +47 -0
  81. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/invalid_token_response.rb +54 -0
  82. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  83. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/password_access_token_request.rb +75 -0
  84. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/pre_authorization.rb +187 -0
  85. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/refresh_token_request.rb +144 -0
  86. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/scopes.rb +134 -0
  87. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/token.rb +66 -0
  88. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/token_introspection.rb +220 -0
  89. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/token_request.rb +25 -0
  90. data/doorkeeper-5.9.3/lib/doorkeeper/oauth/token_response.rb +38 -0
  91. data/doorkeeper-5.9.3/lib/doorkeeper/oauth.rb +13 -0
  92. data/doorkeeper-5.9.3/lib/doorkeeper/orm/active_record/access_grant.rb +9 -0
  93. data/doorkeeper-5.9.3/lib/doorkeeper/orm/active_record/access_token.rb +9 -0
  94. data/doorkeeper-5.9.3/lib/doorkeeper/orm/active_record/application.rb +10 -0
  95. data/doorkeeper-5.9.3/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +64 -0
  96. data/doorkeeper-5.9.3/lib/doorkeeper/orm/active_record/mixins/access_token.rb +95 -0
  97. data/doorkeeper-5.9.3/lib/doorkeeper/orm/active_record/mixins/application.rb +223 -0
  98. data/doorkeeper-5.9.3/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
  99. data/doorkeeper-5.9.3/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +44 -0
  100. data/doorkeeper-5.9.3/lib/doorkeeper/orm/active_record.rb +41 -0
  101. data/doorkeeper-5.9.3/lib/doorkeeper/rails/helpers.rb +82 -0
  102. data/doorkeeper-5.9.3/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  103. data/doorkeeper-5.9.3/lib/doorkeeper/rails/routes/mapper.rb +30 -0
  104. data/doorkeeper-5.9.3/lib/doorkeeper/rails/routes/mapping.rb +40 -0
  105. data/doorkeeper-5.9.3/lib/doorkeeper/rails/routes/registry.rb +45 -0
  106. data/doorkeeper-5.9.3/lib/doorkeeper/rails/routes.rb +110 -0
  107. data/doorkeeper-5.9.3/lib/doorkeeper/rake/db.rake +40 -0
  108. data/doorkeeper-5.9.3/lib/doorkeeper/rake/setup.rake +6 -0
  109. data/doorkeeper-5.9.3/lib/doorkeeper/rake.rb +14 -0
  110. data/doorkeeper-5.9.3/lib/doorkeeper/request/authorization_code.rb +26 -0
  111. data/doorkeeper-5.9.3/lib/doorkeeper/request/client_credentials.rb +17 -0
  112. data/doorkeeper-5.9.3/lib/doorkeeper/request/code.rb +17 -0
  113. data/doorkeeper-5.9.3/lib/doorkeeper/request/password.rb +19 -0
  114. data/doorkeeper-5.9.3/lib/doorkeeper/request/refresh_token.rb +22 -0
  115. data/doorkeeper-5.9.3/lib/doorkeeper/request/strategy.rb +19 -0
  116. data/doorkeeper-5.9.3/lib/doorkeeper/request/token.rb +17 -0
  117. data/doorkeeper-5.9.3/lib/doorkeeper/request.rb +73 -0
  118. data/doorkeeper-5.9.3/lib/doorkeeper/revocable_tokens/revocable_access_token.rb +21 -0
  119. data/doorkeeper-5.9.3/lib/doorkeeper/revocable_tokens/revocable_refresh_token.rb +21 -0
  120. data/doorkeeper-5.9.3/lib/doorkeeper/secret_storing/base.rb +64 -0
  121. data/doorkeeper-5.9.3/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
  122. data/doorkeeper-5.9.3/lib/doorkeeper/secret_storing/plain.rb +33 -0
  123. data/doorkeeper-5.9.3/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
  124. data/doorkeeper-5.9.3/lib/doorkeeper/server.rb +44 -0
  125. data/doorkeeper-5.9.3/lib/doorkeeper/stale_records_cleaner.rb +24 -0
  126. data/doorkeeper-5.9.3/lib/doorkeeper/validations.rb +33 -0
  127. data/doorkeeper-5.9.3/lib/doorkeeper/version.rb +14 -0
  128. data/doorkeeper-5.9.3/lib/doorkeeper.rb +209 -0
  129. data/doorkeeper-5.9.3/lib/generators/doorkeeper/application_owner_generator.rb +33 -0
  130. data/doorkeeper-5.9.3/lib/generators/doorkeeper/confidential_applications_generator.rb +33 -0
  131. data/doorkeeper-5.9.3/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  132. data/doorkeeper-5.9.3/lib/generators/doorkeeper/install_generator.rb +22 -0
  133. data/doorkeeper-5.9.3/lib/generators/doorkeeper/migration_generator.rb +32 -0
  134. data/doorkeeper-5.9.3/lib/generators/doorkeeper/pkce_generator.rb +33 -0
  135. data/doorkeeper-5.9.3/lib/generators/doorkeeper/previous_refresh_token_generator.rb +41 -0
  136. data/doorkeeper-5.9.3/lib/generators/doorkeeper/remove_applications_secret_not_null_constraint_generator.rb +33 -0
  137. data/doorkeeper-5.9.3/lib/generators/doorkeeper/templates/README +24 -0
  138. data/doorkeeper-5.9.3/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  139. data/doorkeeper-5.9.3/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +9 -0
  140. data/doorkeeper-5.9.3/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +13 -0
  141. data/doorkeeper-5.9.3/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +8 -0
  142. data/doorkeeper-5.9.3/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  143. data/doorkeeper-5.9.3/lib/generators/doorkeeper/templates/initializer.rb +544 -0
  144. data/doorkeeper-5.9.3/lib/generators/doorkeeper/templates/migration.rb.erb +99 -0
  145. data/doorkeeper-5.9.3/lib/generators/doorkeeper/templates/remove_applications_secret_not_null_constraint.rb.erb +7 -0
  146. data/doorkeeper-5.9.3/lib/generators/doorkeeper/views_generator.rb +18 -0
  147. data/doorkeeper-5.9.3/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +6 -0
  148. data/super-smart-kit.gemspec +12 -0
  149. metadata +188 -0
@@ -0,0 +1,223 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper::Orm::ActiveRecord::Mixins
4
+ module Application
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ self.table_name = compute_doorkeeper_table_name
9
+ self.strict_loading_by_default = false if respond_to?(:strict_loading_by_default)
10
+
11
+ include ::Doorkeeper::ApplicationMixin
12
+ # `enable_application_owner?` is read once, at parent-class autoload
13
+ # time (#1831): with the feature off the model exposes no `:owner`
14
+ # association — avoiding a misleading reflection on schemas that lack
15
+ # the owner columns. The flag is therefore a load-time switch; turning
16
+ # it on later requires defining a fresh model class.
17
+ include ::Doorkeeper::Models::Ownership if Doorkeeper.config.enable_application_owner?
18
+
19
+ has_many :access_grants,
20
+ foreign_key: :application_id,
21
+ dependent: :delete_all,
22
+ class_name: Doorkeeper.config.access_grant_class.to_s
23
+
24
+ has_many :access_tokens,
25
+ foreign_key: :application_id,
26
+ dependent: :delete_all,
27
+ class_name: Doorkeeper.config.access_token_class.to_s
28
+
29
+ validates :name, :uid, presence: true
30
+ validates :secret, presence: true, if: -> { secret_required? }
31
+ validates :uid, uniqueness: { case_sensitive: true }
32
+ validates :confidential, inclusion: { in: [true, false] }
33
+
34
+ validates_with Doorkeeper::RedirectUriValidator, attributes: [:redirect_uri]
35
+
36
+ validate :scopes_match_configured, if: :enforce_scopes?
37
+
38
+ before_validation :generate_uid, :generate_secret, on: :create
39
+
40
+ has_many :authorized_tokens,
41
+ -> { where(revoked_at: nil) },
42
+ foreign_key: :application_id,
43
+ class_name: Doorkeeper.config.access_token_class.to_s
44
+
45
+ has_many :authorized_applications,
46
+ through: :authorized_tokens,
47
+ source: :application
48
+
49
+ # Generates a new secret for this application, intended to be used
50
+ # for rotating the secret or in case of compromise.
51
+ #
52
+ # @return [String] new transformed secret value
53
+ #
54
+ def renew_secret
55
+ @raw_secret = secret_generator.generate
56
+ secret_strategy.store_secret(self, :secret, @raw_secret)
57
+ end
58
+
59
+ # We keep a volatile copy of the raw secret for initial communication
60
+ # The stored refresh_token may be mapped and not available in cleartext.
61
+ #
62
+ # Some strategies allow restoring stored secrets (e.g. symmetric encryption)
63
+ # while hashing strategies do not, so you cannot rely on this value
64
+ # returning a present value for persisted tokens.
65
+ def plaintext_secret
66
+ if secret_strategy.allows_restoring_secrets?
67
+ secret_strategy.restore_secret(self, :secret)
68
+ else
69
+ @raw_secret
70
+ end
71
+ end
72
+
73
+ # Represents client as set of it's attributes in JSON format.
74
+ # This is the right way how we want to override ActiveRecord #to_json.
75
+ #
76
+ # Respects privacy settings and serializes minimum set of attributes
77
+ # for public/private clients and full set for authorized owners.
78
+ #
79
+ # @return [Hash] entity attributes for JSON
80
+ #
81
+ def as_json(options = {})
82
+ # if application belongs to some owner we need to check if it's the same as
83
+ # the one passed in the options or check if we render the client as an owner
84
+ if (respond_to?(:owner) && owner && owner == options[:current_resource_owner]) ||
85
+ options[:as_owner]
86
+ # Owners can see all the client attributes, fallback to ActiveModel serialization
87
+ super
88
+ else
89
+ # if application has no owner or it's owner doesn't match one from the options
90
+ # we render only minimum set of attributes that could be exposed to a public
91
+ only = extract_serializable_attributes(options)
92
+ super(options.merge(only: only))
93
+ end
94
+ end
95
+
96
+ def authorized_for_resource_owner?(resource_owner)
97
+ Doorkeeper.configuration.authorize_resource_owner_for_client.call(self, resource_owner)
98
+ end
99
+
100
+ # We need to hook into this method to allow serializing plan-text secrets
101
+ # when secrets hashing enabled.
102
+ #
103
+ # @param key [String] attribute name
104
+ #
105
+ def read_attribute_for_serialization(key)
106
+ return super unless key.to_s == "secret"
107
+
108
+ plaintext_secret || secret
109
+ end
110
+
111
+ private
112
+
113
+ def secret_generator
114
+ generator_name = Doorkeeper.config.application_secret_generator
115
+ generator = generator_name.constantize
116
+
117
+ return generator if generator.respond_to?(:generate)
118
+
119
+ raise Errors::UnableToGenerateToken, "#{generator} does not respond to `.generate`."
120
+ rescue NameError
121
+ raise Errors::TokenGeneratorNotFound, "#{generator_name} not found"
122
+ end
123
+
124
+ def generate_uid
125
+ self.uid = Doorkeeper::OAuth::Helpers::UniqueToken.generate if uid.blank?
126
+ end
127
+
128
+ def generate_secret
129
+ return if secret.present? || !secret_required?
130
+
131
+ renew_secret
132
+ end
133
+
134
+ def scopes_match_configured
135
+ if scopes.present? && !Doorkeeper::OAuth::Helpers::ScopeChecker.valid?(
136
+ scope_str: scopes.to_s,
137
+ server_scopes: Doorkeeper.config.scopes,
138
+ )
139
+ errors.add(:scopes, :not_match_configured)
140
+ end
141
+ end
142
+
143
+ def enforce_scopes?
144
+ Doorkeeper.config.enforce_configured_scopes?
145
+ end
146
+
147
+ def secret_required?
148
+ confidential? ||
149
+ !self.class.columns.detect { |column| column.name == "secret" }&.null
150
+ end
151
+
152
+ # Helper method to extract collection of serializable attribute names
153
+ # considering serialization options (like `only`, `except` and so on).
154
+ #
155
+ # @param options [Hash] serialization options
156
+ #
157
+ # @return [Array<String>]
158
+ # collection of attributes to be serialized using #as_json
159
+ #
160
+ def extract_serializable_attributes(options = {})
161
+ opts = options.try(:dup) || {}
162
+ only = Array.wrap(opts[:only]).map(&:to_s)
163
+
164
+ only = if only.blank?
165
+ client_serializable_attributes
166
+ else
167
+ only & client_serializable_attributes
168
+ end
169
+
170
+ only -= Array.wrap(opts[:except]).map(&:to_s) if opts.key?(:except)
171
+ only.uniq
172
+ end
173
+
174
+ # Collection of attributes that could be serialized for public.
175
+ # Override this method if you need additional attributes to be serialized.
176
+ #
177
+ # @return [Array<String>] collection of serializable attributes
178
+ #
179
+ # NOTE: `serializable_attributes` method already taken by Rails >= 6
180
+ #
181
+ def client_serializable_attributes
182
+ attributes = %w[id name created_at]
183
+ attributes << "uid" unless confidential?
184
+ attributes
185
+ end
186
+ end
187
+
188
+ module ClassMethods
189
+ # Returns Applications associated with active (not revoked) Access Tokens
190
+ # that are owned by the specific Resource Owner.
191
+ #
192
+ # @param resource_owner [ActiveRecord::Base]
193
+ # Resource Owner model instance
194
+ #
195
+ # @return [ActiveRecord::Relation]
196
+ # Applications authorized for the Resource Owner
197
+ #
198
+ def authorized_for(resource_owner)
199
+ resource_access_tokens = Doorkeeper.config.access_token_model.active_for(resource_owner)
200
+ where(id: resource_access_tokens.select(:application_id).distinct)
201
+ end
202
+
203
+ # Revokes AccessToken and AccessGrant records that have not been revoked and
204
+ # associated with the specific Application and Resource Owner.
205
+ #
206
+ # @param resource_owner [ActiveRecord::Base]
207
+ # instance of the Resource Owner model
208
+ #
209
+ def revoke_tokens_and_grants_for(id, resource_owner)
210
+ Doorkeeper.config.access_token_model.revoke_all_for(id, resource_owner)
211
+ Doorkeeper.config.access_grant_model.revoke_all_for(id, resource_owner)
212
+ end
213
+
214
+ private
215
+
216
+ def compute_doorkeeper_table_name
217
+ table_name = "oauth_application"
218
+ table_name = table_name.pluralize if pluralize_table_names
219
+ "#{table_name_prefix}#{table_name}#{table_name_suffix}"
220
+ end
221
+ end
222
+ end
223
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ module Doorkeeper
6
+ # ActiveModel validator for redirect URI validation in according
7
+ # to OAuth standards and Doorkeeper configuration.
8
+ class RedirectUriValidator < ActiveModel::EachValidator
9
+ def validate_each(record, attribute, value)
10
+ if value.blank?
11
+ return if Doorkeeper.config.allow_blank_redirect_uri?(record)
12
+
13
+ record.errors.add(attribute, :blank)
14
+ else
15
+ value.split.each do |val|
16
+ next if oob_redirect_uri?(val)
17
+
18
+ uri = ::URI.parse(val)
19
+ record.errors.add(attribute, :forbidden_uri) if forbidden_uri?(uri)
20
+ record.errors.add(attribute, :fragment_present) unless uri.fragment.nil?
21
+ record.errors.add(attribute, :unspecified_scheme) if unspecified_scheme?(uri)
22
+ record.errors.add(attribute, :relative_uri) if relative_uri?(uri)
23
+ record.errors.add(attribute, :secured_uri) if invalid_ssl_uri?(uri)
24
+ record.errors.add(attribute, :invalid_uri) if unspecified_host?(uri)
25
+ end
26
+ end
27
+ rescue URI::InvalidURIError
28
+ record.errors.add(attribute, :invalid_uri)
29
+ end
30
+
31
+ private
32
+
33
+ def oob_redirect_uri?(uri)
34
+ Doorkeeper::OAuth::NonStandard::IETF_WG_OAUTH2_OOB_METHODS.include?(uri)
35
+ end
36
+
37
+ def forbidden_uri?(uri)
38
+ Doorkeeper.config.forbid_redirect_uri.call(uri)
39
+ end
40
+
41
+ def unspecified_scheme?(uri)
42
+ return true if uri.opaque.present?
43
+
44
+ %w[localhost].include?(uri.try(:scheme))
45
+ end
46
+
47
+ def unspecified_host?(uri)
48
+ uri.is_a?(URI::HTTP) && uri.host.blank?
49
+ end
50
+
51
+ def relative_uri?(uri)
52
+ uri.scheme.nil? && uri.host.blank?
53
+ end
54
+
55
+ def invalid_ssl_uri?(uri)
56
+ forces_ssl = Doorkeeper.config.force_ssl_in_redirect_uri
57
+ non_https = uri.try(:scheme) == "http"
58
+
59
+ if forces_ssl.respond_to?(:call)
60
+ forces_ssl.call(uri) && non_https
61
+ else
62
+ forces_ssl && non_https
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Orm
5
+ module ActiveRecord
6
+ # Helper class to clear stale and non-active tokens and grants.
7
+ # Used by Doorkeeper Rake tasks.
8
+ #
9
+ class StaleRecordsCleaner
10
+ def initialize(base_scope)
11
+ @base_scope = base_scope
12
+ end
13
+
14
+ # Clears revoked records
15
+ def clean_revoked
16
+ table = @base_scope.arel_table
17
+
18
+ @base_scope
19
+ .where.not(revoked_at: nil)
20
+ .where(table[:revoked_at].lt(Time.current))
21
+ .in_batches(&:delete_all)
22
+ end
23
+
24
+ # Clears expired records
25
+ def clean_expired(ttl)
26
+ table = @base_scope.arel_table
27
+ model_class = @base_scope.is_a?(::ActiveRecord::Relation) ? @base_scope.klass : @base_scope
28
+
29
+ scope = @base_scope
30
+ .where.not(expires_in: nil)
31
+ .where(table[:created_at].lt(Time.current - ttl))
32
+
33
+ if model_class.respond_to?(:supports_expiration_time_math?) && model_class.supports_expiration_time_math?
34
+ scope = scope.where("#{model_class.expiration_time_sql} < ?", Time.current)
35
+ else
36
+ ::Kernel.warn(::Doorkeeper::Models::ExpirationTimeSqlMath::WARNING_MESSAGE)
37
+ end
38
+
39
+ scope.in_batches(&:delete_all)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ autoload :AccessGrant, "doorkeeper/orm/active_record/access_grant"
5
+ autoload :AccessToken, "doorkeeper/orm/active_record/access_token"
6
+ autoload :Application, "doorkeeper/orm/active_record/application"
7
+ autoload :RedirectUriValidator, "doorkeeper/orm/active_record/redirect_uri_validator"
8
+
9
+ module Models
10
+ autoload :Ownership, "doorkeeper/models/concerns/ownership"
11
+ end
12
+
13
+ # ActiveRecord ORM for Doorkeeper entity models.
14
+ # Consists of three main OAuth entities:
15
+ # * Access Token
16
+ # * Access Grant
17
+ # * Application (client)
18
+ #
19
+ # Do a lazy loading of all the required and configured stuff.
20
+ #
21
+ module Orm
22
+ module ActiveRecord
23
+ autoload :StaleRecordsCleaner, "doorkeeper/orm/active_record/stale_records_cleaner"
24
+
25
+ module Mixins
26
+ autoload :AccessGrant, "doorkeeper/orm/active_record/mixins/access_grant"
27
+ autoload :AccessToken, "doorkeeper/orm/active_record/mixins/access_token"
28
+ autoload :Application, "doorkeeper/orm/active_record/mixins/application"
29
+ end
30
+
31
+ # Kept as a no-op so `Doorkeeper.run_orm_hooks` (and any plugin that
32
+ # checks `respond_to?(:run_hooks)`) stays quiet. The model concerns
33
+ # that used to be wired up here are now included from each Mixin's
34
+ # `included` block, which runs at parent-class autoload time — well
35
+ # after `Doorkeeper.configure` has applied user settings, and without
36
+ # touching `ActiveSupport.on_load(:active_record)` (whose re-entrant
37
+ # firing during `ApplicationRecord` autoload caused #1828).
38
+ def self.run_hooks; end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rails
5
+ module Helpers
6
+ def doorkeeper_authorize!(*scopes)
7
+ @_doorkeeper_scopes = scopes.presence || Doorkeeper.config.default_scopes
8
+
9
+ doorkeeper_render_error unless valid_doorkeeper_token?
10
+ end
11
+
12
+ def doorkeeper_unauthorized_render_options(**); end
13
+
14
+ def doorkeeper_forbidden_render_options(**); end
15
+
16
+ def valid_doorkeeper_token?
17
+ doorkeeper_token&.acceptable?(@_doorkeeper_scopes)
18
+ end
19
+
20
+ private
21
+
22
+ def doorkeeper_render_error
23
+ error = doorkeeper_error
24
+ error.raise_exception! if Doorkeeper.config.raise_on_errors?
25
+
26
+ headers.merge!(error.headers.reject { |k| k == "Content-Type" })
27
+ doorkeeper_render_error_with(error)
28
+ end
29
+
30
+ def doorkeeper_render_error_with(error)
31
+ options = doorkeeper_render_options(error) || {}
32
+ status = doorkeeper_status_for_error(
33
+ error, options.delete(:respond_not_found_when_forbidden),
34
+ )
35
+ if options.blank?
36
+ head status
37
+ else
38
+ options[:status] = status
39
+ options[:layout] = false if options[:layout].nil?
40
+ render options
41
+ end
42
+ end
43
+
44
+ def doorkeeper_error
45
+ if doorkeeper_invalid_token_response?
46
+ OAuth::InvalidTokenResponse.from_access_token(doorkeeper_token)
47
+ else
48
+ OAuth::ForbiddenTokenResponse.from_scopes(@_doorkeeper_scopes)
49
+ end
50
+ end
51
+
52
+ def doorkeeper_render_options(error)
53
+ if doorkeeper_invalid_token_response?
54
+ doorkeeper_unauthorized_render_options(error: error)
55
+ else
56
+ doorkeeper_forbidden_render_options(error: error)
57
+ end
58
+ end
59
+
60
+ def doorkeeper_status_for_error(error, respond_not_found_when_forbidden)
61
+ if respond_not_found_when_forbidden && error.status == :forbidden
62
+ :not_found
63
+ else
64
+ error.status
65
+ end
66
+ end
67
+
68
+ def doorkeeper_invalid_token_response?
69
+ !doorkeeper_token || !doorkeeper_token.accessible?
70
+ end
71
+
72
+ def doorkeeper_token
73
+ return @doorkeeper_token if defined?(@doorkeeper_token)
74
+
75
+ @doorkeeper_token = OAuth::Token.authenticate(
76
+ request,
77
+ *Doorkeeper.config.access_token_methods,
78
+ )
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rails
5
+ # Abstract router module that implements base behavior
6
+ # for generating and mapping Rails routes.
7
+ #
8
+ # Could be reused in Doorkeeper extensions.
9
+ #
10
+ module AbstractRouter
11
+ extend ActiveSupport::Concern
12
+
13
+ attr_reader :routes
14
+
15
+ def initialize(routes, mapper = Mapper.new, &block)
16
+ @routes = routes
17
+ @mapping = mapper.map(&block)
18
+ end
19
+
20
+ def generate_routes!(**_options)
21
+ raise NotImplementedError, "must be redefined for #{self.class.name}!"
22
+ end
23
+
24
+ private
25
+
26
+ def map_route(name, method)
27
+ return if @mapping.skipped?(name)
28
+
29
+ send(method, @mapping[name])
30
+
31
+ mapping[name] = @mapping[name]
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rails
5
+ class Routes # :nodoc:
6
+ class Mapper
7
+ def initialize(mapping = Mapping.new)
8
+ @mapping = mapping
9
+ end
10
+
11
+ def map(&block)
12
+ instance_eval(&block) if block
13
+ @mapping
14
+ end
15
+
16
+ def controllers(controller_names = {})
17
+ @mapping.controllers.merge!(controller_names)
18
+ end
19
+
20
+ def skip_controllers(*controller_names)
21
+ @mapping.skips = controller_names
22
+ end
23
+
24
+ def as(alias_names = {})
25
+ @mapping.as.merge!(alias_names)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rails
5
+ class Routes # :nodoc:
6
+ class Mapping
7
+ attr_accessor :controllers, :as, :skips
8
+
9
+ def initialize
10
+ @controllers = {
11
+ authorizations: "doorkeeper/authorizations",
12
+ applications: "doorkeeper/applications",
13
+ authorized_applications: "doorkeeper/authorized_applications",
14
+ tokens: "doorkeeper/tokens",
15
+ token_info: "doorkeeper/token_info",
16
+ }
17
+
18
+ @as = {
19
+ authorizations: :authorization,
20
+ tokens: :token,
21
+ token_info: :token_info,
22
+ }
23
+
24
+ @skips = []
25
+ end
26
+
27
+ def [](routes)
28
+ {
29
+ controllers: @controllers[routes],
30
+ as: @as[routes],
31
+ }
32
+ end
33
+
34
+ def skipped?(controller)
35
+ @skips.include?(controller)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rails
5
+ class Routes
6
+ # Thread-safe registry of any Doorkeeper additional routes.
7
+ # Used to allow implementing of Doorkeeper extensions that must
8
+ # use their own routes.
9
+ #
10
+ module Registry
11
+ ROUTES_ACCESS_LOCK = Mutex.new
12
+ ROUTES_DEFINITION_LOCK = Mutex.new
13
+
14
+ InvalidRouterClass = Class.new(StandardError)
15
+
16
+ # Collection of additional registered routes for Doorkeeper.
17
+ #
18
+ # @return [Array<Object>] set of registered routes
19
+ #
20
+ def registered_routes
21
+ ROUTES_DEFINITION_LOCK.synchronize do
22
+ @registered_routes ||= Set.new
23
+ end
24
+ end
25
+
26
+ # Registers additional routes in the Doorkeeper registry
27
+ #
28
+ # @param [Object] routes
29
+ # routes class
30
+ #
31
+ def register_routes(routes)
32
+ if !routes.is_a?(Module) || !(routes < AbstractRouter)
33
+ raise InvalidRouterClass, "routes class must include Doorkeeper::Rails::AbstractRouter"
34
+ end
35
+
36
+ ROUTES_ACCESS_LOCK.synchronize do
37
+ registered_routes << routes
38
+ end
39
+ end
40
+
41
+ alias register register_routes
42
+ end
43
+ end
44
+ end
45
+ end