mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-23 21:27:44 +03:00
Allowed port number on domain field when creating shotr URLs
This commit is contained in:
parent
232bf5a68b
commit
b5e4da847a
3 changed files with 44 additions and 13 deletions
|
@ -50,9 +50,7 @@ class ShortUrlMetaInputFilter extends InputFilter
|
||||||
$this->add($this->createBooleanInput(self::FIND_IF_EXISTS, false));
|
$this->add($this->createBooleanInput(self::FIND_IF_EXISTS, false));
|
||||||
|
|
||||||
$domain = $this->createInput(self::DOMAIN, false);
|
$domain = $this->createInput(self::DOMAIN, false);
|
||||||
$domain->getValidatorChain()->attach(new Validator\Hostname([
|
$domain->getValidatorChain()->attach(new Validation\HostAndPortValidator());
|
||||||
'allow' => Validator\Hostname::ALLOW_DNS | Validator\Hostname::ALLOW_LOCAL,
|
|
||||||
]));
|
|
||||||
$this->add($domain);
|
$this->add($domain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
|
||||||
use Cake\Chronos\Chronos;
|
use Cake\Chronos\Chronos;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||||
|
use Shlinkio\Shlink\Core\Exception\ValidationException;
|
||||||
use Shlinkio\Shlink\Core\Model\CreateShortUrlData;
|
use Shlinkio\Shlink\Core\Model\CreateShortUrlData;
|
||||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||||
use Zend\Diactoros\Uri;
|
use Zend\Diactoros\Uri;
|
||||||
|
@ -29,18 +30,20 @@ class CreateShortUrlAction extends AbstractCreateShortUrlAction
|
||||||
throw new InvalidArgumentException('A URL was not provided');
|
throw new InvalidArgumentException('A URL was not provided');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CreateShortUrlData(
|
try {
|
||||||
new Uri($postData['longUrl']),
|
$meta = ShortUrlMeta::createFromParams(
|
||||||
(array) ($postData['tags'] ?? []),
|
|
||||||
ShortUrlMeta::createFromParams(
|
|
||||||
$this->getOptionalDate($postData, 'validSince'),
|
$this->getOptionalDate($postData, 'validSince'),
|
||||||
$this->getOptionalDate($postData, 'validUntil'),
|
$this->getOptionalDate($postData, 'validUntil'),
|
||||||
$postData['customSlug'] ?? null,
|
$postData['customSlug'] ?? null,
|
||||||
$postData['maxVisits'] ?? null,
|
$postData['maxVisits'] ?? null,
|
||||||
$postData['findIfExists'] ?? null,
|
$postData['findIfExists'] ?? null,
|
||||||
$postData['domain'] ?? null
|
$postData['domain'] ?? null
|
||||||
)
|
);
|
||||||
);
|
|
||||||
|
return new CreateShortUrlData(new Uri($postData['longUrl']), (array) ($postData['tags'] ?? []), $meta);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
throw new InvalidArgumentException('Provided meta data is not valid', -1, $e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getOptionalDate(array $postData, string $fieldName): ?Chronos
|
private function getOptionalDate(array $postData, string $fieldName): ?Chronos
|
||||||
|
|
|
@ -15,6 +15,7 @@ use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||||
use Shlinkio\Shlink\Rest\Action\ShortUrl\CreateShortUrlAction;
|
use Shlinkio\Shlink\Rest\Action\ShortUrl\CreateShortUrlAction;
|
||||||
use Shlinkio\Shlink\Rest\Util\RestUtils;
|
use Shlinkio\Shlink\Rest\Util\RestUtils;
|
||||||
|
use Zend\Diactoros\Response\JsonResponse;
|
||||||
use Zend\Diactoros\ServerRequest;
|
use Zend\Diactoros\ServerRequest;
|
||||||
use Zend\Diactoros\Uri;
|
use Zend\Diactoros\Uri;
|
||||||
|
|
||||||
|
@ -50,8 +51,8 @@ class CreateShortUrlActionTest extends TestCase
|
||||||
{
|
{
|
||||||
$shortUrl = new ShortUrl('');
|
$shortUrl = new ShortUrl('');
|
||||||
$this->urlShortener->urlToShortCode(Argument::type(Uri::class), Argument::type('array'), Argument::cetera())
|
$this->urlShortener->urlToShortCode(Argument::type(Uri::class), Argument::type('array'), Argument::cetera())
|
||||||
->willReturn($shortUrl)
|
->willReturn($shortUrl)
|
||||||
->shouldBeCalledOnce();
|
->shouldBeCalledOnce();
|
||||||
|
|
||||||
$request = (new ServerRequest())->withParsedBody([
|
$request = (new ServerRequest())->withParsedBody([
|
||||||
'longUrl' => 'http://www.domain.com/foo/bar',
|
'longUrl' => 'http://www.domain.com/foo/bar',
|
||||||
|
@ -65,8 +66,8 @@ class CreateShortUrlActionTest extends TestCase
|
||||||
public function anInvalidUrlReturnsError(): void
|
public function anInvalidUrlReturnsError(): void
|
||||||
{
|
{
|
||||||
$this->urlShortener->urlToShortCode(Argument::type(Uri::class), Argument::type('array'), Argument::cetera())
|
$this->urlShortener->urlToShortCode(Argument::type(Uri::class), Argument::type('array'), Argument::cetera())
|
||||||
->willThrow(InvalidUrlException::class)
|
->willThrow(InvalidUrlException::class)
|
||||||
->shouldBeCalledOnce();
|
->shouldBeCalledOnce();
|
||||||
|
|
||||||
$request = (new ServerRequest())->withParsedBody([
|
$request = (new ServerRequest())->withParsedBody([
|
||||||
'longUrl' => 'http://www.domain.com/foo/bar',
|
'longUrl' => 'http://www.domain.com/foo/bar',
|
||||||
|
@ -76,6 +77,35 @@ class CreateShortUrlActionTest extends TestCase
|
||||||
$this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::INVALID_URL_ERROR) > 0);
|
$this->assertTrue(strpos($response->getBody()->getContents(), RestUtils::INVALID_URL_ERROR) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @dataProvider provideInvalidDomains
|
||||||
|
*/
|
||||||
|
public function anInvalidDomainReturnsError(string $domain): void
|
||||||
|
{
|
||||||
|
$shortUrl = new ShortUrl('');
|
||||||
|
$urlToShortCode = $this->urlShortener->urlToShortCode(Argument::cetera())->willReturn($shortUrl);
|
||||||
|
|
||||||
|
$request = (new ServerRequest())->withParsedBody([
|
||||||
|
'longUrl' => 'http://www.domain.com/foo/bar',
|
||||||
|
'domain' => $domain,
|
||||||
|
]);
|
||||||
|
/** @var JsonResponse $response */
|
||||||
|
$response = $this->action->handle($request);
|
||||||
|
$payload = $response->getPayload();
|
||||||
|
|
||||||
|
$this->assertEquals(400, $response->getStatusCode());
|
||||||
|
$this->assertEquals(RestUtils::INVALID_ARGUMENT_ERROR, $payload['error']);
|
||||||
|
$urlToShortCode->shouldNotHaveBeenCalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideInvalidDomains(): iterable
|
||||||
|
{
|
||||||
|
yield ['localhost:80000'];
|
||||||
|
yield ['127.0.0.1'];
|
||||||
|
yield ['???/&%$&'];
|
||||||
|
}
|
||||||
|
|
||||||
/** @test */
|
/** @test */
|
||||||
public function nonUniqueSlugReturnsError(): void
|
public function nonUniqueSlugReturnsError(): void
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue