I’m still working on password validation, and part of that is making sure a user doesn’t try to use a common password. I’ve downloaded a list of common passwords.
I’m trying to compare the user’s desired password to the text file containing 1 million common passwords (one password per line).
The code below works great, and is relatively fast. I’m wondering if I can get it to perform any better though? Preferably without loading the entire file into memory at once, but if that will give a large performance boost, I could be convinced…
#
# Password rarity is checked against the largest list of common passwords
# found here: https://github.com/danielmiessler/SecLists/tree/master/Passwords/Common-Credentials
#
defp validate_password_rarity(changeset, field) do
proposed_password = get_field(changeset, field)
proposed_password = "#{proposed_password}\n" # Append line break here to avoid needing to remove 1M line breaks from the stream.
common_password_stream = File.stream!(Path.join(:code.priv_dir(:my_app), "static/10-million-password-list-top-1,000,000.txt"))
|> Stream.filter(fn common_password -> proposed_password == common_password end)
|> Enum.to_list
if length(common_password_stream) == 0 do
changeset
else
add_error(changeset, field, "The given password is too common. Please choose a less common password.")
end
end