The module is not compatible with the user_registrationpassword module that allows users to set a password on the registration form - even if the email has to be validated.

The problem is that password policy checks if user.settings.verify_mail is checked and the user_registrationpassword module replace this check with custom options.

I dont know if this is an issue for user_registrationpassword module or for password_policy module.

Maybe the check to know if password policy should be verified should be done on the presence or not of the password field and not on something not really related as user.settings.verify_mail.

Comments

marabak created an issue. See original summary.

marabak’s picture

Category: Bug report » Support request
Kristen Pol’s picture

Status: Active » Postponed (maintainer needs more info)

Thanks to everyone for the work on this issue.

I'm going through all the 8.x issues.

As the 8.x is no longer supported, I'm postponing this issue for now and need feedback as to whether or not this issue is relevant to 4.0.x.

If it is, please reopen and change the version, make sure the issue summary is clear and complete, including concrete steps to reproduce, and reroll the patch. If it's not, please close.

If there is no response to this in a month addressing the above, it can be closed.

mably’s picture

Our solution was to override the password_policy.validation_manager in a custom module.

Related code below which checks for user_registrationpassword configuration and acts accordingly:

<?php

namespace Drupal\password_policy_extras;

use Drupal\password_policy\PasswordPolicyValidationManager;

/**
 * Class PasswordPolicyExtrasValidationManager.
 *
 * Decide whether to display validation and whether to validate a password.
 *
 * @package Drupal\password_policy_extras
 */
class PasswordPolicyExtrasValidationManager extends PasswordPolicyValidationManager {

  /**
   * {@inheritdoc}
   */
  public function tableShouldBeVisible() {

    $current_user_roles = $this->currentUser->getRoles();

    $urp_settings = \Drupal::config('user_registrationpassword.settings');
    if (empty($urp_settings)) {
      $verify_email_before_password = $this->userSettingsConfig->get('verify_mail');
    }
    else {
      $registration = $urp_settings->get('registration');
      $verify_email_before_password = ($registration === 'default');
      if (!$verify_email_before_password && $this->currentUser->isAnonymous()) {
        // Before a user has registered all they have is the anonymous role,
        // which can't be targeted by a password policy rule. So also search
        // for the authenticated role, which every user will have post register.
        $current_user_roles[] = "authenticated";
      }
    }

    if ($this->currentUser->isAnonymous()
      && $verify_email_before_password
      && $this->routeMatch->getRouteName() !== 'user.reset') {
      return FALSE;
    }

    $role_applies = $this->passwordPolicyStorage->getQuery()
      ->condition('roles.*', $current_user_roles, 'IN')
      ->condition('show_policy_table', TRUE)
      ->accessCheck(FALSE)
      ->execute();
    return !empty($role_applies);
  }

  /**
   * {@inheritdoc}
   */
  public function validationShouldRun() {

    $urp_settings = \Drupal::config('user_registrationpassword.settings');
    if (empty($urp_settings)) {
      $verify_email_before_password = $this->userSettingsConfig->get('verify_mail');
    }
    else {
      $registration = $urp_settings->get('registration');
      $verify_email_before_password = ($registration === 'default');
    }

    if ($this->currentUser->isAnonymous()
      && $verify_email_before_password
      && $this->routeMatch->getRouteName() !== 'user.reset') {
      return FALSE;
    }

    $current_user_roles = $this->currentUser->getRoles();
    // Before a user has registered all they have is the anonymous role,
    // which can't be targeted by a password policy rule. So also search
    // for the authenticated role, which every user will have post register.
    $current_user_roles[] = "authenticated";
    $role_applies = $this->passwordPolicyStorage->getQuery()
      ->condition('roles.*', $current_user_roles, 'IN')
      ->accessCheck(FALSE)
      ->execute();
    return !empty($role_applies);
  }

}

May be password policy could provides two hooks to allow other modules to modify by reference the boolean value checked for the return FALSE part and to modify the user_roles array. Both were needed to make Password Policy work with the user_registrationpassword module.

But may be other modules will have other needs.

mably’s picture

Started implementing my compatibility fix for the user_registrationpassword module in a new contrib module: https://www.drupal.org/project/password_policy_extras

This new project could be used as a sandbox for the Password Policy module.