mirror of
https://github.com/discourse/discourse.git
synced 2024-11-25 18:30:26 -06:00
51 lines
1.5 KiB
Ruby
51 lines
1.5 KiB
Ruby
|
# CommonPasswords will check a given password against a list of the most commonly used passwords.
|
||
|
# The list comes from https://xato.net/passwords/more-top-worst-passwords/#.UrR1AHmpxs4
|
||
|
# The list is stored in Redis at a key that is shared by all sites in a multisite config.
|
||
|
#
|
||
|
# If the password file is changed, you need to add a migration that deletes the list from redis
|
||
|
# so it gets re-populated:
|
||
|
#
|
||
|
# $redis.without_namespace.del CommonPasswords::LIST_KEY
|
||
|
|
||
|
class CommonPasswords
|
||
|
|
||
|
PASSWORD_FILE = File.join(Rails.root, 'lib', 'common_passwords', '10k-common-passwords.txt')
|
||
|
LIST_KEY = 'discourse-common-passwords'
|
||
|
|
||
|
@mutex = Mutex.new
|
||
|
|
||
|
def self.common_password?(password)
|
||
|
return false unless password.present?
|
||
|
password_list.include?(password)
|
||
|
end
|
||
|
|
||
|
|
||
|
private
|
||
|
|
||
|
class RedisPasswordList
|
||
|
def include?(password)
|
||
|
CommonPasswords.redis.sismember CommonPasswords::LIST_KEY, password
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def self.password_list
|
||
|
@mutex.synchronize do
|
||
|
load_passwords unless redis.exists(LIST_KEY)
|
||
|
end
|
||
|
RedisPasswordList.new
|
||
|
end
|
||
|
|
||
|
def self.redis
|
||
|
$redis.without_namespace
|
||
|
end
|
||
|
|
||
|
def self.load_passwords
|
||
|
passwords = File.readlines(PASSWORD_FILE)
|
||
|
redis.sadd LIST_KEY, passwords[0,5000].map!(&:chomp)
|
||
|
rescue Errno::ENOENT
|
||
|
# tolerate this so we don't block signups
|
||
|
Rails.logger.error "Common passwords file #{PASSWORD_FILE} is not found! Common password checking is skipped."
|
||
|
end
|
||
|
|
||
|
end
|