Skip to content
Snippets Groups Projects
Commit 9aa8d39c authored by catch's avatar catch
Browse files

Issue #3443198 by andypost, smustgrave, catch: Remove deprecated code from phpPass + bigpipe

parent 5fbd411f
Branches
Tags
29 merge requests!12227Issue #3181946 by jonmcl, mglaman,!11131[10.4.x-only-DO-NOT-MERGE]: Issue ##2842525 Ajax attached to Views exposed filter form does not trigger callbacks,!9470[10.3.x-only-DO-NOT-MERGE]: #3331771 Fix file_get_contents(): Passing null to parameter,!8540Issue #3457061: Bootstrap Modal dialog Not closing after 10.3.0 Update,!8528Issue #3456871 by Tim Bozeman: Support NULL services,!8373Issue #3427374 by danflanagan8, Vighneshh: taxonomy_tid ViewsArgumentDefault...,!5423Draft: Resolve #3329907 "Test2",!3878Removed unused condition head title for views,!3818Issue #2140179: $entity->original gets stale between updates,!3742Issue #3328429: Create item list field formatter for displaying ordered and unordered lists,!3731Claro: role=button on status report items,!3651Issue #3347736: Create new SDC component for Olivero (header-search),!3531Issue #3336994: StringFormatter always displays links to entity even if the user in context does not have access,!3478Issue #3337882: Deleted menus are not removed from content type config,!3355Issue #3209129: Scrolling problems when adding a block via layout builder,!3154Fixes #2987987 - CSRF token validation broken on routes with optional parameters.,!3133core/modules/system/css/components/hidden.module.css,!2964Issue #2865710 : Dependencies from only one instance of a widget are used in display modes,!2812Issue #3312049: [Followup] Fix Drupal.Commenting.FunctionComment.MissingReturnType returns for NULL,!2378Issue #2875033: Optimize joins and table selection in SQL entity query implementation,!2062Issue #3246454: Add weekly granularity to views date sort,!1105Issue #3025039: New non translatable field on translatable content throws error,!1073issue #3191727: Focus states on mobile second level navigation items fixed,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!877Issue #2708101: Default value for link text is not saved,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493,!213Issue #2906496: Give Media a menu item under Content
Pipeline #155795 passed with warnings
Pipeline: drupal

#155799

    ......@@ -35,43 +35,13 @@ abstract class PhpassHashedPasswordBase implements PasswordInterface {
    */
    public static $ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    /**
    * Password stretching iteration count.
    *
    * Specifies the number of times the hashing function will be applied when
    * generating new password hashes. The number of times is calculated by
    * raising 2 to the power of the given value.
    *
    * @var int
    */
    protected $countLog2;
    /**
    * The core PHP password interface.
    */
    protected ?PasswordInterface $corePassword;
    /**
    * Constructs a new password hashing instance.
    *
    * @param \Drupal\Core\Password\PasswordInterface|int $corePassword
    * The core PHP password interface (or the countLog2 value for BC).
    * @param \Drupal\Core\Password\PasswordInterface $corePassword
    * The core PHP password interface.
    */
    public function __construct(PasswordInterface|int $corePassword) {
    if ($corePassword instanceof PasswordInterface) {
    // Note: If $corePassword is set, $countLog2 isn't used anywhere in the
    // code path of this class. Still, set it to the default value for BC
    // reasons.
    $this->countLog2 = 16;
    $this->corePassword = $corePassword;
    }
    else {
    $countLog2 = $corePassword;
    @trigger_error('Calling ' . __METHOD__ . '() with numeric $countLog2 as the first parameter is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use PhpassHashedPasswordInterface::__construct() with $corePassword parameter set to an instance of Drupal\Core\Password\PhpPassword instead. See https://www.drupal.org/node/3322420', E_USER_DEPRECATED);
    // Ensure that $countLog2 is within set bounds.
    $this->countLog2 = $this->enforceLog2Boundaries($countLog2);
    $this->corePassword = NULL;
    }
    public function __construct(protected PasswordInterface $corePassword) {
    }
    /**
    ......@@ -111,27 +81,6 @@ protected function base64Encode($input, $count) {
    return $output;
    }
    /**
    * Generates a random base 64-encoded salt prefixed with hash settings.
    *
    * Proper use of salts may defeat a number of attacks, including:
    * - The ability to try candidate passwords against multiple hashes at once.
    * - The ability to use pre-hashed lists of candidate passwords.
    * - The ability to determine whether two users have the same (or different)
    * password without actually having to guess one of the passwords.
    *
    * @return string
    * A 12 character string containing the iteration count and a random salt.
    */
    protected function generateSalt() {
    $output = '$S$';
    // We encode the final log2 iteration count in base 64.
    $output .= static::$ITOA64[$this->countLog2];
    // 6 bytes is the standard salt for a portable phpass hash.
    $output .= $this->base64Encode(random_bytes(6), 6);
    return $output;
    }
    /**
    * Ensures that $count_log2 is within set bounds.
    *
    ......@@ -233,13 +182,9 @@ public function getCountLog2($setting) {
    * {@inheritdoc}
    */
    public function hash(#[\SensitiveParameter] $password) {
    if (isset($this->corePassword)) {
    return $this->corePassword->hash($password);
    }
    return $this->crypt('sha512', $password, $this->generateSalt());
    }
    /**
    * {@inheritdoc}
    */
    ......@@ -290,18 +235,7 @@ public function check(#[\SensitiveParameter] $password, #[\SensitiveParameter] $
    * {@inheritdoc}
    */
    public function needsRehash(#[\SensitiveParameter] $hash) {
    if (isset($this->corePassword)) {
    return $this->corePassword->needsRehash($hash);
    }
    // Check whether this was an updated password.
    if (!str_starts_with($hash, '$S$') || (strlen($hash) != static::HASH_LENGTH)) {
    return TRUE;
    }
    // Ensure that $count_log2 is within set bounds.
    $count_log2 = $this->enforceLog2Boundaries($this->countLog2);
    // Check whether the iteration count used differs from the standard number.
    return ($this->getCountLog2($hash) !== $count_log2);
    }
    }
    ......@@ -165,59 +165,15 @@ class BigPipe {
    */
    const STOP_SIGNAL = '<script type="application/vnd.drupal-ajax" data-big-pipe-event="stop"></script>';
    /**
    * The renderer.
    *
    * @var \Drupal\Core\Render\RendererInterface
    */
    protected $renderer;
    /**
    * The session.
    *
    * @var \Symfony\Component\HttpFoundation\Session\SessionInterface
    */
    protected $session;
    /**
    * The request stack.
    *
    * @var \Symfony\Component\HttpFoundation\RequestStack
    */
    protected $requestStack;
    /**
    * The HTTP kernel.
    *
    * @var \Symfony\Component\HttpKernel\HttpKernelInterface
    */
    protected $httpKernel;
    /**
    * The event dispatcher.
    *
    * @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface
    */
    protected $eventDispatcher;
    /**
    * The config factory.
    *
    * @var \Drupal\Core\Config\ConfigFactoryInterface
    */
    protected $configFactory;
    public function __construct(RendererInterface $renderer, SessionInterface $session, RequestStack $request_stack, HttpKernelInterface $http_kernel, EventDispatcherInterface $event_dispatcher, ConfigFactoryInterface $config_factory, protected ?MessengerInterface $messenger = NULL) {
    $this->renderer = $renderer;
    $this->session = $session;
    $this->requestStack = $request_stack;
    $this->httpKernel = $http_kernel;
    $this->eventDispatcher = $event_dispatcher;
    $this->configFactory = $config_factory;
    if (!isset($this->messenger)) {
    @trigger_error('Calling ' . __CLASS__ . '::_construct() without the $messenger argument is deprecated in drupal:10.3.0 and it will be required in drupal:11.0.0. See https://www.drupal.org/node/3343754', E_USER_DEPRECATED);
    $this->messenger = \Drupal::messenger();
    }
    public function __construct(
    protected RendererInterface $renderer,
    protected SessionInterface $session,
    protected RequestStack $requestStack,
    protected HttpKernelInterface $httpKernel,
    protected EventDispatcherInterface $eventDispatcher,
    protected ConfigFactoryInterface $configFactory,
    protected MessengerInterface $messenger,
    ) {
    }
    /**
    ......
    <?php
    declare(strict_types=1);
    namespace Drupal\Tests\phpass\Unit;
    use Drupal\phpass\Password\PhpassHashedPassword;
    use Drupal\Tests\UnitTestCase;
    /**
    * Unit tests for password hashing API.
    *
    * Legacy tests, deprecated in drupal:10.1.0 and removed from drupal:11.0.0 as
    * soon as PhpassHashedPassword::__construct() with $corePassword parameter is
    * enforced to be an instance of Drupal\Core\Password\PhpPassword.
    *
    * @see https://www.drupal.org/node/3322420
    *
    * @coversDefaultClass \Drupal\phpass\Password\PhpassHashedPassword
    * @group phpass
    * @group legacy
    */
    class LegacyPasswordHashingTest extends UnitTestCase {
    /**
    * The raw password.
    *
    * @var string
    */
    protected $password;
    /**
    * The md5 password.
    *
    * @var string
    */
    protected $md5HashedPassword;
    /**
    * The hashed password.
    *
    * @var string
    */
    protected $hashedPassword;
    /**
    * The password hasher under test.
    *
    * @var \Drupal\Core\Password\PhpassHashedPassword
    */
    protected $passwordHasher;
    /**
    * {@inheritdoc}
    */
    protected function setUp(): void {
    parent::setUp();
    $this->expectDeprecation('Calling Drupal\Core\Password\PhpassHashedPasswordBase::__construct() with numeric $countLog2 as the first parameter is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use PhpassHashedPasswordInterface::__construct() with $corePassword parameter set to an instance of Drupal\Core\Password\PhpPassword instead. See https://www.drupal.org/node/3322420');
    $this->password = $this->randomMachineName();
    $this->passwordHasher = new PhpassHashedPassword(1);
    $this->hashedPassword = $this->passwordHasher->hash($this->password);
    $this->md5HashedPassword = 'U' . $this->passwordHasher->hash(md5($this->password));
    }
    /**
    * Tests a password needs update.
    *
    * @covers ::needsRehash
    */
    public function testPasswordNeedsUpdate() {
    // The md5 password should be flagged as needing an update.
    $this->assertTrue($this->passwordHasher->needsRehash($this->md5HashedPassword), 'Upgraded md5 password hash needs a new hash.');
    }
    /**
    * Tests password hashing.
    *
    * @covers ::hash
    * @covers ::getCountLog2
    * @covers ::base64Encode
    * @covers ::check
    * @covers ::generateSalt
    * @covers ::needsRehash
    */
    public function testPasswordHashing() {
    $this->assertSame(PhpassHashedPassword::MIN_HASH_COUNT, $this->passwordHasher->getCountLog2($this->hashedPassword), 'Hashed password has the minimum number of log2 iterations.');
    $this->assertNotEquals($this->hashedPassword, $this->md5HashedPassword, 'Password hashes not the same.');
    $this->assertTrue($this->passwordHasher->check($this->password, $this->md5HashedPassword), 'Password check succeeds.');
    $this->assertTrue($this->passwordHasher->check($this->password, $this->hashedPassword), 'Password check succeeds.');
    // Since the log2 setting hasn't changed and the user has a valid password,
    // userNeedsNewHash() should return FALSE.
    $this->assertFalse($this->passwordHasher->needsRehash($this->hashedPassword), 'Does not need a new hash.');
    }
    /**
    * Tests password rehashing.
    *
    * @covers ::__construct
    * @covers ::hash
    * @covers ::getCountLog2
    * @covers ::check
    * @covers ::needsRehash
    */
    public function testPasswordRehashing() {
    // Increment the log2 iteration to MIN + 1.
    $password_hasher = new PhpassHashedPassword(PhpassHashedPassword::MIN_HASH_COUNT + 1);
    $this->assertTrue($password_hasher->needsRehash($this->hashedPassword), 'Needs a new hash after incrementing the log2 count.');
    // Re-hash the password.
    $rehashed_password = $password_hasher->hash($this->password);
    $this->assertSame(PhpassHashedPassword::MIN_HASH_COUNT + 1, $password_hasher->getCountLog2($rehashed_password), 'Re-hashed password has the correct number of log2 iterations.');
    $this->assertNotEquals($rehashed_password, $this->hashedPassword, 'Password hash changed again.');
    // Now the hash should be OK.
    $this->assertFalse($password_hasher->needsRehash($rehashed_password), 'Re-hashed password does not need a new hash.');
    $this->assertTrue($password_hasher->check($this->password, $rehashed_password), 'Password check succeeds with re-hashed password.');
    $this->assertTrue($this->passwordHasher->check($this->password, $rehashed_password), 'Password check succeeds with re-hashed password with original hasher.');
    }
    /**
    * Tests password validation when the hash is NULL.
    *
    * @covers ::check
    */
    public function testEmptyHash(): void {
    $this->assertFalse($this->passwordHasher->check($this->password, NULL));
    $this->assertFalse($this->passwordHasher->check($this->password, ''));
    }
    }
    <?php
    declare(strict_types=1);
    namespace Drupal\Tests\Core\Password;
    use Drupal\Core\Password\PhpassHashedPassword;
    use Drupal\Tests\UnitTestCase;
    /**
    * Unit tests for deprecated password hashing API.
    *
    * @group System
    * @group legacy
    */
    class PasswordHashingLegacyTest extends UnitTestCase {
    /**
    * @covers \Drupal\Core\Password\PhpassHashedPassword
    */
    public function testDeprecation() {
    $this->expectDeprecation('\Drupal\Core\Password\PhpassHashedPassword is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. The password compatibility service has been moved to the phpass module. Use \Drupal\phpass\Password\PhpassHashedPassword instead. See https://www.drupal.org/node/3322420');
    $this->expectDeprecation('Calling Drupal\Core\Password\PhpassHashedPasswordBase::__construct() with numeric $countLog2 as the first parameter is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use PhpassHashedPasswordInterface::__construct() with $corePassword parameter set to an instance of Drupal\Core\Password\PhpPassword instead. See https://www.drupal.org/node/3322420');
    $passwordService = new PhpassHashedPassword(4);
    $this->assertInstanceOf(PhpassHashedPassword::class, $passwordService);
    }
    }
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please to comment