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.

CommentFileSizeAuthor
#69 policy_B_selected_to_not_show.png92.06 KBsophiavs
#69 both_policies_showing.png101.53 KBsophiavs
#69 policy_A_and_B_selected_to_not_show.png87.98 KBsophiavs
#58 Table_not_display.png237.62 KBandregp
#58 Table_display.png249.92 KBandregp
#48 password_policy-decouple_display_policy_table_policy_validation-2849271-48.patch21.71 KBnigelcunningham
#47 interdiff_46-47.txt965 bytesthomwilhelm
#47 password_policy-decouple_display_policy_table_policy_validation-2849271-47.patch21.1 KBthomwilhelm
#46 interdiff_44-46.txt360 bytescslevy
#46 password_policy-decouple_display_policy_table_policy_validation-2849271-46.patch20.78 KBcslevy
#45 password_policy-decouple_display_policy_table_policy_validation-2849271-44.patch20.35 KBcslevy
#44 interdiff_37-43.txt692 bytescslevy
#44 password_policy-decouple_display_policy_table_policy_validation-2849271-43.patch24.04 KBcslevy
#42 interdiff_37-42.txt692 bytescslevy
#42 password_policy-decouple_display_policy_table_policy_validation-2849271-42.patch16.48 KBcslevy
#37 interdiff-2849271-34-37.txt1.22 KBtucho
#37 password_policy-decouple_display_policy_table_policy_validation-2849271-37.patch19.86 KBtucho
#35 2849271-34.patch19.75 KBvsujeetkumar
#31 2849271-31.patch18.95 KBrpayanm
#29 2849271-29.patch19.45 KBjeroent
#29 interdiff-2849271-27-29.txt19.81 KBjeroent
#28 2849271-28-test-only.patch6.06 KBjeroent
#27 2849271-27.patch30.36 KBjeroent
#27 2849271-27-test-only.patch5.2 KBjeroent
#24 284927-19-23.txt8.16 KBjeroent
#23 2849271-23.patch26.51 KBjeroent
#21 Repeated_Policy.png260.13 KBapathak
#19 decouple-table-from-validation-2849271-19.patch28.2 KBkevin.dutra
#18 decouple-table-from-validation-2849271-18.patch0 byteskevin.dutra
#16 interdiff-2849271-15-16.txt644 bytesvoleger
#16 decouple-table-from-validation-2849271-16.patch29.24 KBvoleger
#15 decouple-table-from-validation-2849271-15.patch29.26 KBvoleger
#15 interdiff-2849271-13-15.txt18.91 KBvoleger
#14 interdiff.txt3.79 KBtatarbj
#13 interdiff.txt3.83 KBtatarbj
#13 decouple-table-from-validation-2849271-13.patch14.3 KBtatarbj
#11 decouple-table-from-validation-2849271-11.patch14.59 KBtatarbj
#2 decouple-table-from-validation-2849271-2.patch9.96 KBmroycroft
Command icon 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

mroycroft created an issue. See original summary.

mroycroft’s picture

Added patch file. A few notes about some of the other changes:

  1. Populated the entity interface with the appropriate methods.
  2. Removed a couple of TODO comments, the AJAX aspect seems to be working fine today.
  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.
  4. Tweaked logic for the validation, so that it would collect a list of failures, then display them as Drupal error messages. The logic for the validation for the case of no table getting generated did not seem like it was possible to enter, despite entering passwords that did not meet password policies.
mroycroft’s picture

Status: Active » Needs review
Related issues: +#2735943: Administrators always bypass password policies
nick.james’s picture

I performed a code review for the changes suggested here and they look good to me.

nerdstein’s picture

I 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?

+  // Check whether the policy validation should run.
+  if (_password_policy_validation_should_run()) {

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?

-  if ($account->hasPermission('bypass password policies')) {
-bypass password policies:
-  title: 'Bypass password policies'
-  description: "Be able to bypass password policies. Users with this permission will not have enforced password policies."
mroycroft’s picture

Thanks 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 configuration verify_mail is 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.

nerdstein’s picture

I 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.

nerdstein’s picture

Status: Needs review » Needs work
0sarah0al’s picture

Hi
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

tatarbj’s picture

Assigned: Unassigned » tatarbj

reroll and some other tests, maybe further work is needed, i'm assigning it to me to work on it

tatarbj’s picture

StatusFileSize
new14.59 KB

As 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.

voleger’s picture

A few notes that I had seen from that patch:

  1. +++ b/password_policy.module
    @@ -85,16 +76,58 @@ function _password_policy_show_policy() {
    + *   TRUE if the current user has a role captured in a policy, FALSE otherwise.
    + */
    +function _password_policy_validation_should_run() {
    +  $account = \Drupal::currentUser();
    +  $config = \Drupal::config('user.settings');
    

    Should this function stored in the .module file?
    I prefer to move this functionality into the service with the related service injection.

  2. +++ b/password_policy.module
    @@ -57,7 +45,10 @@ function password_policy_form_user_form_alter(&$form, &$form_state) {
    +  // Check whether the policy validation should run.
    +  if (_password_policy_validation_should_run()) {
         $form['#validate'][] = '_password_policy_user_profile_form_validate';
    

    This should be updated regarding previous suggestion.

  3. +++ b/config/schema/password_policy.schema.yml
    @@ -20,9 +20,13 @@ password_policy.password_policy.*:
         policy_constraints:
           type: sequence
           label: 'Constraints'
    -      sequence:
    -        type: password_policy.constraint.plugin.[id]
    -        label: 'Constraint'
    +    sequence:
    +      type: password_policy.constraint.plugin.[id]
    +      label: 'Constraint'
    

    Changes for property of policy_constraints configuration schema. Should be reverted.

  4. +++ b/password_policy.module
    @@ -85,16 +76,58 @@ function _password_policy_show_policy() {
     
    ...
    +  if ($account->isAnonymous() && $config->get('verify_mail')) {
    
    +++ b/password_policy.permissions.yml
    @@ -1,6 +1,3 @@
    -bypass password policies:
    -  title: 'Bypass password policies'
    -  description: "Be able to bypass password policies. Users with this permission will not have enforced password policies."
    

    Should 'bypass password policies' permission check be removed from the functionality?

tatarbj’s picture

Assigned: tatarbj » Unassigned
Status: Needs work » Needs review
StatusFileSize
new14.3 KB
new3.83 KB

Hey 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.

tatarbj’s picture

StatusFileSize
new3.79 KB

i just update the interdiff to a correct one (removed the header)

voleger’s picture

A 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.

voleger’s picture

StatusFileSize
new29.24 KB
new644 bytes

Missed one thing.

nerdstein’s picture

Status: Needs review » Needs work

Thanks, 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:

+  /**
+   * Determine if there is a role within any given policy for the current user.
+   *
+   * @return bool
+   *   TRUE if the current user has a role captured in a policy,
+   *   FALSE otherwise.
+   */

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?

kevin.dutra’s picture

Reroll of #16 for Alpha 5

kevin.dutra’s picture

StatusFileSize
new28.2 KB

Whoops! For real this time. :)

jasonluttrell’s picture

Neither 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?

apathak’s picture

StatusFileSize
new260.13 KB

Hello,

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.

apathak’s picture

Patches from comments #16 and #19 are failing to apply.

In any case, could some one please answer my question from #21?

jeroent’s picture

Status: Needs work » Needs review
StatusFileSize
new26.51 KB

Patch attached fixes the current failing tests.

jeroent’s picture

StatusFileSize
new8.16 KB
jeroent’s picture

Issue tags: +Needs tests

17.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.

+++ b/src/Plugin/PasswordPolicyVisibility/BypassVisibility.php
@@ -0,0 +1,77 @@
+  protected $weight = 1000;

17.6: Automated tests still need to be added.

jeroent’s picture

Also, 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...

jeroent’s picture

StatusFileSize
new5.2 KB
new30.36 KB

Provided some test coverage.

jeroent’s picture

StatusFileSize
new6.06 KB

Hmm, seems something was wrong with the test-only patch.

jeroent’s picture

StatusFileSize
new19.81 KB
new19.45 KB

Removed the plugin manager for the visibility rules since imo this is adding too much complexity for a small piece of code.

ant1’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
rpayanm’s picture

Status: Needs work » Needs review
StatusFileSize
new18.95 KB

Status: Needs review » Needs work

The last submitted patch, 31: 2849271-31.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

ant1’s picture

#31 doesn't apply correctly.

vsujeetkumar’s picture

Assigned: Unassigned » vsujeetkumar
vsujeetkumar’s picture

Assigned: vsujeetkumar » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new19.75 KB

Re-roll patch created, Please review.

ant1’s picture

Status: Needs review » Needs work

The 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...

tucho’s picture

Status: Needs work » Needs review
StatusFileSize
new19.86 KB
new1.22 KB

The 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.

ant1’s picture

Table 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...

tucho’s picture

Hi @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

ant1’s picture

I 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.

edmund.dunn’s picture

#37 worked for me.

cslevy’s picture

I created anothe patch to based on #37 to fix some warnings in case of Account Field split module is used.

Status: Needs review » Needs work

The last submitted patch, 42: password_policy-decouple_display_policy_table_policy_validation-2849271-42.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

cslevy’s picture

Status: Needs work » Needs review
StatusFileSize
new24.04 KB
new692 bytes

Wrong patch added in the previous comment . Uploading new patch

cslevy’s picture

For 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.

cslevy’s picture

Added also the possibility to alter the Constraints table rows

thomwilhelm’s picture

This 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.

nigelcunningham’s picture

Here is a reroll of the patch against current 8.x-3.x (526f77e2ffa7f7dd6a6c51591460928edb16d758).

marcos_lima made their first commit to this issue’s fork.

marcos_lima’s picture

Hi all!
I changed the approach to MR from patch #48.

j.’s picture

Patch #48 works great for my use case, on 9.2.7. Thanks! This has saved me loads of time.

paulocs’s picture

Status: Needs review » Postponed
Related issues: +#3054412: Make policy summary table easier to customise

Lets postpone this issue while #3054412: Make policy summary table easier to customise is not committed.

paulocs’s picture

Status: Postponed » Needs work

As #3054412: Make policy summary table easier to customise was committed, I'm updating the issue status.

jeroent’s picture

Issue tags: +Needs reroll
nigelcunningham’s picture

Issue tags: -Needs reroll

Another rebase.

andregp’s picture

Assigned: Unassigned » andregp

I'll try a manual test to review the last MR

andregp’s picture

Assigned: andregp » Unassigned
Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs tests
StatusFileSize
new249.92 KB
new237.62 KB

It 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:

Policy A - Constraint 1
Policy A - Constraint 2
Policy B - Constraint 1

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

Policy A - Constraint 2
Policy B - Constraint 1

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).

adriancid’s picture

@NigelCunningham:

Merge blocked: the source branch must be rebased onto the target branch.

paulocs’s picture

Status: Reviewed & tested by the community » Needs review

Only removed some deprecated code added before in the MR 20!

dancbatista’s picture

Assigned: Unassigned » dancbatista

I'm working in this issue!

dancbatista’s picture

Assigned: dancbatista » Unassigned
Status: Needs review » Reviewed & tested by the community

I tested and the patch works fine! Rebase still needed.

nigelcunningham’s picture

I've now rebased the branch, thanks.

jeroent’s picture

Status: Reviewed & tested by the community » Needs work

Tests are failing.

lucasbaralm’s picture

Assigned: Unassigned » lucasbaralm

I will work on this issue.

paulocs’s picture

Assigned: lucasbaralm » Unassigned
Status: Needs work » Needs review
Parent issue: » #3305839: Create Password Policy 8.x-3.2 release

Please review.

the_g_bomb made their first commit to this issue’s fork.

sophiavs’s picture

Assigned: Unassigned » sophiavs

I'll do the review

sophiavs’s picture

Assigned: sophiavs » Unassigned
StatusFileSize
new87.98 KB
new101.53 KB
new92.06 KB

While 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.

lucassc’s picture

Assigned: Unassigned » lucassc
lucassc’s picture

Assigned: lucassc » Unassigned

Addressed #69: Fixed warning in src/PasswordPolicyValidator.php to use dependency injection instead of \Drupal call on line 155.

Please review this.

lucasbaralm’s picture

Assigned: Unassigned » lucasbaralm

I will do the review.

lucasbaralm’s picture

Assigned: lucasbaralm » Unassigned
Status: Needs review » Reviewed & tested by the community

I 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.

FILE: /password_policy/src/Plugin/migrate/process/PolicyConfiguration.php
---------------------------------------------------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
---------------------------------------------------------------------------------------------------------------------------
 124 | ERROR | Missing parameter type
---------------------------------------------------------------------------------------------------------------------------


FILE: /password_policy/password_policy.module
-----------------------------------------------------------------------------------------------
FOUND 0 ERRORS AND 1 WARNING AFFECTING 1 LINE
-----------------------------------------------------------------------------------------------
 8 | WARNING | [x] Unused use statement
-----------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
-----------------------------------------------------------------------------------------------

  • paulocs committed 45f9bf6 on 8.x-3.x authored by marcos_lima
    Issue #2849271 by JeroenT, paulocs, cslevy, Nigel Cunningham, tatarbj,...
paulocs’s picture

Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.