Files
danbooru/app/logical/user_name_validator.rb
evazion 74d6b4e81e users: don't allow names ending with file extensions.
This is so in the future we can have URLs like https://danbooru.donmai.us/users/evazion
without problems caused by names like https://danbooru.donmai.us/users/evazion.json
2022-03-07 04:39:00 -06:00

42 lines
1.8 KiB
Ruby

# frozen_string_literal: true
# Define a custom validator for user names.
#
# @example
# validates :name, user_name: true
#
# @see https://guides.rubyonrails.org/active_record_validations.html#custom-validators
class UserNameValidator < ActiveModel::EachValidator
ALLOWED_PUNCTUATION = "_.-" # All other punctuation characters are forbidden
def validate_each(rec, attr, name)
forbidden_characters = name.delete(ALLOWED_PUNCTUATION).chars.grep(/[[:punct:]]/).uniq
if rec.new_record? && User.find_by_name(name).present?
rec.errors.add(attr, "already exists")
elsif name.length <= 1
rec.errors.add(attr, "must be more than 1 character long")
elsif name.length >= 25
rec.errors.add(attr, "must be less than 25 characters long")
elsif name =~ /[[:space:]]/
rec.errors.add(attr, "can't contain whitespace")
elsif name =~ /\A[[:punct:]]/
rec.errors.add(attr, "can't start with '#{name.first}'")
elsif name =~ /[[:punct:]]\z/
rec.errors.add(attr, "can't end with '#{name.last}'")
elsif name =~ /\.(html|json|xml|atom|rss|txt|js|css|csv|png|jpg|jpeg|gif|png|mp4|webm|zip|pdf|exe|sitemap)\z/i
rec.errors.add(attr, "can't end with a file extension")
elsif name =~ /__/
rec.errors.add(attr, "can't contain multiple underscores in a row")
elsif forbidden_characters.present?
rec.errors.add(attr, "can't contain #{forbidden_characters.map { |c| "'#{c}'" }.to_sentence}")
elsif name !~ /\A([a-zA-Z0-9]|\p{Han}|\p{Hangul}|\p{Hiragana}|\p{Katakana}|[#{ALLOWED_PUNCTUATION}])+\z/
rec.errors.add(attr, "must contain only basic letters or numbers")
elsif name =~ /\Auser_\d+\z/i
rec.errors.add(attr, "can't be the same as a deleted user")
elsif name =~ Regexp.union(Danbooru.config.user_name_blacklist)
rec.errors.add(attr, "is not allowed")
end
end
end