The logic used in hook_install() to expire the passwords of current users doesn't scale well (for sites with many users).
It should be refactored using Queue API.
Original summary
The $user->save() in hook_install() has performance issues on sites with lots of users, which means that installing this module can take a very very long time. There is a @todo to remove this code anyway, and given that I'm currently unable to install this module I thought now would be a good time to remove it...
| Comment | File | Size | Author |
|---|---|---|---|
| #18 | Do_not_set_user_fields_on_install-2983448-17.patch | 9.4 KB | piggito |
Comments
Comment #2
kalpaitch commentedComment #3
kalpaitch commentedIt's quite a tricky one to test this because it's just straight up in the cron function. Ideally would abstract the expiration of users, but keeping it simple for now.
Comment #4
kalpaitch commentedInstall time needs to be removed on uninstall.
Comment #5
keshavv commentedComment #6
zahor commented+1 on this being good. Installed and tested successfully.
Comment #7
aohrvetpv commentedThanks, this looks good to me after a first pass of reviewing.
The query for loading users in cron has grown more complex and I think it could use some inline comments to explain its parts. I will plan to add those shortly and make a couple other tweaks.
I agree with #3 that parts of the cron function should be abstracted into other functions (if that is what was meant). The function is growing too long. In the 7.x-1.x branch,
password_policy_cron()grew into like multiple hundreds of lines. :(Comment #8
aohrvetpv commentedWhy does
password_policy_install()usegmdate()for formatting the install date when thedate.formatterservice is used elsewhere for formatting the last password reset date? Seems inconsistent--maybe there's a good reason.I feel this needs tests. Functional tests can invoke cron. I don't know if there is a good way to mock time methods in Drupal 8. In 7.x-1.x, I did so by writing wrapper functions for all time functions. So, for example, if you tried to get the current time, and the expiration code was under test, it would be the phony time set by the test.
I can try to contribute some tests.
Comment #9
claudiu.cristeaI'm proposing a simpler way to solve this, without needing of a state variable. No interdiff because it's a different approach.
This is critical as breaks the module install on sites with tons of existing users.
EDIT: Of course this means that existing users will have to reset their password when the module is enabled.
Comment #10
wellsI'm looking at using this module for a site with 30k users and I ran in to issue in testing as well. The changes in this patch for
hook_install()make sense, but the changes topassword_policy_cron()do not because it would expire passwords for all users in chunks of 250 over the course of cron runs after install.Is there any good reason for this operation to happen during cron anyway? Why not just check the expiration condition on login and send the user to reset if the password is found to be expired? For initial install, a simple config variable could be set with the install time to use a fallback when the field is not yet present for a user.
I could provide a patch for this if the maintainers are on board with the change (and there is no clear advantage to doing this with cron).
Comment #11
wellsAttaching an updated version of the patch from #4. I was not able to apply that patch on the latest dev version of the module (and, incidentally, was not able to interdiff it with my patch, either). Changes in this patch are:
gmdate-- I couldn't see any reason to use that over Drupal's service (per #8).$install_time && $install_time <= $expire_date, but should be$install_time && $install_time >= $expire_dateto ensure that the policy only applies if the expire date occurs after the install time.Comment #12
wellsAnd here is a version with tests passing, to show the change... had an affect, anyway (: We still need tests of the actual change in functionality here. This test case should probably:
Comment #13
wellsComment #14
wellsHere's an updated patch with tests for this change.
Comment #15
wellsComment #16
piggito commentedRerolled last patch
Comment #18
piggito commentedThere was en error on previouse patch. Here is updated reroll.
Comment #19
shrop commented@piggito's patch in #18 is working great for Guardr installs. Thank you!
Comment #20
kalpaitch commentedI've tested this under most of the conditions I can see and it works well for me. Let's get this in!
Comment #21
tanmaykPatch in #18 works well. Also #2771129: "Field field_last_password_reset is unknown" while importing configuration on site without password_policy activated gets resolved with this patch.
Comment #22
ultimikePatch #18 applied cleanly to 3.x-dev.
Updating issue title and summary to better reflect current patch.
Comment #24
nerdsteinThank you all, this has been reviewed, tested, and merged.
Comment #26
marcelovaniCan we have a new release pls?