Issue #3238227 by alexpott: \Drupal\Core\Field\Plugin\Field\FieldType\PasswordItem causes deprecation errors on PHP 8.1
parent
f680e8ea6c
commit
b6e74cf3fb
|
@ -523,6 +523,16 @@ field.value.string_long:
|
|||
type: text
|
||||
label: 'Value'
|
||||
|
||||
# Schema for the configuration of the Password field type.
|
||||
|
||||
field.storage_settings.password:
|
||||
type: field.storage_settings.string
|
||||
label: 'Password settings'
|
||||
|
||||
field.field_settings.password:
|
||||
type: mapping
|
||||
label: 'Password settings'
|
||||
|
||||
# Schema for the configuration of the URI field type.
|
||||
|
||||
field.storage_settings.uri:
|
||||
|
|
|
@ -46,6 +46,11 @@ class PasswordItem extends StringItem {
|
|||
// Reset the pre_hashed value since it has now been used.
|
||||
$this->pre_hashed = FALSE;
|
||||
}
|
||||
elseif (!$entity->isNew() && empty($this->value)) {
|
||||
// If the password is empty, that means it was not changed, so use the
|
||||
// original password.
|
||||
$this->value = $entity->original->{$this->getFieldDefinition()->getName()}->value;
|
||||
}
|
||||
elseif ($entity->isNew() || (strlen(trim($this->value)) > 0 && $this->value != $entity->original->{$this->getFieldDefinition()->getName()}->value)) {
|
||||
// Allow alternate password hashing schemes.
|
||||
$this->value = \Drupal::service('password')->hash(trim($this->value));
|
||||
|
@ -55,13 +60,6 @@ class PasswordItem extends StringItem {
|
|||
}
|
||||
}
|
||||
|
||||
if (!$entity->isNew()) {
|
||||
// If the password is empty, that means it was not changed, so use the
|
||||
// original password.
|
||||
if (empty($this->value)) {
|
||||
$this->value = $entity->original->{$this->getFieldDefinition()->getName()}->value;
|
||||
}
|
||||
}
|
||||
// Ensure that the existing password is unset to minimise risks of it
|
||||
// getting serialized and stored somewhere.
|
||||
$this->existing = NULL;
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\KernelTests\Core\Field\FieldType;
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageException;
|
||||
use Drupal\Core\Password\PasswordInterface;
|
||||
use Drupal\entity_test\Entity\EntityTest;
|
||||
use Drupal\field\Entity\FieldConfig;
|
||||
use Drupal\field\Entity\FieldStorageConfig;
|
||||
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\Core\Field\Plugin\Field\FieldType\PasswordItem
|
||||
* @group Field
|
||||
*/
|
||||
class PasswordItemTest extends FieldKernelTestBase {
|
||||
|
||||
/**
|
||||
* A field storage to use in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldStorageConfig
|
||||
*/
|
||||
protected $fieldStorage;
|
||||
|
||||
/**
|
||||
* The field used in this test class.
|
||||
*
|
||||
* @var \Drupal\field\Entity\FieldConfig
|
||||
*/
|
||||
protected $field;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
||||
$this->fieldStorage = FieldStorageConfig::create([
|
||||
'field_name' => 'test_field',
|
||||
'entity_type' => 'entity_test',
|
||||
'type' => 'password',
|
||||
]);
|
||||
$this->fieldStorage->save();
|
||||
|
||||
$this->field = FieldConfig::create([
|
||||
'field_storage' => $this->fieldStorage,
|
||||
'bundle' => 'entity_test',
|
||||
'required' => TRUE,
|
||||
]);
|
||||
$this->field->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::preSave
|
||||
*/
|
||||
public function testPreSavePreHashed() {
|
||||
$entity = EntityTest::create([
|
||||
'name' => $this->randomString(),
|
||||
]);
|
||||
$entity->test_field = 'this_is_not_a_real_hash';
|
||||
$entity->test_field->pre_hashed = TRUE;
|
||||
|
||||
$entity->save();
|
||||
$this->assertSame('this_is_not_a_real_hash', $entity->test_field->value);
|
||||
$this->assertFalse($entity->test_field->pre_hashed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::preSave
|
||||
*/
|
||||
public function testPreSaveNewNull() {
|
||||
$entity = EntityTest::create([
|
||||
'name' => $this->randomString(),
|
||||
]);
|
||||
$entity->test_field = NULL;
|
||||
|
||||
$entity->save();
|
||||
$this->assertNull($entity->test_field->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::preSave
|
||||
*/
|
||||
public function testPreSaveNewEmptyString() {
|
||||
$entity = EntityTest::create([
|
||||
'name' => $this->randomString(),
|
||||
]);
|
||||
$entity->test_field = '';
|
||||
|
||||
$entity->save();
|
||||
|
||||
// The string starts with the portable password string and is a hash of an
|
||||
// empty string.
|
||||
$this->assertStringStartsWith('$S$', $entity->test_field->value);
|
||||
$this->assertTrue($this->container->get('password')->check('', $entity->test_field->value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::preSave
|
||||
*/
|
||||
public function testPreSaveNewMultipleSpacesString() {
|
||||
$entity = EntityTest::create([
|
||||
'name' => $this->randomString(),
|
||||
]);
|
||||
$entity->test_field = ' ';
|
||||
|
||||
$entity->save();
|
||||
|
||||
// The string starts with the portable password string and is a hash of an
|
||||
// empty string.
|
||||
$this->assertStringStartsWith('$S$', $entity->test_field->value);
|
||||
$this->assertTrue($this->container->get('password')->check('', $entity->test_field->value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::preSave
|
||||
*/
|
||||
public function testPreSaveExistingNull() {
|
||||
$entity = EntityTest::create();
|
||||
$entity->test_field = $this->randomString();
|
||||
$entity->save();
|
||||
|
||||
$this->assertNotNull($entity->test_field->value);
|
||||
|
||||
$entity->test_field = NULL;
|
||||
$entity->save();
|
||||
|
||||
$this->assertNull($entity->test_field->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::preSave
|
||||
*/
|
||||
public function testPreSaveExistingEmptyString() {
|
||||
$entity = EntityTest::create();
|
||||
$entity->test_field = $this->randomString();
|
||||
$entity->save();
|
||||
|
||||
$hashed_password = $entity->test_field->value;
|
||||
|
||||
$entity->test_field = '';
|
||||
$entity->save();
|
||||
|
||||
$this->assertSame($hashed_password, $entity->test_field->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::preSave
|
||||
*/
|
||||
public function testPreSaveExistingMultipleSpacesString() {
|
||||
$entity = EntityTest::create();
|
||||
$entity->test_field = $this->randomString();
|
||||
$entity->save();
|
||||
|
||||
$entity->test_field = ' ';
|
||||
$entity->save();
|
||||
|
||||
// @todo Fix this bug in https://www.drupal.org/project/i/3238399.
|
||||
$this->assertSame(' ', $entity->test_field->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::preSave
|
||||
*/
|
||||
public function testPreSaveExceptionNew() {
|
||||
$entity = EntityTest::create();
|
||||
$entity->test_field = str_repeat('a', PasswordInterface::PASSWORD_MAX_LENGTH + 1);
|
||||
$this->expectException(EntityStorageException::class);
|
||||
$this->expectExceptionMessage('The entity does not have a password');
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::preSave
|
||||
*/
|
||||
public function testPreSaveExceptionExisting() {
|
||||
$entity = EntityTest::create();
|
||||
$entity->test_field = 'will_be_hashed';
|
||||
$entity->save();
|
||||
|
||||
$this->assertNotEquals('will_be_hashed', $entity->test_field->value);
|
||||
|
||||
$this->expectException(EntityStorageException::class);
|
||||
$this->expectExceptionMessage('The entity does not have a password');
|
||||
$entity->test_field = str_repeat('a', PasswordInterface::PASSWORD_MAX_LENGTH + 1);
|
||||
$entity->save();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue