module Doorkeeper::AccessTokenMixin::ClassMethods
Public Instance Methods
Returns an instance of the Doorkeeper::AccessToken
found by previous refresh token. Keep in mind that value of the previous_refresh_token isn’t encrypted using secrets strategy.
@param previous_refresh_token [#to_s]
previous refresh token value (any object that responds to `#to_s`)
@return [Doorkeeper::AccessToken, nil] AccessToken
object or nil
if there is no record with such refresh token
# File lib/doorkeeper/models/access_token_mixin.rb, line 56 def by_previous_refresh_token(previous_refresh_token) find_by(refresh_token: previous_refresh_token) end
Returns an instance of the Doorkeeper::AccessToken
with specific token value.
@param refresh_token [#to_s]
refresh token value (any object that responds to `#to_s`)
@return [Doorkeeper::AccessToken, nil] AccessToken
object or nil
if there is no record with such refresh token
# File lib/doorkeeper/models/access_token_mixin.rb, line 41 def by_refresh_token(refresh_token) find_by_plaintext_token(:refresh_token, refresh_token) end
Returns an instance of the Doorkeeper::AccessToken
with specific plain text token value.
@param token [#to_s]
Plain text token value (any object that responds to `#to_s`)
@return [Doorkeeper::AccessToken, nil] AccessToken
object or nil
if there is no record with such token
# File lib/doorkeeper/models/access_token_mixin.rb, line 28 def by_token(token) find_by_plaintext_token(:token, token) end
Creates a not expired AccessToken
record with a matching set of scopes that belongs to specific Application
and Resource Owner.
@param application [Doorkeeper::Application]
Application instance
@param resource_owner [ActiveRecord::Base, Integer]
Resource Owner model instance or it's ID
@param scopes [#to_s]
set of scopes (any object that responds to `#to_s`)
@param token_attributes [Hash]
Additional attributes to use when creating a token
@option token_attributes [Integer] :expires_in
token lifetime in seconds
@option token_attributes [Boolean] :use_refresh_token
whether to use the refresh token
@return [Doorkeeper::AccessToken] new access token
# File lib/doorkeeper/models/access_token_mixin.rb, line 253 def create_for(application:, resource_owner:, scopes:, **token_attributes) token_attributes[:application] = application token_attributes[:scopes] = scopes.to_s if Doorkeeper.config.polymorphic_resource_owner? token_attributes[:resource_owner] = resource_owner else token_attributes[:resource_owner_id] = resource_owner_id_for(resource_owner) end create!(token_attributes) end
Checks whether the token custom attribute values match the custom attributes from the parameters.
@param token [Doorkeeper::AccessToken]
The access token whose custom attributes are being compared to the custom_attributes.
@param custom_attributes [Hash]
A hash of the attributes for which we want to determine whether the token's custom attributes match.
@return [Boolean] true if the token’s custom attribute values
match those in the custom_attributes, or if both are empty/blank. False otherwise.
# File lib/doorkeeper/models/access_token_mixin.rb, line 186 def custom_attributes_match?(token, custom_attributes) return true if custom_attributes.nil? token_attribs = token.custom_attributes return true if token_attribs.blank? && custom_attributes.blank? Doorkeeper.config.custom_access_token_attributes.all? do |attribute| token_attribs[attribute] == custom_attributes[attribute] end end
Extracts the token’s custom attributes (defined by the custom_access_token_attributes config option) from the token’s attributes.
@param attributes [Hash]
A hash of the access token's attributes.
@return [Hash]
A hash containing only the custom access token attributes.
# File lib/doorkeeper/models/access_token_mixin.rb, line 325 def extract_custom_attributes(attributes) attributes.with_indifferent_access.slice( *Doorkeeper.configuration.custom_access_token_attributes) end
Determine the fallback storing strategy Unless configured, there will be no fallback
# File lib/doorkeeper/models/access_token_mixin.rb, line 314 def fallback_secret_strategy ::Doorkeeper.config.token_secret_fallback_strategy end
Interface to enumerate access token records in batches in order not to bloat the memory. Could be overloaded in any ORM extension.
# File lib/doorkeeper/models/access_token_mixin.rb, line 103 def find_access_token_in_batches(relation, **args, &block) relation.find_in_batches(**args, &block) end
Enumerates AccessToken
records in batches to find a matching token. Batching is required in order not to pollute the memory if Application
has huge amount of associated records.
ActiveRecord 5.x - 6.x ignores custom ordering so we can’t perform a database sort by created_at, so we need to load all the matching records, sort them and find latest one.
@param relation [ActiveRecord::Relation]
Access tokens relation
@param application [Doorkeeper::Application]
Application instance
@param scopes [String, Doorkeeper::OAuth::Scopes
]
set of scopes
@param custom_attributes [Nilable Hash]
A nil value, or hash with keys corresponding to the custom attributes configured with the `custom_access_token_attributes` config option. A nil value will ignore custom attributes.
@return [Doorkeeper::AccessToken, nil] Access Token instance or
nil if matching record was not found
# File lib/doorkeeper/models/access_token_mixin.rb, line 129 def find_matching_token(relation, application, custom_attributes, scopes) return nil unless relation matching_tokens = [] batch_size = Doorkeeper.configuration.token_lookup_batch_size find_access_token_in_batches(relation, batch_size: batch_size) do |batch| tokens = batch.select do |token| scopes_match?(token.scopes, scopes, application&.scopes) && custom_attributes_match?(token, custom_attributes) end matching_tokens.concat(tokens) end matching_tokens.max_by(&:created_at) end
Looking for not expired AccessToken
record with a matching set of scopes that belongs to specific Application
and Resource Owner. If it doesn’t exists - then creates it.
@param application [Doorkeeper::Application]
Application instance
@param resource_owner [ActiveRecord::Base, Integer]
Resource Owner model instance or it's ID
@param scopes [#to_s]
set of scopes (any object that responds to `#to_s`)
@param token_attributes [Hash]
Additional attributes to use when creating a token
@option token_attributes [Integer] :expires_in
token lifetime in seconds
@option token_attributes [Boolean] :use_refresh_token
whether to use the refresh token
@return [Doorkeeper::AccessToken] existing record or a new one
# File lib/doorkeeper/models/access_token_mixin.rb, line 216 def find_or_create_for(application:, resource_owner:, scopes:, **token_attributes) scopes = Doorkeeper::OAuth::Scopes.from_string(scopes) if scopes.is_a?(String) if Doorkeeper.config.reuse_access_token custom_attributes = extract_custom_attributes(token_attributes).presence access_token = matching_token_for( application, resource_owner, scopes, custom_attributes: custom_attributes, include_expired: false) return access_token if access_token&.reusable? end create_for( application: application, resource_owner: resource_owner, scopes: scopes, **token_attributes, ) end
Looking for not revoked Access Token with a matching set of scopes that belongs to specific Application
and Resource Owner.
@param application [Doorkeeper::Application]
Application instance
@param resource_owner [ActiveRecord::Base, Integer]
Resource Owner model instance or it's ID
@param scopes [String, Doorkeeper::OAuth::Scopes
]
set of scopes
@param custom_attributes [Nilable Hash]
A nil value, or hash with keys corresponding to the custom attributes configured with the `custom_access_token_attributes` config option. A nil value will ignore custom attributes.
@return [Doorkeeper::AccessToken, nil] Access Token instance or
nil if matching record was not found
# File lib/doorkeeper/models/access_token_mixin.rb, line 94 def matching_token_for(application, resource_owner, scopes, custom_attributes: nil, include_expired: true) tokens = authorized_tokens_for(application&.id, resource_owner) tokens = tokens.not_expired unless include_expired find_matching_token(tokens, application, custom_attributes, scopes) end
Revokes AccessToken
records that have not been revoked and associated with the specific Application
and Resource Owner.
@param application_id [Integer]
ID of the Application
@param resource_owner [ActiveRecord::Base, Integer]
instance of the Resource Owner model or it's ID
# File lib/doorkeeper/models/access_token_mixin.rb, line 68 def revoke_all_for(application_id, resource_owner, clock = Time) by_resource_owner(resource_owner) .where( application_id: application_id, revoked_at: nil, ) .update_all(revoked_at: clock.now.utc) end
Checks whether the token scopes match the scopes from the parameters
@param token_scopes [#to_s]
set of scopes (any object that responds to `#to_s`)
@param param_scopes [Doorkeeper::OAuth::Scopes]
scopes from params
@param app_scopes [Doorkeeper::OAuth::Scopes]
Application scopes
@return [Boolean] true if the param scopes match the token scopes,
and all the param scopes are defined in the application (or in the server configuration if the application doesn't define any scopes), and false in other cases
# File lib/doorkeeper/models/access_token_mixin.rb, line 161 def scopes_match?(token_scopes, param_scopes, app_scopes) return true if token_scopes.empty? && param_scopes.empty? (token_scopes.sort == param_scopes.sort) && Doorkeeper::OAuth::Helpers::ScopeChecker.valid?( scope_str: param_scopes.to_s, server_scopes: Doorkeeper.config.scopes, app_scopes: app_scopes, ) end
Determines the secret storing transformer Unless configured otherwise, uses the plain secret strategy
@return [Doorkeeper::SecretStoring::Base]
# File lib/doorkeeper/models/access_token_mixin.rb, line 307 def secret_strategy ::Doorkeeper.config.token_secret_strategy end