Commit 13718a20 authored by sumeet jaggi's avatar sumeet jaggi Committed by Greg Knaddison
Browse files

Issue #3264477: Password Strength module is not updated with PHP8.

parent a1369790
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
  "description": "Integrates the Password Strength into Drupal's Password Policy module.",
  "type": "drupal-module",
  "require": {
    "bjeavons/zxcvbn-php": "0.4.0"
    "bjeavons/zxcvbn-php": "^1.3",
    "drupal/password_policy": "^3.1"
  }
}
+17 −59
Original line number Diff line number Diff line
@@ -2,29 +2,28 @@

namespace Drupal\password_strength;

use \ZxcvbnPhp\Scorer;
use \ZxcvbnPhp\Searcher;
use ZxcvbnPhp\Zxcvbn;

class PasswordStrength {
/**
   * @var
 * Base class PasswordStrength.
 *
 * @package Drupal\password_strength
 */
  protected $scorer;

class PasswordStrength {
  /**
   * @var
   * Member variable.
   *
   * @var \ZxcvbnPhp\Zxcvbn
   */
  protected $searcher;
  protected $zxcvbnPhp;

  /**
   * @var
   * {@inheritdoc}
   *
   * Instantiate the Zxcvbn and save it in member variable.
   */
  protected $matcher;

  public function __construct() {
    $this->searcher = new Searcher();
    $this->scorer = new Scorer();
    $this->matcher = new Matcher();
    $this->zxcvbnPhp = new Zxcvbn();
  }

  /**
@@ -42,49 +41,8 @@ class PasswordStrength {
   *     match_sequence
   *     score
   */
  public function passwordStrength($password, array $userInputs = array()) {
    $timeStart = microtime(TRUE);
    if (strlen($password) === 0) {
      $timeStop = microtime(TRUE) - $timeStart;
      return $this->result($password, 0, array(), 0, array('calc_time' => $timeStop));
    }

    // Get matches for $password.
    $matches = $this->matcher->getMatches($password, $userInputs);

    // Calcuate minimum entropy and get best match sequence.
    $entropy = $this->searcher->getMinimumEntropy($password, $matches);
    $bestMatches = $this->searcher->matchSequence;

    // Calculate score and get crack time.
    $score = $this->scorer->score($entropy);
    $metrics = $this->scorer->getMetrics();

    $timeStop = microtime(TRUE) - $timeStart;
    // Include metrics and calculation time.
    $params = array_merge($metrics, array('calc_time' => $timeStop));
    return $this->result($password, $entropy, $bestMatches, $score, $params);
  }

  /**
   * Result array.
   *
   * @param string $password
   * @param float $entropy
   * @param array $matches
   * @param int $score
   * @param array $params
   *
   * @return array
   */
  protected function result($password, $entropy, $matches, $score, $params = array()) {
    $r = array(
      'password' => $password,
      'entropy' => $entropy,
      'match_sequence' => $matches,
      'score' => $score
    );
    return array_merge($params, $r);
  public function passwordStrength($password, array $userInputs = []) {
    return $this->zxcvbnPhp->passwordStrength($password, $userInputs);
  }

}
+42 −21
Original line number Diff line number Diff line
<?php

namespace Drupal\password_strength\Tests;
namespace Drupal\Tests\password_strength\Functional;

use Drupal\Tests\BrowserTestBase;
use Drupal\password_strength;

/**
 * Tests password strength behaviors from Password Strength library.
@@ -11,30 +12,46 @@ use Drupal\Tests\BrowserTestBase;
 */
class PasswordStrengthTests extends BrowserTestBase {

  public static $modules = array('password_policy', 'password_strength');
  /**
   * Modules to install.
   *
   * @var array
   */
  protected static $modules = [
    'password_policy',
    'password_strength',
  ];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * Test password strength behaviors.
   *
   * @group ps_maintester
   */
  function testPasswordStrengthTests() {
  public function testPasswordStrengthTests() {
    // Create user with permission to create policy.
    $user1 = $this->drupalCreateUser(array(
    $user1 = $this->drupalCreateUser([
      'administer site configuration',
      'administer users',
      'administer permissions',
    ));
    ]);
    $this->drupalLogin($user1);

    $user2 = $this->drupalCreateUser();

    // Create role.
    $rid = $this->drupalCreateRole(array());
    $rid = $this->drupalCreateRole([]);

    // Set role for user.
    $edit = [
      'roles[' . $rid . ']' => $rid,
    ];
    $this->drupalPostForm("user/" . $user2->id() . "/edit", $edit, t('Save'));
    $this->drupalGet("user/" . $user2->id() . "/edit");
    $this->submitForm($edit, 'Save');

    // Create new password reset policy for role.
    $this->drupalGet("admin/config/security/password-policy/add");
@@ -44,52 +61,56 @@ class PasswordStrengthTests extends BrowserTestBase {
      'password_reset' => '1',
    ];
    // Set reset and policy info.
    $this->drupalPostForm(NULL, $edit, 'Next');
    $this->submitForm($edit, 'Next');

    $this->assertText('No constraints have been configured.');
    $this->assertSession()->pageTextContains('No constraints have been configured.');

    // Fill out length constraint for test policy.
    $edit = [
      'strength_score' => '4',
    ];
    $this->drupalPostForm('admin/config/system/password_policy/constraint/add/test/password_strength_constraint', $edit, 'Save');
    $this->drupalGet('admin/config/system/password_policy/constraint/add/test/password_strength_constraint');
    $this->submitForm($edit, 'Save');

    $this->assertText('password_strength_constraint');
    $this->assertText('Password Strength minimum score of 4');
    $this->assertSession()->pageTextContains('password_strength_constraint');
    $this->assertSession()->pageTextContains('Password Strength minimum score of 4');

    // Go to the next page.
    $this->drupalPostForm(NULL, [], 'Next');
    $this->submitForm([], 'Next');
    // Set the roles for the policy.
    $edit = [
      'roles[' . $rid . ']' => $rid,
    ];
    $this->drupalPostForm(NULL, $edit, 'Finish');
    $this->submitForm($edit, 'Finish');

    $this->assertText('Saved the test Password Policy.');
    $this->assertSession()->pageTextContains('The Password Policy test has been added.');

    $this->drupalLogout();
    $this->drupalLogin($user2);

    // Change own password with one not very complex.
    $edit = array();
    $edit = [];
    $edit['pass[pass1]'] = '1';
    $edit['pass[pass2]'] = '1';
    $edit['current_pass'] = $user2->pass_raw;
    $this->drupalPostForm("user/" . $user2->id() . "/edit", $edit, t('Save'));
    $this->drupalGet("user/" . $user2->id() . "/edit");
    $this->submitForm($edit, 'Save');

    // Verify we see an error.
    $this->assertText('The password does not satisfy the password policies');
    $this->assertSession()->pageTextContains('The password does not satisfy the password policies');

    // Change own password with one strong enough.
    $edit = array();
    $edit = [];
    $edit['pass[pass1]'] = 'aV3ryC*mplexPassword1nd33d!';
    $edit['pass[pass2]'] = 'aV3ryC*mplexPassword1nd33d!';
    $edit['current_pass'] = $user2->pass_raw;
    $this->drupalPostForm("user/" . $user2->id() . "/edit", $edit, t('Save'));
    $this->drupalGet("user/" . $user2->id() . "/edit");
    $this->submitForm($edit, 'Save');

    // Verify we see do not error.
    $this->assertNoText('The password does not satisfy the password policies');
    $this->assertSession()->pageTextNotContains('The password does not satisfy the password policies');

    $this->drupalLogout();
  }

}