SA-CORE-2024-004 by zengenuity, cilefen, kristiaanvandeneynde, mcdruid, larowlan
parent
83e7c89c57
commit
c70e38c812
|
@ -17,6 +17,16 @@ class UniqueFieldConstraint extends SymfonyConstraint {
|
|||
|
||||
public $message = 'A @entity_type with @field_name %value already exists.';
|
||||
|
||||
/**
|
||||
* This constraint is case-insensitive by default.
|
||||
*
|
||||
* For example "FOO" and "foo" would be considered as equivalent, and
|
||||
* validation of the constraint would fail.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $caseSensitive = FALSE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -64,12 +64,23 @@ class UniqueFieldValueValidator extends ConstraintValidator implements Container
|
|||
->getStorage($entity_type_id)
|
||||
->getAggregateQuery()
|
||||
->accessCheck(FALSE)
|
||||
->condition($field_name, $item_values, 'IN')
|
||||
->groupBy("$field_name.$property_name");
|
||||
if (!$is_new) {
|
||||
$entity_id = $entity->id();
|
||||
$query->condition($id_key, $entity_id, '<>');
|
||||
}
|
||||
|
||||
if ($constraint->caseSensitive) {
|
||||
$query->condition($field_name, $item_values, 'IN');
|
||||
}
|
||||
else {
|
||||
$or_group = $query->orConditionGroup();
|
||||
foreach ($item_values as $item_value) {
|
||||
$or_group->condition($field_name, \Drupal::database()->escapeLike($item_value), 'LIKE');
|
||||
}
|
||||
$query->condition($or_group);
|
||||
}
|
||||
|
||||
$results = $query->execute();
|
||||
|
||||
if (!empty($results)) {
|
||||
|
|
|
@ -4,7 +4,8 @@ namespace Drupal\file\Plugin\Validation\Constraint;
|
|||
|
||||
use Drupal\Core\StringTranslation\TranslatableMarkup;
|
||||
use Drupal\Core\Validation\Attribute\Constraint;
|
||||
use Symfony\Component\Validator\Constraint as SymfonyConstraint;
|
||||
use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldConstraint;
|
||||
use Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator;
|
||||
|
||||
/**
|
||||
* Supports validating file URIs.
|
||||
|
@ -13,15 +14,25 @@ use Symfony\Component\Validator\Constraint as SymfonyConstraint;
|
|||
id: 'FileUriUnique',
|
||||
label: new TranslatableMarkup('File URI', [], ['context' => 'Validation'])
|
||||
)]
|
||||
class FileUriUnique extends SymfonyConstraint {
|
||||
class FileUriUnique extends UniqueFieldConstraint {
|
||||
|
||||
public $message = 'The file %value already exists. Enter a unique file URI.';
|
||||
|
||||
/**
|
||||
* This constraint is case-sensitive.
|
||||
*
|
||||
* For example "public://foo.txt" and "public://FOO.txt" are treated as
|
||||
* different values, and can co-exist.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $caseSensitive = TRUE;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validatedBy(): string {
|
||||
return '\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator';
|
||||
return UniqueFieldValueValidator::class;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ function user_requirements($phase): array {
|
|||
if ($phase !== 'runtime') {
|
||||
return [];
|
||||
}
|
||||
$return = [];
|
||||
|
||||
$result = (bool) \Drupal::entityQuery('user')
|
||||
->accessCheck(FALSE)
|
||||
|
@ -106,17 +107,32 @@ function user_requirements($phase): array {
|
|||
->execute();
|
||||
|
||||
if ($result === FALSE) {
|
||||
return [
|
||||
'anonymous user' => [
|
||||
'title' => t('Anonymous user'),
|
||||
'description' => t('The anonymous user does not exist. See the <a href=":url">restore the anonymous (user ID 0) user record</a> for more information', [
|
||||
':url' => 'https://www.drupal.org/node/1029506',
|
||||
]),
|
||||
'severity' => REQUIREMENT_WARNING,
|
||||
],
|
||||
$return['anonymous user'] = [
|
||||
'title' => t('Anonymous user'),
|
||||
'description' => t('The anonymous user does not exist. See the <a href=":url">restore the anonymous (user ID 0) user record</a> for more information', [
|
||||
':url' => 'https://www.drupal.org/node/1029506',
|
||||
]),
|
||||
'severity' => REQUIREMENT_WARNING,
|
||||
];
|
||||
}
|
||||
return [];
|
||||
|
||||
$query = \Drupal::database()->select('users_field_data');
|
||||
$query->addExpression('LOWER(mail)', 'lower_mail');
|
||||
$query->groupBy('lower_mail');
|
||||
$query->having('COUNT(uid) > :matches', [':matches' => 1]);
|
||||
$conflicts = $query->countQuery()->execute()->fetchField();
|
||||
|
||||
if ($conflicts > 0) {
|
||||
$return['conflicting emails'] = [
|
||||
'title' => t('Conflicting user emails'),
|
||||
'description' => t('Some user accounts have email addresses that differ only by case. For example, one account might have alice@example.com and another might have Alice@Example.com. See <a href=":url">Conflicting User Emails</a> for more information.', [
|
||||
':url' => 'https://www.drupal.org/node/3486109',
|
||||
]),
|
||||
'severity' => REQUIREMENT_WARNING,
|
||||
];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue