Centralize password check as method of 'User' objects #341
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation
Checking passwords (and setting passwords) is something that must be rock-solid.
For this it makes sense to keep as much logic of it at a single place, so you don't have to rewrite it half a dozen times with the risk of introducing a nasty bug each time.
Also bcrypt 3.1.0 introduced a new
bcrypt.checkpw(<input to check>, <hashed password>)
function that is way more intuitive than the oldbcrypt.hashpw(<input>, <hashed password>) == <hashed password>
.If you are wondering how the old one works,
bcrypt.hashpw()
reads the salt from the hashed password (bcrypt hashes save the salt in front of the actual pw hash) and hashes the clear text input using this salt. Then we compare the output with the actual hash.The new method basically still does the same in the background, but we don't need to care about it anymore, it's much more readable.
Changes
Create a new
User.check_password(<input>)
, which takes care of encoding the input strings with UTF-8 to give bcrypt the byte array it wants, and callingbcrypt.checkpw()
. It returnsTrue
for a matching password andFalse
for incorrect ones.All places where we had the complicated
bcrypt.hashpw()
construct now simply callcheckpw()
on aUser
object.If we ever need to change the hash function for passwords, this should simplify the process.
I've also added a basic test to make sure we aren't doing something majorly wrong in this method.
I've specified the minimum version of
bcrypt
we now need in therequirements-backend.txt
.Please review carefully to make sure I didn't accidentally drop a vital
not
or something in the password checks.