Problem/Motivation
There is a need to control when the password policy table is displayed. Similar to how Drupal core has a configuration to toggle password suggestions on and off, Password Policy currently lacks the means to accomplish the same task.
There are a couple of reasons for why this is needed:
1: Offer more control of what gets displayed to the end user, and give a more "Drupal" or "out of the box" feel. When a table is configured to not display, instead present a list of Drupal error messages to indicate why a password failed validation.
2: The concept of running policy validation vs showing the table is becoming fractured in the code, so this is an effort to define and delineate when each of the events gets run. As in reason 1, there is a case where the validation is desired, but not the table output.
Proposed resolution
Add a configuration per policy to define when the policy table is shown. In the event of conflicting settings (e.g. policy A shows, policy B doesn't show, role is contained in both policies), the "show policy" setting will take precedence.
Then decouple the table display from the validation.
Incidentally, as part of this code change, it made sense to integrate the changes proposed here: #2735943: Administrators always bypass password policies, since the validation/table logic was being de-coupled in this issue and was trivial to add.
Remaining tasks
Submit patch, review patch.
User interface changes
A new checkbox offered on the first form of the wizard. Default is "show policy table".
API changes
None.
Data model changes
Updated the schema and password policy entity to include the new "show_table_policy" setting.
| Comment | File | Size | Author |
|---|---|---|---|
| #69 | policy_B_selected_to_not_show.png | 92.06 KB | sophiavs |
| #69 | both_policies_showing.png | 101.53 KB | sophiavs |
| #69 | policy_A_and_B_selected_to_not_show.png | 87.98 KB | sophiavs |
| #48 | password_policy-decouple_display_policy_table_policy_validation-2849271-48.patch | 21.71 KB | nigelcunningham |
| #47 | interdiff_46-47.txt | 965 bytes | thomwilhelm |
Issue fork password_policy-2849271
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
mroycroft commentedAdded patch file. A few notes about some of the other changes:
Comment #3
mroycroft commentedComment #4
nick.james commentedI performed a code review for the changes suggested here and they look good to me.
Comment #5
nerdsteinI have been reviewing this issue and need to some clarity before proceeding. I am all for providing a higher level of configuration for the current adopted behavior, so I'm sure this will be fine. I especially like the "decoupling" of separating discrete things (tables, errors, validation logic, etc) from the actions (user edit, user reset, etc) such that there can be more flexibility.
From reading above, it seems like my interpretation of the goal may differ from the proposed implementation. I'm not clear on how decoupling (which I view as advantageous for the technical implementation) led to new configuration for a policy. I don't fully understand what this configuration is affording either (I didn't relate to the analogy cleanly). Can you describe to me a user story in which this configuration helps? I'm leary about "turning off" a display of policy validation which may make it less clear to the user why their password failed.
It may be something like, "As an authenticated user, I want to be able to turn off table validation and only receive an error message". Is this correct?
RE: "3. Removed the changes of the element weights. This seemed like an overreach of this module, and offered no functional advantage. If there's a compelling reason this should not be changed, please let me know." -> This is fine as long as as the module-related data showed up in a relevant place on the respective forms. I had to reorder it before by adding weights to ensure the policy-related information showed up near/close to the password.
Code review comments:
1. Shouldn't this always run? I doubt we want users to not have any validation. We may tailor *where* or *how* the errors get rendered (see comments above) but the validation still occurs, no?
2. I notice we are removing the permission for "bypass password policies" which is good for the other admin user role issue. Is the other issue updated?
Comment #6
mroycroft commentedThanks for looking at the proposed changes.
For a story type of perspective, the persona would be an administrator I would think.
"As a user with permission to administer Password Policy configuration, I have the means to configure whether the password policy table is displayed during password validation."
For the user who is on the receiving end of the validation, it still rings true that they have a means to see how and when their password does not meet the configured policies. One case shows a table and Drupal error message(s), and the other shows only Drupal error message(s).
Thanks for the insight on why the weights were changed. There is certainly a larger issue with how account fields are managed on the user entity, such as this issue: #1176568: Split up and change "User name and password" field. I'm ok reverting the changes to the weights, as it's still completely possible for a developer to override them if further customization is desired on their own site.
For code review item 1, I think I came up with a lousy name for the function. I'm open to suggestions, but to answer the question, there are certainly times when the policy validation should not run. If a user does not have a role that is captured in a password policy, then the validation should not run.
For code review item 2, I should have updated that ticket, my apologies. I'll leave a comment on there for now.
Something not mentioned here, but I wouldn't mind making some tweaks to accommodate:
1. Phase out the PHP logical
and. It's not as readable or clear as PHP&&, and where it's currently used, evaluates the same.2. Extracting one of the early checks in the password policy table and roll it into the method which checks if validation should run.
$form['#form_id'] == 'user_register_form' && $config->get('verify_mail'). Something that wasn't entirely clear to me in the code was if it was trying to shut off the table, validation, or both. The code accounted for both cases, but it wasn't clear if it was done for completeness, or necessity. One side effect, it seems if the configurationverify_mailis set, then password policy would not ever be able to run on the user add page when an administrator is manually creating a user, regardless of policy settings.Comment #7
nerdsteinI like both recommendations you have in points 1 and 2.
For the name of the function, maybe we should just call it "checkPasswordPolicyInvocation" or "checkPasswordPolicyContext" something similar. In lieu of a function callback (which is very procedural), I'm wondering if this should be put into a service (new or existing). If this service is in the Password Policy module, this would simplify the naming convention to something like, "checkInvocation", "checkContext", or even something as simple as "shouldRun". Again, these are just suggestions but hopefully they trigger some idea you like (or it leads to something).
In terms of decoupling, we should verify there are three separate functions: one that performs the checks (and returns an array of potential issues), a processor for the error message generation, and a processor for the table generation. The new feature you are proposing would be a lot simpler (a condition wrapping the table generation function) and both functions for the optional table and the error message would leverage the same checking function that returns the errors.
I'm going to divert my attention to the other "needs review" issues but will circle back to this if you are able to submit a new patch.
Comment #8
nerdsteinComment #9
0sarah0al commentedHi
I have been using this patch for a while, but it needs to be updated for password_policy version 3.0-alpha4. The patch cannot be applied on this version.
Thanks
Comment #10
tatarbjreroll and some other tests, maybe further work is needed, i'm assigning it to me to work on it
Comment #11
tatarbjAs a first result, i've rolled back the patch on 8.x-3.0-alpha4, also the highlighted issue with 'and' in conditions i've replaced it everywhere to the standards suggested && - and i did the same with 'or' changing it to ||.
I'm still checking the rest of the things from your comments guys, also will check the tests and adapt the new property to them.
Cheers,
Balazs.
Comment #12
volegerA few notes that I had seen from that patch:
Should this function stored in the
.modulefile?I prefer to move this functionality into the service with the related service injection.
This should be updated regarding previous suggestion.
Changes for property of
policy_constraintsconfiguration schema. Should be reverted.Should 'bypass password policies' permission check be removed from the functionality?
Comment #13
tatarbjHey folks,
sorry for disappearing in the last days, now I've made the mentioned changes from comment#12, as code got improved for showing the table with a different condition then checking the permission that we want to remove from the module, for now I've put it back and will follow it under https://www.drupal.org/project/password_policy/issues/2947985
Cheers,
Balazs.
Comment #14
tatarbji just update the interdiff to a correct one (removed the header)
Comment #15
volegerA little bit changes here.
Added plugin manager to handle visibility rules. I also had added the abstraction of weight to have a possibility to change rules order based on the context.
Comment #16
volegerMissed one thing.
Comment #17
nerdsteinThanks, all for working on this. Here are some comments:
1. I am curious why we're switching all the "and" and "ors" in this patch? Is this a coding standard recommendation? Could this please be separated from this patch?
2. I like the cleanup of the interface documents, thank you.
3. In the new plugin manager, this comment doesn't seem to be accurate for what the code is doing:
Isn't the function to process the plugins by weight to determine if the table should be shown?
4. Can the new visibility plugins be turned on / off (enabled / disabled)?
5. Is there a config form to weight the new visibility plugins? How is the weight configured?
6. Can we please have some automated tests added to test the behavior of the new plugin system?
Comment #18
kevin.dutra commentedReroll of #16 for Alpha 5
Comment #19
kevin.dutra commentedWhoops! For real this time. :)
Comment #20
jasonluttrellNeither of the last two patches (#16 and #19) work on the most recent version I downloaded. Is there any chance of getting a more up-to-date update?
Comment #21
apathak commentedHello,
Are the patches being considered for the following scenario?
=======================================
As you can see in the image (Repeated_Policy.png), we have two separate password policies, "Strong" and "Loose" - that are causing repetition when a certain type of user is created, because "authenticated user" is checked by default.
So, let's say a password policy "A" is created for a type of role: "role_A" and another password policy "B" created for "authenticated user" and other types of roles.
Whenever a user is created of type "role_A", it picks up the policies of both "A" and "B" because "authenticated user" is checked by default.
This is demonstrated in the screenshot - "Loose" and "Strong" being the password policies.
Is there a way around this repetition? We would like different policies for different roles. Basic Authenticated users should not have the same requirements as Admin and Content Editors.
Comment #22
apathak commentedPatches from comments #16 and #19 are failing to apply.
In any case, could some one please answer my question from #21?
Comment #23
jeroentPatch attached fixes the current failing tests.
Comment #24
jeroentComment #25
jeroent17.1: Fixed.
17.3: Seems correct. This still needs to be fixed.
17.4: There is no user interface to do this. But it can using some custom code.
17.5: The weight is configured in code. But instead of a method I would suggest moving this to the annotation.
17.6: Automated tests still need to be added.
Comment #26
jeroentAlso, is there a reason why we're using the plugin pattern to show/hide the table? It seems to add a lot of complexity, to replace a function that used to be 20 lines of code...
Comment #27
jeroentProvided some test coverage.
Comment #28
jeroentHmm, seems something was wrong with the test-only patch.
Comment #29
jeroentRemoved the plugin manager for the visibility rules since imo this is adding too much complexity for a small piece of code.
Comment #30
ant1Needs reroll due to #3064853: Refactor _password_policy_constraints_validate().
Comment #31
rpayanmComment #33
ant1#31 doesn't apply correctly.
Comment #34
vsujeetkumar commentedComment #35
vsujeetkumar commentedRe-roll patch created, Please review.
Comment #36
ant1The patch does apply and I'm seeing the configuration setting, but Password Policy itself has disappeared from the forms.
I'm not seeing any errors so I can't pinpoint the exact problem. Unless I forgot something...
Comment #37
tuchoThe previous patches uses the result of \Drupal\password_policy\PasswordPolicyValidator::buildPasswordPolicyConstraintsTableRows as the #items key for the item_list render array.
The structure of the data returned by the method of the password_policy.validator service does not match with the structure expected by the template_preprocess_item_list function showing innecessary information to the user. For example, the row classes will be listed.
The attached patch extracts the
['data']['status']value of each row and then only the status of each policy will be shown.I also attached an interdiff with #34.
Comment #38
ant1Table display does show, but checking it off removes the policy as a whole.
Someone else has to test this and say that I am wrong. Maybe I've overidden something without my own knowledge...
Comment #39
tuchoHi @antoineh!
We're using this patch on our developments and the policies works as expected.
Maybe the selected roles does not match your users? Or there is a bug on one of the policies you're using?
Regards
Cristian
Comment #40
ant1I misinterpreted this issue, that's why I expected a different result and thought the patch didn't work.
My apologies for that.
Testing the patch does seem to fix this issue.
Comment #41
edmund.dunn commented#37 worked for me.
Comment #42
cslevy commentedI created anothe patch to based on #37 to fix some warnings in case of Account Field split module is used.
Comment #44
cslevy commentedWrong patch added in the previous comment . Uploading new patch
Comment #45
cslevy commentedFor some reason this patch from #43 doesn't apply for me with composer. I created another one.
Sorry for the mess.
The interdiff is the same.
Comment #46
cslevy commentedAdded also the possibility to alter the Constraints table rows
Comment #47
thomwilhelm commentedThis patch worked great, except for I found that validationShouldRun() never ran for a rule we had setup for our site. This was because our rule was setup to target only the "authenticated" role. However when a user is logged out, all they have is the anonymous role, which can never match a password policy rule, as you can't target the anonymous role.
To fix, I think we should always search for rules that match the authenticated role, as all users will have this post register.
Comment #48
nigelcunningham commentedHere is a reroll of the patch against current 8.x-3.x (526f77e2ffa7f7dd6a6c51591460928edb16d758).
Comment #51
marcos_lima commentedHi all!
I changed the approach to MR from patch #48.
Comment #52
j. commentedPatch #48 works great for my use case, on 9.2.7. Thanks! This has saved me loads of time.
Comment #53
paulocsLets postpone this issue while #3054412: Make policy summary table easier to customise is not committed.
Comment #54
paulocsAs #3054412: Make policy summary table easier to customise was committed, I'm updating the issue status.
Comment #55
jeroentComment #56
nigelcunningham commentedAnother rebase.
Comment #57
andregp commentedI'll try a manual test to review the last MR
Comment #58
andregp commentedIt seems that all previous comments were addressed except for the question in #21 that wasn't answered. So answering @apathak, in my opinion the patch works as designed. If we repeat the same constraint in more than one policy and apply both policies to the same user than it's natural they would appear repeated, for example:
Policy A has constraints 1 and 2 and is applied to Admin roles
Policy B has constraint 1 and is applied to Authenticated users
The table of constraints for an Admin user would look like this:
Instead of changing this patch logic (and run the risk of making it even more complex) the site owner can solve it by simply managing better the constraints of each role and removing constraint 1 from Policy A (since it will already be applied to all authenticated users through policy B) so the Policies and the table would look like this:
Policy A has constraint 2 and is applied to Admin roles
Policy B has constraint 1 and is applied to Authenticated users
That being said I manually tested the code from the MR20 and it seems to be running well. I tested the case of two Policies to the same role with only one, both and none of them checked to be displayed, and the result was the expected in all cases (it displays the complete table if one or more policies that were applied to the role is checked to be displayed).
Comment #59
adriancid@NigelCunningham:
Merge blocked: the source branch must be rebased onto the target branch.
Comment #60
paulocsOnly removed some deprecated code added before in the MR 20!
Comment #61
dancbatista commentedI'm working in this issue!
Comment #62
dancbatista commentedI tested and the patch works fine! Rebase still needed.
Comment #63
nigelcunningham commentedI've now rebased the branch, thanks.
Comment #64
jeroentTests are failing.
Comment #65
lucasbaralmI will work on this issue.
Comment #66
paulocsPlease review.
Comment #68
sophiavs commentedI'll do the review
Comment #69
sophiavs commentedWhile running the phpcs i recieved 1 warning in src/PasswordPolicyValidator.php to use dependency injection instead of \Drupal call on line 155.
For the automated tests everything worked fine.
For the manual tests it worked as commented on #58. When one or more policy is checked to show it shows all the policies related to the role, and when all policies are not checked it didn't shows.
Comment #70
lucasscComment #71
lucasscAddressed #69: Fixed warning in src/PasswordPolicyValidator.php to use dependency injection instead of \Drupal call on line 155.
Please review this.
Comment #72
lucasbaralmI will do the review.
Comment #73
lucasbaralmI reviewed the last MR. Dependency injection has been handled by the commit of @lucassc, tests are passing and working as mentioned earlier by @sophiavs. There are only two details which were a use statement not being used and a parameter type missing, I fixed it and I'm moving to RTBC.
Comment #75
paulocs