Require user names to be unique after unicode normalisation

As with the previous checks on case sensitivity this only affects
new users, and changes to names of existing users.
This commit is contained in:
Tom Hughes 2023-12-13 20:53:38 +00:00
parent 75042a04a1
commit c12f8959dd
5 changed files with 49 additions and 12 deletions

View file

@ -34,12 +34,13 @@
#
# Indexes
#
# users_auth_idx (auth_provider,auth_uid) UNIQUE
# users_display_name_idx (display_name) UNIQUE
# users_display_name_lower_idx (lower((display_name)::text))
# users_email_idx (email) UNIQUE
# users_email_lower_idx (lower((email)::text))
# users_home_idx (home_tile)
# users_auth_idx (auth_provider,auth_uid) UNIQUE
# users_display_name_canonical_idx (lower(NORMALIZE(display_name, NFKC)))
# users_display_name_idx (display_name) UNIQUE
# users_display_name_lower_idx (lower((display_name)::text))
# users_email_idx (email) UNIQUE
# users_email_lower_idx (lower((email)::text))
# users_home_idx (home_tile)
#
class User < ApplicationRecord
@ -91,7 +92,7 @@ class User < ApplicationRecord
validates :display_name, :presence => true, :length => 3..255,
:exclusion => %w[new terms save confirm confirm-email go_public reset-password forgot-password suspended]
validates :display_name, :if => proc { |u| u.display_name_changed? },
:uniqueness => { :case_sensitive => false }
:normalized_uniqueness => { :case_sensitive => false }
validates :display_name, :if => proc { |u| u.display_name_changed? },
:characters => { :url_safe => true },
:whitespace => { :leading => false, :trailing => false }
@ -129,7 +130,7 @@ class User < ApplicationRecord
user = find_by("email = ? OR display_name = ?", options[:username].strip, options[:username])
if user.nil?
users = where("LOWER(email) = LOWER(?) OR LOWER(display_name) = LOWER(?)", options[:username].strip, options[:username])
users = where("LOWER(email) = LOWER(?) OR LOWER(NORMALIZE(display_name, NFKC)) = LOWER(NORMALIZE(?, NFKC))", options[:username].strip, options[:username])
user = users.first if users.count == 1
end