-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Avoid updating password hash when request with simple password scheme #5820
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
Conversation
rnewson
left a comment
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.
good fine on the root cause of the spurious password "upgrades". I have some style nits to address first though.
| {upgrade_password_hash, Req, UserName, Password, UserProps, AuthModule, AuthCtx} -> | ||
| couch_log:notice("upgrading stored password hash for '~s' (~p)", [UserName, AuthCtx]), | ||
| upgrade_password_hash(Req, UserName, Password, UserProps, AuthModule, AuthCtx), | ||
| ?MODULE:upgrade_password_hash(Req, UserName, Password, UserProps, AuthModule, AuthCtx), |
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.
again, not sure why we'd force ourselves over the newer module for this function
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.
For testing only. Use meck:num_calls(couch_password_hasher, upgrade_password_hash, ['_', '_', '_', '_', '_', '_']). to count how many times the function has been called.
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 (careful) use of module-qualified function calls is an important part of live upgrades (I appreciate Cloudant doesn't do them anymore but others might). I don't think it's wise to abuse it for testing.
Perhaps the module needs some rearranging to make it more testable but, for example, you could call upgrade_password_hash/6 in an eunit tests declared in this file rather than the test/eunit hierarchy, and that way we also don't need to export them.
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 ?MODULE: and export statements have been removed.
Instead, using meck:called/3 to check if the handle_cast({upgrade_password_hash, ...}, ...) function has been called.
66ec097 to
7db1689
Compare
| {upgrade_password_hash, Req, UserName, Password, UserProps, AuthModule, AuthCtx} -> | ||
| couch_log:notice("upgrading stored password hash for '~s' (~p)", [UserName, AuthCtx]), | ||
| upgrade_password_hash(Req, UserName, Password, UserProps, AuthModule, AuthCtx), | ||
| ?MODULE:upgrade_password_hash(Req, UserName, Password, UserProps, AuthModule, AuthCtx), |
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 (careful) use of module-qualified function calls is an important part of live upgrades (I appreciate Cloudant doesn't do them anymore but others might). I don't think it's wise to abuse it for testing.
Perhaps the module needs some rearranging to make it more testable but, for example, you could call upgrade_password_hash/6 in an eunit tests declared in this file rather than the test/eunit hierarchy, and that way we also don't need to export them.
013be30 to
f98c848
Compare
|
I think the needs_upgrade logic is; case {TargetScheme, TargetIterations, TargetPRF} of
{CurrentScheme, _, _} when CurrentScheme == <<"simple">> ->
false;
{CurrentScheme, CurrentIterations, CurrentPRF} when CurrentScheme == <<"pbkdf2">> ->
false;
{_, _, _} ->
true
end.
The original bug (by me) is insisting that TargetIterations matches CurrentIterations. You rightly point out that CurrentIterations will be undefined (which is correct for "simple"), but TargetIterations will be a number (but is only relevant for the pbkdf2 algorithm). |
f98c848 to
0cd1ac8
Compare
When using the `simple` password scheme, the number of iterations is `undefined`, so the user's password hash is updated every time when a new request is made using user's authentication credentials. Add a case statement to avoid this situation.
0cd1ac8 to
2b98fa5
Compare
Overview
When using the
simplepassword scheme, the number of iterations isundefined, so the user's password hash is updated every time when a new request is made using user's authentication credentials.Add a case statement to avoid this situation.
Testing recommendations
make eunit apps=couch suites=couch_passwords_hasher_testsRelated Issues or Pull Requests
Checklist
rel/overlay/etc/default.inisrc/docsfolder