12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- class Token < ApplicationRecord
- # A Token contains some information that can be used as an alternative way to
- # authenticate a user, typically instead of a username/password combination.
- #
- # At least the following types of tokens will exist:
- # - Account confirmation tokens, sent to the user when their account is
- # created (to verify their email address)
- # - Password reset tokens
- # - API authentication tokens
- #
- # @!attribute token
- # @return [String]
- # a unique token, that allows the holder to perform some action.
- #
- # @!attribute expires
- # @return [DateTime]
- # when the token will expire (and will no longer be usable). May be nil
- # for no expiry.
- #
- # @!attribute tokentype
- # @return [String]
- # what action the token allows the holder to perform. Use the hash
- # Token::TYPES instead of comparing directly!
- #
- # @!attribute user
- # @return [User]
- # what user the token allows the holder to authenticate as.
- TYPES = {
- password_reset: 'pw_reset',
- account_confirmation: 'confirm',
- api_authentication: 'api'
- }.freeze
- validates :token, uniqueness: true, presence: true
- validates :user, presence: true
- belongs_to :user
- before_validation :generate_token, if: "self.token.blank?"
- before_validation :generate_expiry, on: :create
- private
- def generate_token
- candidate = nil
- loop do
- candidate = SecureRandom.urlsafe_base64 32
- break candidate unless Token.exists?(token: candidate)
- end
- self.token = candidate
- end
- # Defines the default expiry for the expiring tokens.
- def generate_expiry
- case tokentype
- when TYPES[:password_reset]
- self.expires = 1.day.since
- when TYPES[:account_confirmation]
- self.expires = 7.days.since
- end
- end
- end
|