Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH Use symfony/validation logic #11399

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved

# 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'
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved
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",
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved
"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 <[email protected]>
* 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.
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved
*/
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),
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved
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)) {
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved
$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)) {
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved
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;
}
}
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved
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']
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved
): 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
Loading