Skip to content

Commit

Permalink
ENH Use symfony/validation logic (#11399)
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli authored Oct 2, 2024
1 parent aa2b8c3 commit 7f11bf3
Show file tree
Hide file tree
Showing 28 changed files with 543 additions and 459 deletions.
3 changes: 2 additions & 1 deletion _config/backtrace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ SilverStripe\Dev\Backtrace:
- ['SilverStripe\Security\PasswordEncryptor_Blowfish', 'encryptA']
- ['SilverStripe\Security\PasswordEncryptor_Blowfish', 'encryptX']
- ['SilverStripe\Security\PasswordEncryptor_Blowfish', 'encryptY']
- ['SilverStripe\Security\PasswordValidator', 'validate']
- ['SilverStripe\Security\Validation\RulesPasswordValidator', 'validate']
- ['SilverStripe\Security\Validation\EntropyPasswordValidator', 'validate']
- ['SilverStripe\Security\RememberLoginHash', 'setToken']
- ['SilverStripe\Security\Security', 'encrypt_password']
- ['*', 'checkPassword']
Expand Down
11 changes: 2 additions & 9 deletions _config/passwords.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,5 @@
Name: corepasswords
---
SilverStripe\Core\Injector\Injector:
SilverStripe\Security\PasswordValidator:
properties:
MinLength: 8
HistoricCount: 6

# In the case someone uses `new PasswordValidator` instead of Injector, provide some safe defaults through config.
SilverStripe\Security\PasswordValidator:
min_length: 8
historic_count: 6
SilverStripe\Security\Validation\PasswordValidator:
class: 'SilverStripe\Security\Validation\EntropyPasswordValidator'
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"symfony/mailer": "^7.0",
"symfony/mime": "^7.0",
"symfony/translation": "^7.0",
"symfony/validator": "^7.0",
"symfony/validator": "^7.1",
"symfony/yaml": "^7.0",
"ext-ctype": "*",
"ext-dom": "*",
Expand Down
22 changes: 12 additions & 10 deletions src/Control/Email/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@

use Exception;
use RuntimeException;
use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Validation\RFCValidation;
use SilverStripe\Control\Director;
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Environment;
use SilverStripe\Core\Extensible;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Core\Validation\ConstraintValidator;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\Model\ArrayData;
use SilverStripe\View\Requirements;
Expand All @@ -22,6 +21,8 @@
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email as SymfonyEmail;
use Symfony\Component\Mime\Part\AbstractPart;
use Symfony\Component\Validator\Constraints\Email as EmailConstraint;
use Symfony\Component\Validator\Constraints\NotBlank;

class Email extends SymfonyEmail
{
Expand Down Expand Up @@ -63,16 +64,17 @@ class Email extends SymfonyEmail
private bool $dataHasBeenSet = false;

/**
* Checks for RFC822-valid email format.
*
* @copyright Cal Henderson <cal@iamcal.com>
* This code is licensed under a Creative Commons Attribution-ShareAlike 2.5 License
* http://creativecommons.org/licenses/by-sa/2.5/
* Checks for RFC valid email format.
*/
public static function is_valid_address(string $address): bool
{
$validator = new EmailValidator();
return $validator->isValid($address, new RFCValidation());
return ConstraintValidator::validate(
$address,
[
new EmailConstraint(mode: EmailConstraint::VALIDATION_MODE_STRICT),
new NotBlank()
]
)->isValid();
}

public static function getSendAllEmailsTo(): array
Expand Down Expand Up @@ -117,7 +119,7 @@ private static function convertConfigToAddreses(array|string $config): array
$addresses = [];
if (is_array($config)) {
foreach ($config as $key => $val) {
if (filter_var($key, FILTER_VALIDATE_EMAIL)) {
if (static::is_valid_address($key)) {
$addresses[] = new Address($key, $val);
} else {
$addresses[] = new Address($val);
Expand Down
5 changes: 4 additions & 1 deletion src/Control/HTTPRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use InvalidArgumentException;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\ArrayLib;
use Symfony\Component\Validator\Constraints\Ip;
use Symfony\Component\Validator\Constraints\IpValidator;

/**
* Represents a HTTP-request, including a URL that is tokenised for parsing, and a request method
Expand Down Expand Up @@ -810,7 +812,8 @@ public function getIP()
*/
public function setIP($ip)
{
if (!filter_var($ip, FILTER_VALIDATE_IP)) {
// We can't use ConstraintValidator here because it relies on injector and the kernel may not have booted yet.
if (!IpValidator::checkIp($ip, Ip::ALL)) {
throw new InvalidArgumentException("Invalid ip $ip");
}
$this->ip = $ip;
Expand Down
11 changes: 7 additions & 4 deletions src/Control/Middleware/TrustedProxyMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
namespace SilverStripe\Control\Middleware;

use SilverStripe\Control\HTTPRequest;
use SilverStripe\Core\Validation\ConstraintValidator;
use Symfony\Component\HttpFoundation\IpUtils;
use Symfony\Component\Validator\Constraints\Ip;
use Symfony\Component\Validator\Constraints\NotBlank;

/**
* This middleware will rewrite headers that provide IP and host details from an upstream proxy.
Expand Down Expand Up @@ -220,14 +223,14 @@ protected function getIPFromHeaderValue($headerValue)

// Prioritise filters
$filters = [
FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE,
FILTER_FLAG_NO_PRIV_RANGE,
null
Ip::ALL_ONLY_PUBLIC,
Ip::ALL_NO_PRIVATE,
Ip::ALL
];
foreach ($filters as $filter) {
// Find best IP
foreach ($ips as $ip) {
if (filter_var($ip, FILTER_VALIDATE_IP, $filter ?? 0)) {
if (ConstraintValidator::validate($ip, [new Ip(version: $filter), new NotBlank()])->isValid()) {
return $ip;
}
}
Expand Down
15 changes: 8 additions & 7 deletions src/Core/Convert.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace SilverStripe\Core;

use SilverStripe\Core\Validation\ConstraintValidator;
use SimpleXMLElement;
use SilverStripe\ORM\DB;
use SilverStripe\View\Parsers\URLSegmentFilter;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Url;

/**
* Library of conversion functions, implemented as static methods.
Expand Down Expand Up @@ -226,16 +229,14 @@ public static function xml2raw($val)

/**
* Create a link if the string is a valid URL
*
* @param string $string The string to linkify
* @return string A link to the URL if string is a URL
*/
public static function linkIfMatch($string)
{
if (preg_match('/^[a-z+]+\:\/\/[a-zA-Z0-9$-_.+?&=!*\'()%]+$/', $string ?? '')) {
public static function linkIfMatch(
string $string,
array $protocols = ['file', 'ftp', 'http', 'https', 'imap', 'nntp']
): string {
if (ConstraintValidator::validate($string, [new Url(protocols: $protocols), new NotBlank()])->isValid()) {
return "<a style=\"white-space: nowrap\" href=\"$string\">$string</a>";
}

return $string;
}

Expand Down
Loading

0 comments on commit 7f11bf3

Please sign in to comment.