#45845 closed defect (bug) (fixed)
Use get_user_by in check_password_reset_key
| Reported by: | spacedmonkey | Owned by: | SergeyBiryukov |
|---|---|---|---|
| Priority: | normal | Milestone: | 5.3 |
| Component: | Users | Version: | 3.1 |
| Severity: | normal | Keywords: | good-first-bug has-patch |
| Cc: | Focuses: | performance |
Description
In check_password_reset_key, there is an uncached call to users table. This could easily be replaced with get_user_by that is cached.
Attachments (3)
Change History (27)
This ticket was mentioned in Slack in #core by david.baumwald. View the logs.
8 years ago
#4
follow-up:
↓ 5
@
8 years ago
This looks good to me, I would like to see the redundant checking changed though to be just a single check and error return.
If nobody is available to update the patch I will try and get it done in the next few days :)
#5
in reply to: ↑ 4
@
8 years ago
Replying to williampatton:
This looks good to me, I would like to see the redundant checking changed though to be just a single check and error return.
If nobody is available to update the patch I will try and get it done in the next few days :)
Which checks do you think should be condensed?
#6
@
8 years ago
@davidbaumwald
The if ( false === $user ) is followed up by casting data to a different $var and then testing if ( ! $row ). I think we could have both tests performed in a single block.
if ( false === $user || ! $user->data ) could work here instead. Since the same error is thrown on both the tests and no additional context is added to the error message I would prefer to test both at the same time is all.
#8
follow-up:
↓ 10
@
8 years ago
- Resolution fixed
- Status closed → reopened
Reopening this because there are some failed unit tests resulting.
I have to step away but wanted to add what I have found so far. I'm not sure what exactly is happening yet, but deleting the user's cache with wp_delete_cache() results in this test passing.
#10
in reply to: ↑ 8
@
8 years ago
Replying to desrosj:
Reopening this because there are some failed unit tests resulting.
I have to step away but wanted to add what I have found so far. I'm not sure what exactly is happening yet, but deleting the user's cache with
wp_delete_cache()results in this test passing.
So, should the cache be cleared before the test case so that fresh results are fetched when get_user_by is called?
#11
@
8 years ago
After digging into this a bit more, caching is definitely the cause of the failure. Series of events as follows:
- User row is updated in the database with a generated activation key.
- Assertion that
check_password_reset_keyis notWP_Errorfails.
Failure is due to the updated code using cached user data. At the time of the above assertion, the user_activation_key is empty.
Expanding upon what @desrosj added, if I add clean_user_cache right after the activation key is created, the tests pass. Maybe that's the solution?
#12
follow-up:
↓ 13
@
8 years ago
@davidbaumwald I haven’t gotten to return to this yet, but my thinking was that digging a bit deeper to understand why the cache does not need to be cleared for other similar tests to ensure there is not a bigger issue buried in these changes somewhere was a good idea.
#13
in reply to: ↑ 12
@
8 years ago
Replying to desrosj:
@davidbaumwald I haven’t gotten to return to this yet, but my thinking was that digging a bit deeper to understand why the cache does not need to be cleared for other similar tests to ensure there is not a bigger issue buried in these changes somewhere was a good idea.
@desrosj That's a good idea. In scanning the tests in auth.php as an example, I see reasons why this test sticks out as having an issue with caching.
All subsequent tests in the file that call check_password_reset_key are looking for expected errors. However, they are just assertInstanceOf using WP_Error. They aren't checking the specific error. Since the user is cached and the user_activation_key is empty, they will pass these assertions, albeit for the wrong reasons.
There is a preceding test case for test_password_length_limit in which get_user_by is also referenced. That test passses but that's because the user cache is reset by the wp_set_password before assertions are made.
Let me know if you'd like me to dig into anything else. Happy to help.
This ticket was mentioned in Slack in #core by david.baumwald. View the logs.
8 years ago
#15
@
8 years ago
Adding to my notes, calling clean_user_cache in the case after the DB update would clear only the user cache without affecting all other caches.
This ticket was mentioned in Slack in #core by audrasjb. View the logs.
8 years ago
This ticket was mentioned in Slack in #core by jeffpaul. View the logs.
8 years ago
#19
@
7 years ago
Thanks for the feedback @desrosj . Really helped.
In 45845.3.diff fixes the tests. Just calling clean_user_cache makes the tests pass. I personally believe the old tests were invalid and this fix is fine. Not sure if this breaking change.
I am going to leave this up to @SergeyBiryukov to commit in 5.2 or punt.
#20
@
7 years ago
- Milestone 5.2 → 5.3
The patch needs reviewing, with 5.2 RC1 due out today, I'm bumping it to 5.3.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Patch with suggested fix