Merge tag 'v3.4.0' into hometown-dev

This commit is contained in:
Darius Kazemi
2021-05-17 13:48:27 -07:00
897 changed files with 26918 additions and 14941 deletions

View File

@ -2,30 +2,29 @@
class BlacklistedEmailValidator < ActiveModel::Validator
def validate(user)
return if user.valid_invitation?
return if user.valid_invitation? || user.email.blank?
@email = user.email
user.errors.add(:email, I18n.t('users.blocked_email_provider')) if blocked_email?
user.errors.add(:email, :blocked) if blocked_email_provider?
user.errors.add(:email, :taken) if blocked_canonical_email?
end
private
def blocked_email?
on_blacklist? || not_on_whitelist?
def blocked_email_provider?
disallowed_through_email_domain_block? || disallowed_through_configuration? || not_allowed_through_configuration?
end
def on_blacklist?
return true if EmailDomainBlock.block?(@email)
return false if Rails.configuration.x.email_domains_blacklist.blank?
domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.')
regexp = Regexp.new("@(.+\\.)?(#{domains})", true)
@email =~ regexp
def blocked_canonical_email?
CanonicalEmailBlock.block?(@email)
end
def not_on_whitelist?
def disallowed_through_email_domain_block?
EmailDomainBlock.block?(@email)
end
def not_allowed_through_configuration?
return false if Rails.configuration.x.email_domains_whitelist.blank?
domains = Rails.configuration.x.email_domains_whitelist.gsub('.', '\.')
@ -33,4 +32,13 @@ class BlacklistedEmailValidator < ActiveModel::Validator
@email !~ regexp
end
def disallowed_through_configuration?
return false if Rails.configuration.x.email_domains_blacklist.blank?
domains = Rails.configuration.x.email_domains_blacklist.gsub('.', '\.')
regexp = Regexp.new("@(.+\\.)?(#{domains})", true)
regexp.match?(@email)
end
end

View File

@ -4,16 +4,19 @@ require 'resolv'
class EmailMxValidator < ActiveModel::Validator
def validate(user)
return if user.email.blank?
domain = get_domain(user.email)
if domain.nil?
user.errors.add(:email, I18n.t('users.invalid_email'))
else
if domain.blank?
user.errors.add(:email, :invalid)
elsif !on_allowlist?(domain)
ips, hostnames = resolve_mx(domain)
if ips.empty?
user.errors.add(:email, I18n.t('users.invalid_email_mx'))
user.errors.add(:email, :unreachable)
elsif on_blacklist?(hostnames + ips)
user.errors.add(:email, I18n.t('users.blocked_email_provider'))
user.errors.add(:email, :blocked)
end
end
end
@ -30,6 +33,12 @@ class EmailMxValidator < ActiveModel::Validator
nil
end
def on_allowlist?(domain)
return false if Rails.configuration.x.email_domains_whitelist.blank?
Rails.configuration.x.email_domains_whitelist.include?(domain)
end
def resolve_mx(domain)
hostnames = []
ips = []

View File

@ -4,11 +4,25 @@ class ExistingUsernameValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if value.blank?
usernames_and_domains = begin
value.split(',').map do |str|
username, domain = str.strip.gsub(/\A@/, '').split('@')
domain = nil if TagManager.instance.local_domain?(domain)
next if username.blank?
[str, username, domain]
end.compact
end
usernames_with_no_accounts = usernames_and_domains.filter_map do |(str, username, domain)|
str unless Account.find_remote(username, domain)
end
if options[:multiple]
missing_usernames = value.split(',').map { |username| username.strip.gsub(/\A@/, '') }.map { |username| username unless Account.find_local(username) }.compact
record.errors.add(attribute, I18n.t('existing_username_validator.not_found_multiple', usernames: missing_usernames.join(', '))) if missing_usernames.any?
record.errors.add(attribute, I18n.t('existing_username_validator.not_found_multiple', usernames: usernames_with_no_accounts.join(', '))) if usernames_with_no_accounts.any?
else
record.errors.add(attribute, I18n.t('existing_username_validator.not_found')) unless Account.find_local(value.strip.gsub(/\A@/, ''))
record.errors.add(attribute, I18n.t('existing_username_validator.not_found')) if usernames_with_no_accounts.any? || usernames_and_domains.size > 1
end
end
end

View File

@ -15,6 +15,6 @@ class HtmlValidator < ActiveModel::EachValidator
def html_errors(str)
fragment = Nokogiri::HTML.fragment(options[:wrap_with] ? "<#{options[:wrap_with]}>#{str}</#{options[:wrap_with]}>" : str)
fragment.errors.select { |error| ERROR_RE =~ error.message }
fragment.errors.select { |error| ERROR_RE.match?(error.message) }
end
end

View File

@ -2,7 +2,7 @@
class NoteLengthValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors.add(attribute, I18n.t('statuses.over_character_limit', max: options[:maximum])) if too_long?(value)
record.errors.add(attribute, :too_long, message: I18n.t('statuses.over_character_limit', max: options[:maximum]), count: options[:maximum]) if too_long?(value)
end
private
@ -15,7 +15,7 @@ class NoteLengthValidator < ActiveModel::EachValidator
return '' if value.nil?
value.dup.tap do |new_text|
new_text.gsub!(FetchLinkCardService::URL_PATTERN, 'x' * 23)
new_text.gsub!(FetchLinkCardService::URL_PATTERN, StatusLengthValidator::URL_PLACEHOLDER)
new_text.gsub!(Account::MENTION_RE, '@\2')
end
end

View File

@ -2,6 +2,7 @@
class StatusLengthValidator < ActiveModel::Validator
MAX_CHARS = (ENV['MAX_TOOT_CHARS'] || 500).to_i
URL_PLACEHOLDER = "\1#{'x' * 23}"
def validate(status)
return unless status.local? && !status.reblog?
@ -28,7 +29,7 @@ class StatusLengthValidator < ActiveModel::Validator
return '' if @status.text.nil?
@status.text.dup.tap do |new_text|
new_text.gsub!(FetchLinkCardService::URL_PATTERN, 'x' * 23)
new_text.gsub!(FetchLinkCardService::URL_PATTERN, URL_PLACEHOLDER)
new_text.gsub!(Account::MENTION_RE, '@\2')
end
end

View File

@ -4,7 +4,7 @@
class UniqueUsernameValidator < ActiveModel::Validator
def validate(account)
return if account.username.nil?
return if account.username.blank?
normalized_username = account.username.downcase
normalized_domain = account.domain&.downcase

View File

@ -3,9 +3,10 @@
class UnreservedUsernameValidator < ActiveModel::Validator
def validate(account)
@username = account.username
return if @username.nil?
account.errors.add(:username, I18n.t('accounts.reserved_username')) if reserved_username?
return if @username.blank?
account.errors.add(:username, :reserved) if reserved_username?
end
private

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
class UrlValidator < ActiveModel::EachValidator
class URLValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors.add(attribute, I18n.t('applications.invalid_url')) unless compliant?(value)
end