class RsAuthorizationCode < ApplicationRecord belongs_to :user CODE_TTL = 60.seconds serialize :permissions, coder: YAML attr_accessor :code before_validation :generate_code scope :active, -> { where(expires_at: Time.current..) } def self.find_by_code(raw_code) return nil if raw_code.blank? find_by(code_digest: Digest::SHA256.hexdigest(raw_code)) end def expired? expires_at <= Time.current end def consume! destroy! end private def generate_code return if code_digest.present? self.code = SecureRandom.urlsafe_base64(32) self.code_digest = Digest::SHA256.hexdigest(code) self.expires_at ||= CODE_TTL.from_now end end