Password Policy History submodule is behaving in another way around.
If history constraint is implemented and restriction needs to be added that user cannot use last 5 passwords then it's impossible to implement. Configuration only allows using 0 if you don't want any of the previous passwords to be used. Or you can set a number, let's say 5, which means the user can use last 5 passwords but not prior to that.
This was not the behavior in the Drupal 7 version of this module.
Comment | File | Size | Author |
---|---|---|---|
#65 | 2867320-65.patch | 9.96 KB | balbeeryadav |
#64 | 2867320-64.patch | 9.96 KB | alok.tiwari |
#30 | Screen Shot 2020-08-17 at 9.42.54.png | 27.17 KB | ultrabob |
#28 | interdiff_23_28.txt | 655 bytes | iyyappan.govind |
#28 | 2867320-28.patch | 9.95 KB | iyyappan.govind |
Issue fork password_policy-2867320
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
gbisht CreditAttribution: gbisht as a volunteer and at Acquia commentedComment #3
AohRveTPV CreditAttribution: AohRveTPV commentedIn support of gulab.bisht:
Websites will not uncommonly have a restriction like "Your password must be different than your last 10 passwords."
The "History" constraint in 7.x-1.x and the "Past Passwords" constraint in 7.x-2.x make this restriction possible, by setting a value of 10 for the constraint.
The idea is the constraint coupled with expiration forces the user to regularly change their password. That, for one, provides some defense against compromise due to re-use of a password compromised from another system.
It looks like in 8.x-3.x the behavior is different. I think the 7.x form of the constraint is useful to have, and some organizational policies require it.
Comment #4
steveworley CreditAttribution: steveworley at Acquia commentedGreat work on the module! I noticed that the history constraint worked slightly differently to how it did in D7. I created a new constraint that allows the password recycle functionality that I think is defined here (while keeping the history constraint as well).
The Password Recycle constraint works by allowing you to configure how many passwords must be used before you can recycle a password. For example:
If I configure the constraint to 5.
Forgive me if this is not the right issue for this constraint.
Comment #5
AohRveTPV CreditAttribution: AohRveTPV commentedsteveworley, I haven't reviewed your patch but in your example, should the last line actually be:
Password_1 (ok)
Five passwords have been used (Password_1, Password_2, Password_3, Password_4, Password_5), so you can re-use Password_1, right?
Comment #6
steveworley CreditAttribution: steveworley at Acquia commentedYou're absolutely right! Sorry a bit of copy paste anxiety there.
Comment #7
kamkejj CreditAttribution: kamkejj at Nerdery commentedTested this patch using the dev version of the module and seems to be working fine.
Comment #8
jasonawantChanging to Needs Review to get maintainer feedback
Comment #9
AohRveTPV CreditAttribution: AohRveTPV commentedI think we should replace the existing D8 Password History constraint, which does not seem useful (or at least is unconventional), with one that has the same functionality as in the D7 branches. As I wrote in #3, the 7.x-1.x Password History constraint provides a password constraint that other, non-Drupal password policies commonly use.
It seems like the Password Recycle constraint in #4 is the same as the Password History contraint in the 7.x-1.x branch. If so, would it be fine to rename it "Password History" for consistency and replace the current Password History constraint? Or is there a reason to prefer the "Password Recycle" name?
Comment #10
gbisht CreditAttribution: gbisht as a volunteer and commentedComment #11
ultrabob CreditAttribution: ultrabob commentedI just enabled and tested this module on our soon to be launched Drupal 8 migration of a Drupal 7 site that used this module, and noticed this discrepancy. I'm writing to give a ++ to replacing the current functionality with the one described here. It would be ok to have both, but the current version is pretty unusual, so it almost seems like a good candidate for an add on module.
Comment #12
rocket777 CreditAttribution: rocket777 at EPAM Systems commentedI agree the functionality to restrict use of last N passwords should be available. Currently it is not.
i tried to use the Password Policy History, but that does not provide the needed functionality.
This issue was created almost 2 years ago what the current thinking, have the maintainers commented on this?
Comment #13
AohRveTPV CreditAttribution: AohRveTPV commentedrocket777, ultrabob, thanks for your thoughts on this. I'm also in favor of changing the history constraint to work as in the Drupal 7 versions of Password Policy, and not including the current history submodule's functionality by default in this module, since it seems like an uncommon password constraint.
The Password Recycle module for which steveworley gave a patch in #4 looks like it provides the desired functionality, if you want to try it. It could be renamed Password History and tested/reviewed. Contributions welcome, I'm uncertain when I will have time to work on this issue.
Comment #14
PCate CreditAttribution: PCate commentedAfter applying this patch to 8.x-3.0-beta1, when editing any user profile page the follow error is thrown and the page is inaccessible.
php-error ded-15106 [20-Apr-2020 14:34:27 America/New_York] Error: Cannot use object of type Drupal\user\Entity\User as array in REDACTED/docroot/modules/contrib/password_policy/password_policy_recycle/src/Plugin/PasswordConstraint/PasswordRecycle.php on line 167 #0 /mnt/www/html/hrnih/docroot/modules/contrib/password_policy/src/PasswordPolicyValidator.php(123): Drupal\password_policy_recycle\Plugin\PasswordConstraint\PasswordRecycle->validate('', Object(Drupal\user\Entity\User))
Comment #15
ultrabob CreditAttribution: ultrabob commentedI found some time to take a look tonight, and validated the report in #14. I'm attaching a patch to resolve this issue. I also tested the module briefly, and unless I'm mistaken, it may currently be suffering an off by one error. I need to check more carefully to be sure, but I set the number of passwords required between reuses to 2.
started with Original Password (OP) before installing constraints
Tried to change password to OP again, got an error from password recycle
Changed Password to P2 was successful
Tried to change password to OP. Expected an error, but was successful.
Finally, I took a look at what it will take to replace the password_policy_history constraint with the password_policy_recycle constraint. The recycle constraint currently depends on the history constraint, and uses the database schema that was established by the history constraint. This is find, and means that we basically need to merge the two under the history name. I didn't have time to work on that part tonight, and I'm not sure when I will have, but I think with this patch, the functionality should at least be testable again.
Comment #16
ultrabob CreditAttribution: ultrabob commentedBriefly looking at this while waiting for a process to finish, it appears that my "off by one error" is because each password hash is being written to the database twice.
is being fired twice, and I don't know why.
Comment #17
ultrabob CreditAttribution: ultrabob commentedThe way
operates lines up with 7.x-1.x of the module, but seems quite simple and is causing problems for me because hook_user_update is running twice and creating duplicate entries. (Aside: One other point of investigation: the 7.x-1.x version o fthe constraint used hook_user_presave instead of hook_user_update, is this significant?) It just naively writes a new hash value and timestamp to the database whenever it is called. That means that if something causes the hook_user_update hook to be called more than once in rapid succession, there is no debouncing happening. For the purposes of the password history (and recycle module) we could either adjust this behavior or the validation side behaviour.
Input side:
When a new insert_password_hash is called it checks to see if the id/has pair already exists in the database, and if it does, replace the timestamp with the current one. That would mean only one of each id/password hash combo would exist in the table, and it would always be the most recent one. This is the perfect behavior for the history constraint, it doesn't add extra rows to the database that will never be needed. If there is some case where knowing that we've reused the same password in the past is important, this behavior will clear that information out.
Validation side:
We could query for the last $password_reuse_gap_count (don't remember the real setting name) unique id/password hash combos and check to see if the new password matches that list. This would have the pro that we maintain a complete history of all passwords stored, but the cons that if the hook runs twice in quick succession we'll have a duplicate entry in the database, it just won't affect the history validation, and the table will contain significantly more rows.
I lean toward fixing this on the input side, but welcome feedback.
Comment #18
ultrabob CreditAttribution: ultrabob commentedI've made a change to debounce the password history hash write to the table (some of my assumptions in #17 were wrong, but this part is working) I was trying to get the unit tests attached to this constraint to work, but they seem to have been copied from somewhere else, and would not run at all. I've got them running now, but all the tests fail, and I have no experience with writing these tests. I can upload a patch of what I've got so far, hopefully sometime tomorrow, but would anyone more experienced with testing be able to spare a bit of time to help me get them figured out?
Comment #19
jjmackow CreditAttribution: jjmackow as a volunteer commentedI reproduced #14 after installing 8.x-3 beta 2.
The latest dev build from July 20th,2020 8.x-3.x-dev is producing the error:
The website encountered an unexpected error. Please try again later.
Error: Cannot use object of type Drupal\user\Entity\User as array in Drupal\password_policy_recycle\Plugin\PasswordConstraint\PasswordRecycle->validate() (line 167 of modules/contrib/password_policy/password_policy_recycle/src/Plugin/PasswordConstraint/PasswordRecycle.php).
Drupal\password_policy_recycle\Plugin\PasswordConstraint\PasswordRecycle->validate('', Object) (Line: 123)
Drupal\password_policy\PasswordPolicyValidator->buildPasswordPolicyConstraintsTableRows('', Object, Array) (Line: 57)
password_policy_form_user_form_alter(Array, Object, 'user_form') (Line: 539)
Drupal\Core\Extension\ModuleHandler->alter('form', Array, Object, 'user_form') (Line: 838)
Drupal\Core\Form\FormBuilder->prepareForm('user_form', Array, Object) (Line: 279)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 91)
Drupal\Core\Controller\FormController->getContentResult(Object, Object) (Line: 39)
Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 573)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 151)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 68)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 708)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Comment #20
volkswagenchickTagging this as novice for DrupalCon Global contribs day
Comment #21
kamkejj CreditAttribution: kamkejj at Nerdery for Nestle Purina PetCare - United States commentedUsing the new patch from #15 I made a couple of changes.
The signature for PasswordConstraintInterface::validate() changed at some point so updated PasswordRecycle::validate() to match and I don't think
is needed since the User object should always have an id and the addition of the UserInterface type hint.
validate($password, UserInterface $user)
Any thoughts or concerns?
Comment #22
PCate CreditAttribution: PCate commentedComment #23
kunal_singh CreditAttribution: kunal_singh at Innoraft for Drupal India Association commentedMinor change in #21 patch.
Added support for D9.
Comment #24
ultrabob CreditAttribution: ultrabob commentedI seemed to fail the password recycle check no matter how many new passwords I used before reusing. If I set the limit to 5, and started with password:
password05
I changed to:
password06
password07
password08
password09
password10
password11
then tried changing back to password05. I still got the error about violating password recycle.
Also it may be a peculiarity of my install, but I get two password history entries in the database for each password change made from the logged in user, and once when changing the password from the admin account.
Comment #25
JayKandariComment #26
iyyappan.govindWorking on this issue. Assigning to myself.
Comment #27
iyyappan.govindHi ultrabob, As per my analyse, password policy history saves two for authenticated changes the password. Becase user is called in custom submit handler in password_policy.module. We already have issue. Please look at Here. I have tested the functionality with the patch I posted.
Thanks
Comment #28
iyyappan.govindAdded the default value to configuration form because I have compared other policy configuration form, it has default value set. Please look at the inter diff. We can test this patch once the https://www.drupal.org/project/password_policy/issues/3095980 is fixed. Please review the patch. Thanks
Comment #29
iyyappan.govindComment #30
ultrabob CreditAttribution: ultrabob commentedTesting steps with password_policy_recycle installed and enabled, set to 2. No other password policy criteria set..
1. Use reset password link to set password to 10
2. observe one new entry in the password_policy_history table for this change (due to patch on issue #3095980
3. try to change password to 10 again. Observe fail warning after ajax runs and actual fail on submit
4. change password to 11
5. try to change password to 10. observe fail warning and actual fail.
6. change password to 12
7. change password to 10.
Up to this point everything works as expected. I'm so happy to see this moving forward, thank you! I have found one problem (which may be a different issue, not specific to recycle), and one more step I think we need to accomplish before this can be committed.
The issue:
If you submit the password change form while the password policy ajax is running, the password reset fails everytime with error:
The additional Step:
I agree with @AohRveTPV that it would be better to replace the history module with this recycle one. Since currently the recycle module depends on the history mosule, it seems like it could potentially be complicated to roll out a version of the module with both history and recycle, and then remove history. Even if both modules stay in place, it will confuse the interface if history has to be installed for recycle to be used. I think we should move the recycle code into the history module instead of making a new module. Optionally we could add a new module with the behavior currently in history, but the use case where current history is useful must be extremely rare.
Comment #31
iyyappan.govindHi ultrabob, Thanks for making the review. I am agree with your suggestion on replacing the history module with recycle module.
Also I am unable to reproduce the ajax issue while changing the password. Please provide video if possible. So I can reproduce the issue and fix.
Thanks
Comment #32
iyyappan.govindChanging the status to Review for reviewing of module maintainer.
Comment #33
mfrosch CreditAttribution: mfrosch commentedPatch #28 works for me.
Cheers
Comment #34
rukayya CreditAttribution: rukayya at QED42 for Drupal Association commented#28 worked well
Comment #35
the_g_bomb CreditAttribution: the_g_bomb at Cyber-Duck commentedConfirming RTBC status
Comment #38
paulocsAlso agree with @ultrabob that we should replace the PasswordHistory module.
Comment #39
paulocsComment #40
lucienchalom CreditAttribution: lucienchalom at CI&T commentedComment #41
lucienchalom CreditAttribution: lucienchalom at CI&T commentedI run in to the Error: Call to a member function select() on null in Drupal\password_policy_history\Plugin\PasswordConstraint\PasswordHistory->getHashes() (line 95 of /app/modules/contrib/password_policy/
when I tried to open the user page after configuring a password policy history.
Comment #42
paulocsComment #43
paulocsComment #44
lucienchalom CreditAttribution: lucienchalom at CI&T commentedNow it is working, thank you!
just please in password_policy_history/src/Plugin/PasswordConstraint/PasswordHistory.php add the parameter $connection on the doblock.
Comment #46
bruno.bicudoAdded the parameter $connection to the docblock as pointed in #44
Kindly review it :)
Comment #47
matheusmaciel CreditAttribution: matheusmaciel at CI&T commentedI'll try to review it!
Comment #48
matheusmaciel CreditAttribution: matheusmaciel at CI&T commentedI didn't understand if the issue's version is 8.x-3.0-alpha3 or the version that has been worked on the comments of this issue.
Comment #49
WagnerMelo CreditAttribution: WagnerMelo at CI&T commentedHello, i'll try review it.
Comment #50
WagnerMelo CreditAttribution: WagnerMelo at CI&T commentedI reviewed, and all changes that was asked, was implemented and work correctly.
So i'll change this issue to RTBC.
Comment #51
John Franklin CreditAttribution: John Franklin at Sentai Digital for Bixal commentedThanks to everyone who has contributed to this!
The only thing I would add to this patch is to reword the configuration page and error message. "Number of allowed repeated passwords" reflects the pre-patch behavior of counting repeats and it should be something that indicates none of the last n passwords can be used.
Letting the user know how many are forbidden would be nice, too. Something like "The last @count passwords cannot be reused."
Comment #52
John Franklin CreditAttribution: John Franklin at Sentai Digital for Bixal commentedWe're using Password Policy along with PRLP. I'm not sure if it is a side-effect of installing both of them or if there is still an issue since #17 above, but we get duplicate password history entries. We've added an internal patch that checks if there is already a record with the current UID and request time, and skips inserting a new record if that's the case.
Comment #53
paulocsUpdated the labels and and fixed a bug when the history configuration is set to '0' so that all passwords are checked.
Regarding #52, check if the duplicated entries bug was fixed in #3095980: Password history policy inserts password twice in password_policy_history table @John Franklin
Comment #54
the_g_bomb CreditAttribution: the_g_bomb at Cyber-Duck commentedPatch no longer applies
Comment #55
the_g_bomb CreditAttribution: the_g_bomb at Cyber-Duck commentedWrong status, sorry
Comment #56
paulocsComment #57
lucasscComment #58
the_g_bomb CreditAttribution: the_g_bomb at Cyber-Duck commentedStrangest thing.
If I use:
https://git.drupalcode.org/project/password_policy/-/merge_requests/28.p...
I get all sorts of errors
however, using:
https://git.drupalcode.org/project/password_policy/-/merge_requests/28.diff
The patch applies without issue.
Tested with the following steps and results:
Create a password policy with 1 constraint - password_policy_history_constraint
- Number of passwords that will be checked in the user password update history: 5
Create a test user account set an initial password
Edit the account and set a new password to Password_001 and click save
Edit the account and set a new password to Password_001 which fails then change it to Password_002 and click save
Edit the account and set a new password to Password_001 which fails then change it to Password_003 and click save
Edit the account and set a new password to Password_001 which fails then change it to Password_004 and click save
Edit the account and set a new password to Password_001 which fails then change it to Password_005 and click save
Edit the account and set a new password to Password_001 which fails then change it to Password_006 and click save
Edit the account and set a new password to Password_001 which is allowed and click save
Comment #59
lucasscComment #60
lucasscHi!
I applied MR !28 against 9.4.x-dev and works as it should, confirming RTBC.
Steps:
- set the number of allowed repeated passwords to 5;
- created a new user with password "pass1";
- changed new user's password to "pass2"
- tried to change new user's password to "pass1" once more: blocked with "The last 5 passwords cannot be reused" error;
- changed new user's password to "pass3";
- tried to change new user's password to "pass1" and "pass2": blocked;
- changed new user's password to "pass4"
- tried to change new user's password to "pass1", "pass2" and "pass3": blocked;
- changed new user's password to "pass5";
- tried to change new user's password to "pass1", "pass2", "pass3" and "pass4": blocked;
- changed new user's password to "pass6";
- now I was able to change new user's password to "pass1" again.
Comment #62
paulocsComment #64
alok.tiwari CreditAttribution: alok.tiwari at Srijan | A Material+ Company commentedUpdated #28 to support Drupal 10.
Only .info had to be updated.
Comment #65
balbeeryadav CreditAttribution: balbeeryadav at Srijan | A Material+ Company commented#64 is not applying.
Updated patch for #64
Comment #66
Kristen PolIf there are still issues, please open a new issue rather than update one that is already marked closed/fixed. You can link to this one. Thanks.