Skip to content

Commit

Permalink
SA-CORE-2024-004 by zengenuity, cilefen, kristiaanvandeneynde, mcdrui…
Browse files Browse the repository at this point in the history
…d, larowlan
  • Loading branch information
longwave committed Nov 20, 2024
1 parent 276ac67 commit 7ae0e8f
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,23 @@ public function validate($items, Constraint $constraint): void {
->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)) {
Expand Down
17 changes: 14 additions & 3 deletions modules/file/src/Plugin/Validation/Constraint/FileUriUnique.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

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.
Expand All @@ -13,15 +14,25 @@
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;
}

}
34 changes: 25 additions & 9 deletions modules/user/user.install
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ function user_requirements($phase): array {
if ($phase !== 'runtime') {
return [];
}
$return = [];

$result = (bool) \Drupal::entityQuery('user')
->accessCheck(FALSE)
Expand All @@ -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,
];
}

$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 [email protected] and another might have [email protected]. See <a href=":url">Conflicting User Emails</a> for more information.', [
':url' => 'https://www.drupal.org/node/3486109',
]),
'severity' => REQUIREMENT_WARNING,
];
}
return [];

return $return;
}

/**
Expand Down

0 comments on commit 7ae0e8f

Please sign in to comment.