Scenario:
After a user's password has expired, after 90 days for example, their account is timestamped blocked in the expiration table. If blocking accounts is selected, the next cron will block that user's access.
Then a site administrator tries to unblock a blocked user by going to the default user node edit form selecting "Active" and clicking save.
This process will unblock the user (user status = 1) until the next cron run.
Issue:
The next Password Policy cron will see the blocked timestamp and block the user (user status = 0).
The hook_user_update in Password Policy does not recognize the user status active/blocked being changed. The $edit['status'] and $account->status will have the same value because the user node will already have been saved at this time. The _password_policy_unblock() will not be called. And if it was called, the user node would be saved again because there is a user_save() in this function. This would create another user save cycle.
My suggestion:
I created a patch that contains another check in the hook_user_update() that compares $account->status and $account->original->status, and timestamps unblocked if applicable.
This allows a site administrator to unblock a user for the 24h allowance to get a password reset.
My situation has multiple thousands of users and multiple crons per hour. The unblock feature of expired accounts is a table without search capabilities and can be cumbersome to use with thousands of users.
Version: 7.x-1.11
Comments
Comment #2
mikebarkas commentedComment #3
mikebarkas commentedAttaching patch.
Comment #5
mikebarkas commentedChanged directory location for patch.
Comment #6
mikebarkas commentedSetting this to needs review.
Comment #8
mikebarkas commentedFix directory location of patch file.
Setting to needs review.
Comment #9
aohrvetpv commentedThank you for the report and patch. Reviewing this I think there may be some code in the module that could be eliminated/changed to simplify the fix. The expiration code is a problem spot in this module and I have been working locally to refactor it.
First, here is a test method to reproduce the problem as you described it. Testbot failure expected. I think your patch will cause the tests to pass but I haven't yet tried.
Setting to bug report as this seems to me a bug. Accounts aren't supposed to be reblocked until the 24-hour window has elapsed.
Comment #11
aohrvetpv commentedMerged patch in #8 with test method that reproduces problem in #9.
Comment #13
aohrvetpv commentedPatch in #8 does not seem to fix the problem.
Comment #14
aohrvetpv commentedMy mistake, I did not merge the patch in #8 properly.
The patch in #8 was against 7.x-1.11. In 7.x-1.x-dev,
_password_policy_get_request_time()and_password_policy_get_current_time()are now used in place ofREQUEST_TIMEandtime(). So I just needed to changetime()to_password_policy_get_request_time().Comment #15
aohrvetpv commentedAgain merged patch in #8 with test method that reproduces problem in #9.
Comment #16
aohrvetpv commentedThis patch eliminates the code duplication in #8 between
_password_policy_unblock()and_password_policy_unblock_from_user_edit_form(). The former is removed and the latter is renamed to_password_policy_handle_unblock(). (It does not actually unblock the user; it just responds to the unblocking.)Unblocking (i.e., setting status to 1) is only directly done by this module when the Password Policy Expired Accounts UI is used.
This code has also been removed:
I do not see the circumstances in which that condition would evaluate true. I am suspecting it is a useless relic from the D6 version of this module. Please correct me if it does have a purpose.
With this patch, a DB query is made redundantly when a user is unblocked via the Expired Accounts UI. I think since users are unblocked individually via that UI, it is not a performance issue.
Comment #17
aohrvetpv commentedA to-do: Remove code duplication between
testExpiration()andtestUnblockingExpiredAccountViaUserEditForm()methods.Comment #18
aohrvetpv commentedSimplified test method. (This completes the to-do in #17, I think).
Comment #19
aohrvetpv commentedNote that this probably does not fix all problems with unblocking users blocked due to expiration:
#2468449: Cannot unblock reblocked expired account
Comment #21
mikebarkas commented@AohRveTPV thanks for you help with this issue.
Comment #23
aohrvetpv commentedComment #24
aohrvetpv commentedComment #25
aohrvetpv commented6.x-1.x is no longer supported.