Added validation to not found redirects for domain

This commit is contained in:
Alejandro Celaya 2021-08-03 14:08:36 +02:00
parent 20f70b8b07
commit 9f25979b4c
9 changed files with 106 additions and 25 deletions

View File

@ -92,7 +92,7 @@ class DomainRedirectsCommand extends Command
};
};
$this->domainService->configureNotFoundRedirects($domainAuthority, new NotFoundRedirects(
$this->domainService->configureNotFoundRedirects($domainAuthority, NotFoundRedirects::withRedirects(
$ask(
'URL to redirect to when a user hits this domain\'s base URL',
$domain?->baseUrlRedirect(),

View File

@ -40,7 +40,7 @@ class DomainRedirectsCommandTest extends TestCase
$findDomain = $this->domainService->findByAuthority($domainAuthority)->willReturn($domain);
$configureRedirects = $this->domainService->configureNotFoundRedirects(
$domainAuthority,
new NotFoundRedirects('foo.com', null, 'baz.com'),
NotFoundRedirects::withRedirects('foo.com', null, 'baz.com'),
)->willReturn(Domain::withAuthority(''));
$this->commandTester->setInputs(['foo.com', '', 'baz.com']);
@ -71,12 +71,12 @@ class DomainRedirectsCommandTest extends TestCase
{
$domainAuthority = 'example.com';
$domain = Domain::withAuthority($domainAuthority);
$domain->configureNotFoundRedirects(new NotFoundRedirects('foo.com', 'bar.com', 'baz.com'));
$domain->configureNotFoundRedirects(NotFoundRedirects::withRedirects('foo.com', 'bar.com', 'baz.com'));
$findDomain = $this->domainService->findByAuthority($domainAuthority)->willReturn($domain);
$configureRedirects = $this->domainService->configureNotFoundRedirects(
$domainAuthority,
new NotFoundRedirects(null, 'edited.com', 'baz.com'),
NotFoundRedirects::withRedirects(null, 'edited.com', 'baz.com'),
)->willReturn($domain);
$this->commandTester->setInputs(['2', '1', 'edited.com', '0']);
@ -105,7 +105,7 @@ class DomainRedirectsCommandTest extends TestCase
$findDomain = $this->domainService->findByAuthority($domainAuthority)->willReturn($domain);
$configureRedirects = $this->domainService->configureNotFoundRedirects(
$domainAuthority,
new NotFoundRedirects(),
NotFoundRedirects::withoutRedirects(),
)->willReturn($domain);
$this->commandTester->setInputs([$domainAuthority, '', '', '']);
@ -132,7 +132,7 @@ class DomainRedirectsCommandTest extends TestCase
$findDomain = $this->domainService->findByAuthority($domainAuthority)->willReturn($domain);
$configureRedirects = $this->domainService->configureNotFoundRedirects(
$domainAuthority,
new NotFoundRedirects(),
NotFoundRedirects::withoutRedirects(),
)->willReturn($domain);
$this->commandTester->setInputs(['1', '', '', '']);
@ -162,7 +162,7 @@ class DomainRedirectsCommandTest extends TestCase
$findDomain = $this->domainService->findByAuthority($domainAuthority)->willReturn($domain);
$configureRedirects = $this->domainService->configureNotFoundRedirects(
$domainAuthority,
new NotFoundRedirects(),
NotFoundRedirects::withoutRedirects(),
)->willReturn($domain);
$this->commandTester->setInputs(['2', $domainAuthority, '', '', '']);

View File

@ -36,7 +36,7 @@ class ListDomainsCommandTest extends TestCase
public function allDomainsAreProperlyPrinted(array $input, string $expectedOutput): void
{
$bazDomain = Domain::withAuthority('baz.com');
$bazDomain->configureNotFoundRedirects(new NotFoundRedirects(
$bazDomain->configureNotFoundRedirects(NotFoundRedirects::withRedirects(
null,
'https://foo.com/baz-domain/regular',
'https://foo.com/baz-domain/invalid',

View File

@ -8,13 +8,26 @@ use JsonSerializable;
final class NotFoundRedirects implements JsonSerializable
{
public function __construct(
private ?string $baseUrlRedirect = null,
private ?string $regular404Redirect = null,
private ?string $invalidShortUrlRedirect = null,
private function __construct(
private ?string $baseUrlRedirect,
private ?string $regular404Redirect,
private ?string $invalidShortUrlRedirect,
) {
}
public static function withRedirects(
?string $baseUrlRedirect = null,
?string $regular404Redirect = null,
?string $invalidShortUrlRedirect = null,
): self {
return new self($baseUrlRedirect, $regular404Redirect, $invalidShortUrlRedirect);
}
public static function withoutRedirects(): self
{
return new self(null, null, null);
}
public function baseUrlRedirect(): ?string
{
return $this->baseUrlRedirect;

View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Domain\Validation;
use Laminas\InputFilter\InputFilter;
use Laminas\Validator;
use Shlinkio\Shlink\Common\Validation;
class DomainRedirectsInputFilter extends InputFilter
{
use Validation\InputFactoryTrait;
public const DOMAIN = 'domain';
public const BASE_URL_REDIRECT = 'baseUrlRedirect';
public const REGULAR_404_REDIRECT = 'regular404Redirect';
public const INVALID_SHORT_URL_REDIRECT = 'invalidShortUrlRedirect';
private function __construct()
{
}
public static function withData(array $data): self
{
$instance = new self();
$instance->initializeInputs();
$instance->setData($data);
return $instance;
}
private function initializeInputs(): void
{
$domain = $this->createInput(self::DOMAIN);
$domain->getValidatorChain()->attach(new Validator\NotEmpty([
Validator\NotEmpty::OBJECT,
Validator\NotEmpty::SPACE,
Validator\NotEmpty::NULL,
Validator\NotEmpty::EMPTY_ARRAY,
Validator\NotEmpty::BOOLEAN,
]));
$this->add($domain);
$this->add($this->createInput(self::BASE_URL_REDIRECT, false));
$this->add($this->createInput(self::REGULAR_404_REDIRECT, false));
$this->add($this->createInput(self::INVALID_SHORT_URL_REDIRECT, false));
}
}

View File

@ -45,7 +45,7 @@ class DomainRepositoryTest extends DatabaseTestCase
$this->getEntityManager()->persist($detachedDomain);
$detachedWithRedirects = Domain::withAuthority('detached-with-redirects.com');
$detachedWithRedirects->configureNotFoundRedirects(new NotFoundRedirects('foo.com', 'bar.com'));
$detachedWithRedirects->configureNotFoundRedirects(NotFoundRedirects::withRedirects('foo.com', 'bar.com'));
$this->getEntityManager()->persist($detachedWithRedirects);
$this->getEntityManager()->flush();
@ -101,7 +101,7 @@ class DomainRepositoryTest extends DatabaseTestCase
$this->getEntityManager()->persist($detachedDomain);
$detachedWithRedirects = Domain::withAuthority('detached-with-redirects.com');
$detachedWithRedirects->configureNotFoundRedirects(new NotFoundRedirects('foo.com', 'bar.com'));
$detachedWithRedirects->configureNotFoundRedirects(NotFoundRedirects::withRedirects('foo.com', 'bar.com'));
$this->getEntityManager()->persist($detachedWithRedirects);
$this->getEntityManager()->flush();

View File

@ -183,7 +183,7 @@ class DomainServiceTest extends TestCase
$persist = $this->em->persist($foundDomain ?? Argument::type(Domain::class));
$flush = $this->em->flush();
$result = $this->domainService->configureNotFoundRedirects($authority, new NotFoundRedirects(
$result = $this->domainService->configureNotFoundRedirects($authority, NotFoundRedirects::withRedirects(
'foo.com',
'bar.com',
'baz.com',

View File

@ -6,6 +6,8 @@ namespace Shlinkio\Shlink\Rest\Action\Domain\Request;
use Shlinkio\Shlink\Core\Config\NotFoundRedirectConfigInterface;
use Shlinkio\Shlink\Core\Config\NotFoundRedirects;
use Shlinkio\Shlink\Core\Domain\Validation\DomainRedirectsInputFilter;
use Shlinkio\Shlink\Core\Exception\ValidationException;
use function array_key_exists;
@ -30,17 +32,33 @@ class DomainRedirectsRequest
return $instance;
}
/**
* @throws ValidationException
*/
private function validateAndInit(array $payload): void
{
// TODO Validate data
$this->baseUrlRedirectWasProvided = array_key_exists('baseUrlRedirect', $payload);
$this->regular404RedirectWasProvided = array_key_exists('regular404Redirect', $payload);
$this->invalidShortUrlRedirectWasProvided = array_key_exists('invalidShortUrlRedirect', $payload);
$inputFilter = DomainRedirectsInputFilter::withData($payload);
if (! $inputFilter->isValid()) {
throw ValidationException::fromInputFilter($inputFilter);
}
$this->authority = $payload['domain'];
$this->baseUrlRedirect = $payload['baseUrlRedirect'] ?? null;
$this->regular404Redirect = $payload['regular404Redirect'] ?? null;
$this->invalidShortUrlRedirect = $payload['invalidShortUrlRedirect'] ?? null;
$this->baseUrlRedirectWasProvided = array_key_exists(
DomainRedirectsInputFilter::BASE_URL_REDIRECT,
$payload,
);
$this->regular404RedirectWasProvided = array_key_exists(
DomainRedirectsInputFilter::REGULAR_404_REDIRECT,
$payload,
);
$this->invalidShortUrlRedirectWasProvided = array_key_exists(
DomainRedirectsInputFilter::INVALID_SHORT_URL_REDIRECT,
$payload,
);
$this->authority = $inputFilter->getValue(DomainRedirectsInputFilter::DOMAIN);
$this->baseUrlRedirect = $inputFilter->getValue(DomainRedirectsInputFilter::BASE_URL_REDIRECT);
$this->regular404Redirect = $inputFilter->getValue(DomainRedirectsInputFilter::REGULAR_404_REDIRECT);
$this->invalidShortUrlRedirect = $inputFilter->getValue(DomainRedirectsInputFilter::INVALID_SHORT_URL_REDIRECT);
}
public function authority(): string
@ -50,7 +68,7 @@ class DomainRedirectsRequest
public function toNotFoundRedirects(?NotFoundRedirectConfigInterface $defaults = null): NotFoundRedirects
{
return new NotFoundRedirects(
return NotFoundRedirects::withRedirects(
$this->baseUrlRedirectWasProvided ? $this->baseUrlRedirect : $defaults?->baseUrlRedirect(),
$this->regular404RedirectWasProvided ? $this->regular404Redirect : $defaults?->regular404Redirect(),
$this->invalidShortUrlRedirectWasProvided

View File

@ -20,7 +20,7 @@ class DomainFixture extends AbstractFixture
$manager->persist(Domain::withAuthority('this_domain_is_detached.com'));
$detachedWithRedirects = Domain::withAuthority('detached-with-redirects.com');
$detachedWithRedirects->configureNotFoundRedirects(new NotFoundRedirects('foo.com', 'bar.com'));
$detachedWithRedirects->configureNotFoundRedirects(NotFoundRedirects::withRedirects('foo.com', 'bar.com'));
$manager->persist($detachedWithRedirects);
$manager->flush();