mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-28 09:03:07 +03:00
Added mechanisms to be able to provide the API key when creating a short URL
This commit is contained in:
parent
97f89bcede
commit
2732b05834
11 changed files with 113 additions and 25 deletions
|
@ -7,7 +7,6 @@ namespace Shlinkio\Shlink\Core;
|
|||
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
|
||||
use Mezzio\Template\TemplateRendererInterface;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Shlinkio\Shlink\Core\Domain\Resolver;
|
||||
use Shlinkio\Shlink\Core\ErrorHandler;
|
||||
use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions;
|
||||
use Shlinkio\Shlink\Importer\ImportedLinksProcessorInterface;
|
||||
|
@ -42,7 +41,7 @@ return [
|
|||
Action\PixelAction::class => ConfigAbstractFactory::class,
|
||||
Action\QrCodeAction::class => ConfigAbstractFactory::class,
|
||||
|
||||
Resolver\PersistenceDomainResolver::class => ConfigAbstractFactory::class,
|
||||
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class => ConfigAbstractFactory::class,
|
||||
|
||||
Mercure\MercureUpdatesGenerator::class => ConfigAbstractFactory::class,
|
||||
|
||||
|
@ -66,7 +65,7 @@ return [
|
|||
Service\UrlShortener::class => [
|
||||
Util\UrlValidator::class,
|
||||
'em',
|
||||
Resolver\PersistenceDomainResolver::class,
|
||||
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class,
|
||||
Service\ShortUrl\ShortCodeHelper::class,
|
||||
],
|
||||
Service\VisitsTracker::class => [
|
||||
|
@ -109,13 +108,13 @@ return [
|
|||
'Logger_Shlink',
|
||||
],
|
||||
|
||||
Resolver\PersistenceDomainResolver::class => ['em'],
|
||||
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class => ['em'],
|
||||
|
||||
Mercure\MercureUpdatesGenerator::class => ['config.url_shortener.domain'],
|
||||
|
||||
Importer\ImportedLinksProcessor::class => [
|
||||
'em',
|
||||
Resolver\PersistenceDomainResolver::class,
|
||||
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class,
|
||||
Service\ShortUrl\ShortCodeHelper::class,
|
||||
Util\DoctrineBatchHelper::class,
|
||||
],
|
||||
|
|
|
@ -9,11 +9,11 @@ use Doctrine\Common\Collections\ArrayCollection;
|
|||
use Doctrine\Common\Collections\Collection;
|
||||
use Laminas\Diactoros\Uri;
|
||||
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
|
||||
use Shlinkio\Shlink\Core\Domain\Resolver\DomainResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Domain\Resolver\SimpleDomainResolver;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortCodeCannotBeRegeneratedException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlEdit;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Resolver\SimpleShortUrlRelationResolver;
|
||||
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
|
||||
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
@ -43,9 +43,10 @@ class ShortUrl extends AbstractEntity
|
|||
public function __construct(
|
||||
string $longUrl,
|
||||
?ShortUrlMeta $meta = null,
|
||||
?DomainResolverInterface $domainResolver = null
|
||||
?ShortUrlRelationResolverInterface $relationResolver = null
|
||||
) {
|
||||
$meta = $meta ?? ShortUrlMeta::createEmpty();
|
||||
$relationResolver = $relationResolver ?? new SimpleShortUrlRelationResolver();
|
||||
|
||||
$this->longUrl = $longUrl;
|
||||
$this->dateCreated = Chronos::now();
|
||||
|
@ -57,13 +58,14 @@ class ShortUrl extends AbstractEntity
|
|||
$this->customSlugWasProvided = $meta->hasCustomSlug();
|
||||
$this->shortCodeLength = $meta->getShortCodeLength();
|
||||
$this->shortCode = $meta->getCustomSlug() ?? generateRandomShortCode($this->shortCodeLength);
|
||||
$this->domain = ($domainResolver ?? new SimpleDomainResolver())->resolveDomain($meta->getDomain());
|
||||
$this->domain = $relationResolver->resolveDomain($meta->getDomain());
|
||||
$this->authorApiKey = $relationResolver->resolveApiKey($meta->getApiKey());
|
||||
}
|
||||
|
||||
public static function fromImport(
|
||||
ImportedShlinkUrl $url,
|
||||
bool $importShortCode,
|
||||
?DomainResolverInterface $domainResolver = null
|
||||
?ShortUrlRelationResolverInterface $relationResolver = null
|
||||
): self {
|
||||
$meta = [
|
||||
ShortUrlMetaInputFilter::DOMAIN => $url->domain(),
|
||||
|
@ -73,7 +75,7 @@ class ShortUrl extends AbstractEntity
|
|||
$meta[ShortUrlMetaInputFilter::CUSTOM_SLUG] = $url->shortCode();
|
||||
}
|
||||
|
||||
$instance = new self($url->longUrl(), ShortUrlMeta::fromRawData($meta), $domainResolver);
|
||||
$instance = new self($url->longUrl(), ShortUrlMeta::fromRawData($meta), $relationResolver);
|
||||
$instance->importSource = $url->source();
|
||||
$instance->importOriginalShortCode = $url->shortCode();
|
||||
$instance->dateCreated = Chronos::instance($url->createdAt());
|
||||
|
|
|
@ -5,10 +5,10 @@ declare(strict_types=1);
|
|||
namespace Shlinkio\Shlink\Core\Importer;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Shlinkio\Shlink\Core\Domain\Resolver\DomainResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortCodeHelperInterface;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Util\DoctrineBatchHelperInterface;
|
||||
use Shlinkio\Shlink\Core\Util\TagManagerTrait;
|
||||
use Shlinkio\Shlink\Importer\ImportedLinksProcessorInterface;
|
||||
|
@ -22,18 +22,18 @@ class ImportedLinksProcessor implements ImportedLinksProcessorInterface
|
|||
use TagManagerTrait;
|
||||
|
||||
private EntityManagerInterface $em;
|
||||
private DomainResolverInterface $domainResolver;
|
||||
private ShortUrlRelationResolverInterface $relationResolver;
|
||||
private ShortCodeHelperInterface $shortCodeHelper;
|
||||
private DoctrineBatchHelperInterface $batchHelper;
|
||||
|
||||
public function __construct(
|
||||
EntityManagerInterface $em,
|
||||
DomainResolverInterface $domainResolver,
|
||||
ShortUrlRelationResolverInterface $relationResolver,
|
||||
ShortCodeHelperInterface $shortCodeHelper,
|
||||
DoctrineBatchHelperInterface $batchHelper
|
||||
) {
|
||||
$this->em = $em;
|
||||
$this->domainResolver = $domainResolver;
|
||||
$this->relationResolver = $relationResolver;
|
||||
$this->shortCodeHelper = $shortCodeHelper;
|
||||
$this->batchHelper = $batchHelper;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class ImportedLinksProcessor implements ImportedLinksProcessorInterface
|
|||
continue;
|
||||
}
|
||||
|
||||
$shortUrl = ShortUrl::fromImport($url, $importShortCodes, $this->domainResolver);
|
||||
$shortUrl = ShortUrl::fromImport($url, $importShortCodes, $this->relationResolver);
|
||||
$shortUrl->setTags($this->tagNamesToEntities($this->em, $url->tags()));
|
||||
|
||||
if (! $this->handleShortCodeUniqueness($url, $shortUrl, $io, $importShortCodes)) {
|
||||
|
|
|
@ -24,6 +24,7 @@ final class ShortUrlMeta
|
|||
private ?string $domain = null;
|
||||
private int $shortCodeLength = 5;
|
||||
private ?bool $validateUrl = null;
|
||||
private ?string $apiKey = null;
|
||||
|
||||
// Enforce named constructors
|
||||
private function __construct()
|
||||
|
@ -66,6 +67,7 @@ final class ShortUrlMeta
|
|||
$inputFilter,
|
||||
ShortUrlMetaInputFilter::SHORT_CODE_LENGTH,
|
||||
) ?? DEFAULT_SHORT_CODES_LENGTH;
|
||||
$this->apiKey = $inputFilter->getValue(ShortUrlMetaInputFilter::API_KEY);
|
||||
}
|
||||
|
||||
public function getValidSince(): ?Chronos
|
||||
|
@ -132,4 +134,9 @@ final class ShortUrlMeta
|
|||
{
|
||||
return $this->validateUrl;
|
||||
}
|
||||
|
||||
public function getApiKey(): ?string
|
||||
{
|
||||
return $this->apiKey;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@ declare(strict_types=1);
|
|||
namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Shlinkio\Shlink\Core\Domain\Resolver\DomainResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortCodeHelperInterface;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Util\TagManagerTrait;
|
||||
use Shlinkio\Shlink\Core\Util\UrlValidatorInterface;
|
||||
use Throwable;
|
||||
|
@ -22,18 +22,18 @@ class UrlShortener implements UrlShortenerInterface
|
|||
|
||||
private EntityManagerInterface $em;
|
||||
private UrlValidatorInterface $urlValidator;
|
||||
private DomainResolverInterface $domainResolver;
|
||||
private ShortUrlRelationResolverInterface $relationResolver;
|
||||
private ShortCodeHelperInterface $shortCodeHelper;
|
||||
|
||||
public function __construct(
|
||||
UrlValidatorInterface $urlValidator,
|
||||
EntityManagerInterface $em,
|
||||
DomainResolverInterface $domainResolver,
|
||||
ShortUrlRelationResolverInterface $relationResolver,
|
||||
ShortCodeHelperInterface $shortCodeHelper
|
||||
) {
|
||||
$this->urlValidator = $urlValidator;
|
||||
$this->em = $em;
|
||||
$this->domainResolver = $domainResolver;
|
||||
$this->relationResolver = $relationResolver;
|
||||
$this->shortCodeHelper = $shortCodeHelper;
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ class UrlShortener implements UrlShortenerInterface
|
|||
$this->urlValidator->validateUrl($url, $meta->doValidateUrl());
|
||||
|
||||
return $this->em->transactional(function () use ($url, $tags, $meta) {
|
||||
$shortUrl = new ShortUrl($url, $meta, $this->domainResolver);
|
||||
$shortUrl = new ShortUrl($url, $meta, $this->relationResolver);
|
||||
$shortUrl->setTags($this->tagNamesToEntities($this->em, $tags));
|
||||
|
||||
$this->verifyShortCodeUniqueness($meta, $shortUrl);
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\ShortUrl\Resolver;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\Domain;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
class PersistenceShortUrlRelationResolver implements ShortUrlRelationResolverInterface
|
||||
{
|
||||
private EntityManagerInterface $em;
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
}
|
||||
|
||||
public function resolveDomain(?string $domain): ?Domain
|
||||
{
|
||||
if ($domain === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var Domain|null $existingDomain */
|
||||
$existingDomain = $this->em->getRepository(Domain::class)->findOneBy(['authority' => $domain]);
|
||||
return $existingDomain ?? new Domain($domain);
|
||||
}
|
||||
|
||||
public function resolveApiKey(?string $key): ?ApiKey
|
||||
{
|
||||
if ($key === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var ApiKey|null $existingApiKey */
|
||||
$existingApiKey = $this->em->getRepository(ApiKey::class)->findOneBy(['key' => $key]);
|
||||
return $existingApiKey;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\ShortUrl\Resolver;
|
||||
|
||||
use Shlinkio\Shlink\Core\Entity\Domain;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
interface ShortUrlRelationResolverInterface
|
||||
{
|
||||
public function resolveDomain(?string $domain): ?Domain;
|
||||
|
||||
public function resolveApiKey(?string $key): ?ApiKey;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\ShortUrl\Resolver;
|
||||
|
||||
use Shlinkio\Shlink\Core\Entity\Domain;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
class SimpleShortUrlRelationResolver implements ShortUrlRelationResolverInterface
|
||||
{
|
||||
public function resolveDomain(?string $domain): ?Domain
|
||||
{
|
||||
return $domain !== null ? new Domain($domain) : null;
|
||||
}
|
||||
|
||||
public function resolveApiKey(?string $key): ?ApiKey
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ class ShortUrlMetaInputFilter extends InputFilter
|
|||
public const SHORT_CODE_LENGTH = 'shortCodeLength';
|
||||
public const LONG_URL = 'longUrl';
|
||||
public const VALIDATE_URL = 'validateUrl';
|
||||
public const API_KEY = 'apiKey';
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
|
@ -70,6 +71,8 @@ class ShortUrlMetaInputFilter extends InputFilter
|
|||
$domain = $this->createInput(self::DOMAIN, false);
|
||||
$domain->getValidatorChain()->attach(new Validation\HostAndPortValidator());
|
||||
$this->add($domain);
|
||||
|
||||
$this->add($this->createInput(self::API_KEY, false));
|
||||
}
|
||||
|
||||
private function createPositiveNumberInput(string $name, int $min = 1): Input
|
||||
|
|
|
@ -10,11 +10,11 @@ use PHPUnit\Framework\TestCase;
|
|||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Core\Domain\Resolver\SimpleDomainResolver;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Importer\ImportedLinksProcessor;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortCodeHelperInterface;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Resolver\SimpleShortUrlRelationResolver;
|
||||
use Shlinkio\Shlink\Core\Util\DoctrineBatchHelperInterface;
|
||||
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
|
||||
use Symfony\Component\Console\Style\StyleInterface;
|
||||
|
@ -46,7 +46,7 @@ class ImportedLinksProcessorTest extends TestCase
|
|||
|
||||
$this->processor = new ImportedLinksProcessor(
|
||||
$this->em->reveal(),
|
||||
new SimpleDomainResolver(),
|
||||
new SimpleShortUrlRelationResolver(),
|
||||
$this->shortCodeHelper->reveal(),
|
||||
$batchHelper->reveal(),
|
||||
);
|
||||
|
|
|
@ -12,7 +12,6 @@ use PHPUnit\Framework\TestCase;
|
|||
use Prophecy\Argument;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Shlinkio\Shlink\Core\Domain\Resolver\SimpleDomainResolver;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Tag;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
|
@ -20,6 +19,7 @@ use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
|||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortCodeHelperInterface;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||
use Shlinkio\Shlink\Core\ShortUrl\Resolver\SimpleShortUrlRelationResolver;
|
||||
use Shlinkio\Shlink\Core\Util\UrlValidatorInterface;
|
||||
|
||||
class UrlShortenerTest extends TestCase
|
||||
|
@ -63,7 +63,7 @@ class UrlShortenerTest extends TestCase
|
|||
$this->urlShortener = new UrlShortener(
|
||||
$this->urlValidator->reveal(),
|
||||
$this->em->reveal(),
|
||||
new SimpleDomainResolver(),
|
||||
new SimpleShortUrlRelationResolver(),
|
||||
$this->shortCodeHelper->reveal(),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue