Skip to content

Commit

Permalink
Fix UniqueUsernameValidator comparison
Browse files Browse the repository at this point in the history
Comparison was downcasing only one side, therefore if previously
existing account had a non-lowercase spelling, it would be ignored
when checking for duplicates.

New rake task `mastodon:maintenance:find_duplicate_usernames` will
help find constraint violations that might have occured from the
presence of this bug.

Bump version to 2.3.3
  • Loading branch information
Gargron committed Mar 27, 2018
1 parent 6cc432b commit 9924ca8
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 3 deletions.
2 changes: 1 addition & 1 deletion app/models/concerns/account_finder_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def initialize(username, domain)
end

def account
scoped_accounts.take
scoped_accounts.order(id: :asc).take
end

private
Expand Down
2 changes: 1 addition & 1 deletion app/validators/unique_username_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def validate(account)

normalized_username = account.username.downcase.delete('.')

scope = Account.where(domain: nil, username: normalized_username)
scope = Account.where(domain: nil).where('lower(username) = ?', normalized_username)
scope = scope.where.not(id: account.id) if account.persisted?

account.errors.add(:username, :taken) if scope.exists?
Expand Down
2 changes: 1 addition & 1 deletion lib/mastodon/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def minor
end

def patch
2
3
end

def pre
Expand Down
18 changes: 18 additions & 0 deletions lib/tasks/mastodon.rake
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,24 @@ namespace :mastodon do
LinkCrawlWorker.push_bulk status_ids
end

desc 'Find case-insensitive username duplicates of local users'
task find_duplicate_usernames: :environment do
include RoutingHelper

disable_log_stdout!

duplicate_masters = Account.find_by_sql('SELECT * FROM accounts WHERE id IN (SELECT min(id) FROM accounts WHERE domain IS NULL GROUP BY lower(username) HAVING count(*) > 1)')
pastel = Pastel.new

duplicate_masters.each do |account|
puts pastel.yellow("First of their name: ") + pastel.bold(account.username) + " (#{admin_account_url(account.id)})"

Account.where('lower(username) = ?', account.username.downcase).where.not(id: account.id).each do |duplicate|
puts " " + pastel.red("Duplicate: ") + admin_account_url(duplicate.id)
end
end
end

desc 'Remove all home feed regeneration markers'
task remove_regeneration_markers: :environment do
keys = Redis.current.keys('account:*:regeneration')
Expand Down

0 comments on commit 9924ca8

Please sign in to comment.