-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: ensure generated passwords have correct characters when mix_case & special_characters enabled #2533
Conversation
0f638d5
to
48902c6
Compare
I wonder if it might be better to simplify the password generation code:
|
i was thinking something along these lines too.. it does currently seem to be more convoluted than it probably needs to be. i'll give simplifying it a go. |
fa96811
to
dfdfc0b
Compare
hey @Zeragamba - have made some changes to ensure that we get the correct number of each character. noticed that the it currently does not error when max_length < min_length so maintained this behaviour. i'm not sure if it was intentionally allowed... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still feel like the password generation can still be made a lot simplier.
There's lots of extra work to keep track of the number of different types, and specific goals for each type, when we only really care about there being at least one of each time.
I was hoping for something more like this:
types = [ :upper, :lower, :special, :spaces ]
password = ""
character_bag = []
if types.include?(:lower)
lower_chars = ('a'..'z').to_a
password += lower_chars[rand(lower_chars.count - 1)]
character_bag += lower_chars
end
#... repeat for other types
target_length = rand(min_length..max_length)
while password.length < target_length
password += character_bag[rand(character_bag.count - 1)]
end
return password.split.shuffle.join
48641d3
to
3c17192
Compare
thanks, have just updated... hopefully more in line with what you had in mind. i didn't handle upper & lower case as separate types and instead considered also decided to use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great, @tiff-o thank you so much for your work on this! 😄
I left a couple of suggestions. Let me know what you think.
What do you think of updating the password docs to reflect the min_length
required for mix_case
and special_characters
?
Lines 34 to 39 in 9134280
# Keyword arguments: min_length, max_length, mix_case, special_characters | |
Faker::Internet.password #=> "Vg5mSvY1UeRg7" | |
Faker::Internet.password(min_length: 8) #=> "YfGjIk0hGzDqS0" | |
Faker::Internet.password(min_length: 10, max_length: 20) #=> "EoC9ShWd1hWq4vBgFw" | |
Faker::Internet.password(min_length: 10, max_length: 20, mix_case: true) #=> "3k5qS15aNmG" | |
Faker::Internet.password(min_length: 10, max_length: 20, mix_case: true, special_characters: true) #=> "*%NkOnJsH4" |
lib/faker/default/internet.rb
Outdated
diff_rand = rand(diff_length + 1) | ||
temp += Lorem.characters(number: diff_rand) | ||
end | ||
types = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At a first glance, types
does not share too much details about what's used for. Perhaps character_types
or something along those lines would clarify its use here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh yes... i see what you mean! types
was initially used for :upper
, :lower
etc but not anymore so i should have updated the name. what do you think of config
/ configuration
to match the error message?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
character_types
would be my preference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think character_types
gives us a better idea of what it is doing.
thanks @stefannibrasil! will also update the docs 👍 |
lib/faker/default/internet.rb
Outdated
diff_rand = rand(diff_length + 1) | ||
temp += Lorem.characters(number: diff_rand) | ||
end | ||
types = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
character_types
would be my preference
lib/faker/default/internet.rb
Outdated
types << :mix_case | ||
min_min_length += 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to split this into :upper and :lower, with :lower as a default if mix_case is false.
The generator params could also be updated to have options { upper: true, lower: true }
and have { mixed_case: true }
be an alias for that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The generator params could also be updated to have options
{ upper: true, lower: true }
and have{ mixed_case: true }
be an alias for that
hey @Zeragamba - would you mind please clarifying what you mean by this? have tried with variations of the below but don't think i'm on the right track...
def password(min_length: 8, max_length: 16, special_characters: false, mix_case: true, options: {} )
...
options[:lower] = true
options[:upper] = true if mix_case
options[:special_character] if special_characters
...
def password(min_length: 8, max_length: 16, special_characters: false, lower: true, upper: true)
...
mix_case = true if lower && upper
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Zeragamba what do you think of this suggestion being done in a follow up PR? I see those as improvements that could be added later, and don't need to block this PR. For now, I feel like the priority is to fix the bug. What do you think?
lib/faker/default/internet.rb
Outdated
target_length = rand(min_length..max_length) | ||
|
||
password = [] | ||
character_bag = Lorem.characters(number: target_length).chars |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would increase the probablity of those letters being more common in the final password. If the bag ends up being empty, then the user did not specify any types to use and thus should be an error.
lib/faker/default/internet.rb
Outdated
|
||
temp | ||
password.shuffle.join |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you add a test to make sure the password is same when the same random seed is used?
hi @tiff-o this is looking like it's going in a great direction. Do you need any help? I'd love to see your work merged. Thanks! |
hey @stefannibrasil - thanks for the nudge & apologies for letting this go cold. have had a bit on but will be able to take another look at this in the next few days and let you know if any questions. appreciate your patience! |
hey @tiff-o I think this PR is in a good shape to be merged after it's rebased. Any other improvements can be done in a follow up PR (we can open a new issue for it, for example). I don't want this one to stay open for too long since it solves the bug, and we can improve on it later. What do you think? |
Hey @stefannibrasil - that sounds good, thanks! I can't get to my computer right now but can rebase and tag you for review within the next 24 hours. Does that work? |
Absolutely! Just a reminder to add the tests that @Zeragamba mentioned. Thank you! |
…_characters enabled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much @tiff-o 💪 🎉
I'm going to merge this now. If you have any other improvements that you wanted to make, feel free to open a new PR 💯
amazing, will do. thanks @stefannibrasil! |
thanks @tiff-o for working on this! 🙏 |
Summary
Previously, when mix_case and special_characters were enabled, the generated password would sometimes exclude the mix_case characters because they were being overwritten by special characters instead.
This PR ensures that when mix_case and special_characters are both true (unless the generated password length is not enough to include all), the generated password includes at least:
Should the generated password not allow for this (e.g. max_length is 3 or less), then raise an error.
Fixes Issue #2512