<commit_before># frozen_string_literal: true

class User < ApplicationRecord
  validates :email, presence: true, uniqueness: true, email: true
  validates :username,
            uniqueness: { if: -> { username.present? } },
            format: { with: /\A[a-z0-9]+\z/, unless: -> { username.nil? } }
  validates :login_code, uniqueness: { if: -> { login_code.present? } }
  validates :auth_token, uniqueness: { if: -> { auth_token.present? } }
  validates :email_on_new_challenges,
            :email_on_new_challenge_posts,
            :email_on_new_challenge_post_comments,
            inclusion: { in: [true, false] }

  validate :username_cannot_be_unset

  has_many :leader_profiles
  has_many :new_club_applications, through: :leader_profiles

  belongs_to :new_leader
  has_many :leadership_position_invites

  after_initialize :default_values
  before_validation :downcase_email
  before_create :set_username_if_unset
  before_create :shadow_ban_if_email_blocked

  def username_cannot_be_unset
    return unless persisted?
    return unless username_changed?
    return if username.present?

    errors.add(:username, 'cannot unset username')
  end

  def default_values
    return if persisted?

    if email_on_new_challenge_post_comments.nil?
      self.email_on_new_challenge_post_comments = true
    end

    self.email_on_new_challenges ||= false
    self.email_on_new_challenge_posts ||= false
  end

  def downcase_email
    email&.downcase!
  end

  def set_username_if_unset
    return if username.present?

    self.username = email.split('@').first
    username.gsub!(/[^a-z0-9]/, '') # strip special chars

    # we good if username is unique
    return unless User.find_by(username: username)

    # if not unique, make it unique
    count = 2
    count += 1 while User.find_by(username: username + count.to_s)

    # set unique value
    self.username = username + count.to_s
  end

  def shadow_ban_if_email_blocked
    matches = Users::BlockedEmailDomain.where("? LIKE ('%' || domain)", email)
    return if matches.empty?

    shadow_ban!
  end

  def generate_login_code!
    loop do
      self.login_code = SecureRandom.random_number(999_999).to_s
      self.login_code = login_code.ljust(6, '0') # left pad w/ zeros

      self.login_code_generation = Time.current

      # repeat until code is unique
      break unless User.find_by(login_code: login_code)
    end
  end
<commit_msg>Provide clarifying comment on blocked domain lookup<commit_after># frozen_string_literal: true

class User < ApplicationRecord
  validates :email, presence: true, uniqueness: true, email: true
  validates :username,
            uniqueness: { if: -> { username.present? } },
            format: { with: /\A[a-z0-9]+\z/, unless: -> { username.nil? } }
  validates :login_code, uniqueness: { if: -> { login_code.present? } }
  validates :auth_token, uniqueness: { if: -> { auth_token.present? } }
  validates :email_on_new_challenges,
            :email_on_new_challenge_posts,
            :email_on_new_challenge_post_comments,
            inclusion: { in: [true, false] }

  validate :username_cannot_be_unset

  has_many :leader_profiles
  has_many :new_club_applications, through: :leader_profiles

  belongs_to :new_leader
  has_many :leadership_position_invites

  after_initialize :default_values
  before_validation :downcase_email
  before_create :set_username_if_unset
  before_create :shadow_ban_if_email_blocked

  def username_cannot_be_unset
    return unless persisted?
    return unless username_changed?
    return if username.present?

    errors.add(:username, 'cannot unset username')
  end

  def default_values
    return if persisted?

    if email_on_new_challenge_post_comments.nil?
      self.email_on_new_challenge_post_comments = true
    end

    self.email_on_new_challenges ||= false
    self.email_on_new_challenge_posts ||= false
  end

  def downcase_email
    email&.downcase!
  end

  def set_username_if_unset
    return if username.present?

    self.username = email.split('@').first
    username.gsub!(/[^a-z0-9]/, '') # strip special chars

    # we good if username is unique
    return unless User.find_by(username: username)

    # if not unique, make it unique
    count = 2
    count += 1 while User.find_by(username: username + count.to_s)

    # set unique value
    self.username = username + count.to_s
  end

  def shadow_ban_if_email_blocked
    # find domains that match the end of the user's email
    matches = Users::BlockedEmailDomain.where("? LIKE ('%' || domain)", email)
    return if matches.empty?

    shadow_ban!
  end

  def generate_login_code!
    loop do
      self.login_code = SecureRandom.random_number(999_999).to_s
      self.login_code = login_code.ljust(6, '0') # left pad w/ zeros

      self.login_code_generation = Time.current

      # repeat until code is unique
      break unless User.find_by(login_code: login_code)
    end
  end

{'fraction_non_alphanumeric': 0.08773354995938261, 'fraction_numerical': 0.005686433793663688, 'mean_word_length': 3.4936131386861313, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5274314', 'n_tokens_mistral': 1654, 'n_tokens_neox': 1542, 'n_words': 372}