Skip to content
Snippets Groups Projects
Select Git revision
  • c255da4dd56398b3a641abfdf659d7da19bd5373
  • 2024ws default
  • 2023ws
  • 2022ws
  • 2021ws
  • 2020ws
  • 2018ws
  • 2019ws
  • 2017ws
  • 2016ws
10 results

gtk-4.c

Blame
  • user.rb 5.59 KiB
    # frozen_string_literal: true
    
    class User < ApplicationRecord
      MAX_AVATAR_SIZE = 3_000_000
      # Reset token max validity period.
      # It's advised to not increase this to more than 1 hour.
      RESET_TOKEN_VALIDITY_PERIOD = 1.hour
      # Account activation token max validity period.
      # It's advised to not increase this to more than 1 hour.
      ACTIVATION_TOKEN_VALIDITY_PERIOD = 1.hour
    
      has_secure_password validations: false
    
      belongs_to :role
    
      has_many :rooms, dependent: :destroy
      has_many :shared_accesses, dependent: :destroy
      has_many :shared_rooms, through: :shared_accesses, class_name: 'Room'
      has_many :recordings, through: :rooms
    
      has_one_attached :avatar
    
      enum status: { active: 0, pending: 1, banned: 2 }
    
      validates :name, presence: true,
                       length: { minimum: 2, maximum: 255 } # TODO: amir - Change into full_name or seperate first and last name.
    
      validates :email,
                format: /\A[\w\-.]+@[\w\-.]+\.[a-z]+\z/i,
                presence: true,
                uniqueness: { case_sensitive: false, scope: :provider },
                length: { minimum: 5, maximum: 255 }
    
      validates :provider, presence: true
      validates :status, presence: true
      validates :password,
                presence: true,
                on: :create, unless: :external_id?,
                length: { maximum: 255 }
    
      validates :password,
                format: %r{\A(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[`@%~!#£$\\^&*()\]\[+={}/|:;"'<>\-,.?_ ]).{8,}\z},
                on: %i[create update], if: :password_digest_changed?, unless: :external_id?
    
      validates :avatar,
                dimension: { width: 300, height: 300 },
                content_type: %i[png jpg jpeg svg],
                size: { less_than: 3.megabytes }
    
      validates :reset_digest, uniqueness: true, if: :reset_digest?
      validates :verification_digest, uniqueness: true, if: :verification_digest?
      validates :session_token, presence: true, uniqueness: true
      validates :session_expiry, presence: true
      validates :language, presence: true
    
      validate :check_user_role_provider, if: :role_changed?
    
      before_validation :set_session_token, on: :create
    
      scope :with_provider, ->(current_provider) { where(provider: current_provider) }
    
      def self.search(input)
        return joins(:role).where('users.name ILIKE :input OR users.email ILIKE :input OR roles.name ILIKE :input', input: "%#{input}%") if input
    
        all
      end
    
      def self.name_search(input)
        return where('users.name ILIKE :input', input: "%#{input}%") if input
    
        all
      end
    
      # Verifies the token existence, fetches its user and validates its expiration
      # and invalidates the user token if expired.
    
      def self.verify_reset_token(token)
        digest = generate_digest(token)
    
        user = find_by reset_digest: digest
        return false unless user
    
        return false unless user.reset_sent_at
    
        expired = reset_token_expired?(user.reset_sent_at)
    
        if expired
          user.invalidate_reset_token
          return false
        end
    
        user
      end
    
      # Generates a token digest.
      def self.generate_digest(token)
        Digest::SHA2.hexdigest(token)
      end
    
      # Checkes the expiration of a token.
      def self.reset_token_expired?(sent_at)
        Time.current > (sent_at.in(RESET_TOKEN_VALIDITY_PERIOD))
      end
    
      # Gives the session token and expiry a default value before saving
      def set_session_token
        self.session_token = User.generate_digest(SecureRandom.alphanumeric(40))
        self.session_expiry = 6.hours.from_now
      end
    
      def generate_session_token!(extended_session: false)
        digest = User.generate_digest(SecureRandom.alphanumeric(40))
        expiry = extended_session ? 7.days.from_now : 6.hours.from_now
    
        update! session_token: digest, session_expiry: expiry
      rescue ActiveRecord::RecordInvalid
        raise unless errors.attribute_names.include? :session_token
    
        retry
      end
    
      # Create a unique random reset token
      def generate_reset_token!
        token = SecureRandom.alphanumeric(40)
        digest = User.generate_digest(token)
    
        update! reset_digest: digest, reset_sent_at: Time.current
    
        token
      rescue ActiveRecord::RecordInvalid
        raise unless errors.attribute_names.include? :reset_digest
    
        retry
      end
    
      # Create a unique random activation token
      # TODO: reduce duplication.
      def generate_activation_token!
        token = SecureRandom.alphanumeric(40)
        digest = User.generate_digest(token)
    
        update! verification_digest: digest, verification_sent_at: Time.current
    
        token
      rescue ActiveRecord::RecordInvalid
        raise unless errors.attribute_names.include? :verification_digest
    
        retry
      end
    
      def invalidate_reset_token
        update reset_sent_at: nil, reset_digest: nil # Remove expired/valid tokens.
      end
    
      # Verifies the token existence, fetches its user and validates its expiration
      # and invalidates the user activationtoken if expired.
    
      def self.verify_activation_token(token)
        digest = generate_digest(token)
    
        user = find_by verification_digest: digest
        return false unless user
    
        return false unless user.verification_sent_at
    
        expired = activation_token_expired?(user.verification_sent_at)
    
        if expired
          user.invalidate_activation_token
          return false
        end
    
        user
      end
    
      # Checkes the expiration of a token.
      def self.activation_token_expired?(sent_at)
        Time.current > (sent_at.in(ACTIVATION_TOKEN_VALIDITY_PERIOD))
      end
    
      def invalidate_activation_token
        update verification_sent_at: nil, verification_digest: nil # Remove expired/valid tokens.
      end
    
      def verify!
        update! verified: true
      end
    
      def deverify!
        update! verified: false
      end
    
      def check_user_role_provider
        return unless role
    
        errors.add(:user_provider, 'has to be the same as the Role provider') if provider != role.provider
      end
    end