ENH Use symfony/validation logic (#3009)

This commit is contained in:
Guy Sartorelli 2024-10-02 18:39:01 +13:00 committed by GitHub
parent 6194844f61
commit bd48b04731
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 5 additions and 62 deletions

View File

@ -7,6 +7,7 @@ use SilverStripe\Assets\File;
use SilverStripe\Forms\FieldList; use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\HeaderField; use SilverStripe\Forms\HeaderField;
use SilverStripe\Forms\OptionsetField; use SilverStripe\Forms\OptionsetField;
use SilverStripe\Forms\UrlField;
use SilverStripe\Versioned\Versioned; use SilverStripe\Versioned\Versioned;
/** /**
@ -47,6 +48,9 @@ class RedirectorPage extends Page
'RedirectionType', 'RedirectionType',
'Content', 'Content',
], ],
'fieldClasses' => [
'ExternalURL' => UrlField::class,
],
]; ];
private static $table_name = 'RedirectorPage'; private static $table_name = 'RedirectorPage';
@ -171,35 +175,12 @@ class RedirectorPage extends Page
} }
} }
protected function onBeforeWrite()
{
parent::onBeforeWrite();
if ($this->ExternalURL && substr($this->ExternalURL ?? '', 0, 2) !== '//') {
$urlParts = parse_url($this->ExternalURL ?? '');
if ($urlParts) {
if (empty($urlParts['scheme'])) {
// no scheme, assume http
$this->ExternalURL = 'http://' . $this->ExternalURL;
} elseif (!in_array($urlParts['scheme'], [
'http',
'https',
])) {
// we only allow http(s) urls
$this->ExternalURL = '';
}
} else {
// malformed URL to reject
$this->ExternalURL = '';
}
}
}
public function getCMSFields() public function getCMSFields()
{ {
$this->beforeUpdateCMSFields(function (FieldList $fields) { $this->beforeUpdateCMSFields(function (FieldList $fields) {
// Remove all metadata fields, does not apply for redirector pages // Remove all metadata fields, does not apply for redirector pages
$fields->removeByName('Metadata'); $fields->removeByName('Metadata');
$fields->dataFieldByName('ExternalURL')?->setAllowRelativeProtocol(true);
$fields->addFieldsToTab( $fields->addFieldsToTab(
'Root.Main', 'Root.Main',

View File

@ -121,33 +121,6 @@ class RedirectorPageTest extends FunctionalTest
$this->assertEquals(Director::absoluteURL('/redirection-dest'), $response->getHeader("Location")); $this->assertEquals(Director::absoluteURL('/redirection-dest'), $response->getHeader("Location"));
} }
public function testExternalURLGetsPrefixIfNotSet()
{
$page = $this->objFromFixture(RedirectorPage::class, 'externalnoprefix');
$this->assertEquals($page->ExternalURL, 'http://google.com', 'onBeforeWrite has prefixed with http');
$page->write();
$this->assertEquals(
$page->ExternalURL,
'http://google.com',
'onBeforeWrite will not double prefix if written again!'
);
}
public function testAllowsProtocolRelative()
{
$noProtocol = new RedirectorPage(['ExternalURL' => 'mydomain.com']);
$noProtocol->write();
$this->assertEquals('http://mydomain.com', $noProtocol->ExternalURL);
$protocolAbsolute = new RedirectorPage(['ExternalURL' => 'http://mydomain.com']);
$protocolAbsolute->write();
$this->assertEquals('http://mydomain.com', $protocolAbsolute->ExternalURL);
$protocolRelative = new RedirectorPage(['ExternalURL' => '//mydomain.com']);
$protocolRelative->write();
$this->assertEquals('//mydomain.com', $protocolRelative->ExternalURL);
}
/** /**
* Test that we can trigger a redirection before RedirectorPageController::init() is called * Test that we can trigger a redirection before RedirectorPageController::init() is called
*/ */
@ -163,17 +136,6 @@ class RedirectorPageTest extends FunctionalTest
RedirectorPageController::remove_extension(RedirectorPageTest_RedirectExtension::class); RedirectorPageController::remove_extension(RedirectorPageTest_RedirectExtension::class);
} }
public function testNoJSLinksAllowed()
{
$page = new RedirectorPage();
$js = 'javascript:alert("hello world")';
$page->ExternalURL = $js;
$this->assertEquals($js, $page->ExternalURL);
$page->write();
$this->assertEmpty($page->ExternalURL);
}
public function testFileRedirector() public function testFileRedirector()
{ {
$page = $this->objFromFixture(RedirectorPage::class, 'file'); $page = $this->objFromFixture(RedirectorPage::class, 'file');