mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-26 02:40:41 -06:00
Applied API role specs to single short URL resolution
This commit is contained in:
parent
940383646b
commit
dc08286a72
@ -90,10 +90,10 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
|
||||
}
|
||||
|
||||
private function createListQueryBuilder(
|
||||
?string $searchTerm = null,
|
||||
array $tags = [],
|
||||
?DateRange $dateRange = null,
|
||||
?Specification $spec = null
|
||||
?string $searchTerm,
|
||||
array $tags,
|
||||
?DateRange $dateRange,
|
||||
?Specification $spec
|
||||
): QueryBuilder {
|
||||
$qb = $this->getEntityManager()->createQueryBuilder();
|
||||
$qb->from(ShortUrl::class, 's')
|
||||
@ -171,9 +171,9 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
|
||||
return $query->getOneOrNullResult();
|
||||
}
|
||||
|
||||
public function findOne(string $shortCode, ?string $domain = null): ?ShortUrl
|
||||
public function findOne(string $shortCode, ?string $domain = null, ?Specification $spec = null): ?ShortUrl
|
||||
{
|
||||
$qb = $this->createFindOneQueryBuilder($shortCode, $domain);
|
||||
$qb = $this->createFindOneQueryBuilder($shortCode, $domain, $spec);
|
||||
$qb->select('s');
|
||||
|
||||
return $qb->getQuery()->getOneOrNullResult();
|
||||
@ -181,13 +181,13 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
|
||||
|
||||
public function shortCodeIsInUse(string $slug, ?string $domain = null): bool
|
||||
{
|
||||
$qb = $this->createFindOneQueryBuilder($slug, $domain);
|
||||
$qb = $this->createFindOneQueryBuilder($slug, $domain, null);
|
||||
$qb->select('COUNT(DISTINCT s.id)');
|
||||
|
||||
return ((int) $qb->getQuery()->getSingleScalarResult()) > 0;
|
||||
}
|
||||
|
||||
private function createFindOneQueryBuilder(string $slug, ?string $domain = null): QueryBuilder
|
||||
private function createFindOneQueryBuilder(string $slug, ?string $domain, ?Specification $spec): QueryBuilder
|
||||
{
|
||||
$qb = $this->getEntityManager()->createQueryBuilder();
|
||||
$qb->from(ShortUrl::class, 's')
|
||||
@ -198,6 +198,10 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
|
||||
|
||||
$this->whereDomainIs($qb, $domain);
|
||||
|
||||
if ($spec !== null) {
|
||||
$this->applySpecification($qb, $spec, 's');
|
||||
}
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ interface ShortUrlRepositoryInterface extends ObjectRepository, EntitySpecificat
|
||||
|
||||
public function findOneWithDomainFallback(string $shortCode, ?string $domain = null): ?ShortUrl;
|
||||
|
||||
public function findOne(string $shortCode, ?string $domain = null): ?ShortUrl;
|
||||
public function findOne(string $shortCode, ?string $domain = null, ?Specification $spec = null): ?ShortUrl;
|
||||
|
||||
public function shortCodeIsInUse(string $slug, ?string $domain): bool;
|
||||
|
||||
|
@ -9,6 +9,7 @@ use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
class ShortUrlResolver implements ShortUrlResolverInterface
|
||||
{
|
||||
@ -22,11 +23,15 @@ class ShortUrlResolver implements ShortUrlResolverInterface
|
||||
/**
|
||||
* @throws ShortUrlNotFoundException
|
||||
*/
|
||||
public function resolveShortUrl(ShortUrlIdentifier $identifier): ShortUrl
|
||||
public function resolveShortUrl(ShortUrlIdentifier $identifier, ?ApiKey $apiKey = null): ShortUrl
|
||||
{
|
||||
/** @var ShortUrlRepository $shortUrlRepo */
|
||||
$shortUrlRepo = $this->em->getRepository(ShortUrl::class);
|
||||
$shortUrl = $shortUrlRepo->findOne($identifier->shortCode(), $identifier->domain());
|
||||
$shortUrl = $shortUrlRepo->findOne(
|
||||
$identifier->shortCode(),
|
||||
$identifier->domain(),
|
||||
$apiKey !== null ? $apiKey->spec() : null,
|
||||
);
|
||||
if ($shortUrl === null) {
|
||||
throw ShortUrlNotFoundException::fromNotFound($identifier);
|
||||
}
|
||||
|
@ -7,13 +7,14 @@ namespace Shlinkio\Shlink\Core\Service\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
interface ShortUrlResolverInterface
|
||||
{
|
||||
/**
|
||||
* @throws ShortUrlNotFoundException
|
||||
*/
|
||||
public function resolveShortUrl(ShortUrlIdentifier $identifier): ShortUrl;
|
||||
public function resolveShortUrl(ShortUrlIdentifier $identifier, ?ApiKey $apiKey = null): ShortUrl;
|
||||
|
||||
/**
|
||||
* @throws ShortUrlNotFoundException
|
||||
|
@ -42,7 +42,7 @@ class ShortUrlResolverTest extends TestCase
|
||||
$shortCode = $shortUrl->getShortCode();
|
||||
|
||||
$repo = $this->prophesize(ShortUrlRepositoryInterface::class);
|
||||
$findOne = $repo->findOne($shortCode, null)->willReturn($shortUrl);
|
||||
$findOne = $repo->findOne($shortCode, null, null)->willReturn($shortUrl);
|
||||
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
|
||||
$result = $this->urlResolver->resolveShortUrl(new ShortUrlIdentifier($shortCode));
|
||||
@ -58,7 +58,7 @@ class ShortUrlResolverTest extends TestCase
|
||||
$shortCode = 'abc123';
|
||||
|
||||
$repo = $this->prophesize(ShortUrlRepositoryInterface::class);
|
||||
$findOne = $repo->findOne($shortCode, null)->willReturn(null);
|
||||
$findOne = $repo->findOne($shortCode, null, null)->willReturn(null);
|
||||
$getRepo = $this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
|
||||
|
||||
$this->expectException(ShortUrlNotFoundException::class);
|
||||
|
@ -11,6 +11,7 @@ use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
|
||||
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
|
||||
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
|
||||
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
|
||||
|
||||
class ResolveShortUrlAction extends AbstractRestAction
|
||||
{
|
||||
@ -29,7 +30,10 @@ class ResolveShortUrlAction extends AbstractRestAction
|
||||
public function handle(Request $request): Response
|
||||
{
|
||||
$transformer = new ShortUrlDataTransformer($this->domainConfig);
|
||||
$url = $this->urlResolver->resolveShortUrl(ShortUrlIdentifier::fromApiRequest($request));
|
||||
$url = $this->urlResolver->resolveShortUrl(
|
||||
ShortUrlIdentifier::fromApiRequest($request),
|
||||
AuthenticationMiddleware::apiKeyFromRequest($request),
|
||||
);
|
||||
|
||||
return new JsonResponse($transformer->transform($url));
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
|
||||
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
|
||||
use Shlinkio\Shlink\Rest\Action\ShortUrl\ResolveShortUrlAction;
|
||||
use Shlinkio\Shlink\Rest\Entity\ApiKey;
|
||||
|
||||
use function strpos;
|
||||
|
||||
@ -32,12 +33,14 @@ class ResolveShortUrlActionTest extends TestCase
|
||||
public function correctShortCodeReturnsSuccess(): void
|
||||
{
|
||||
$shortCode = 'abc123';
|
||||
$this->urlResolver->resolveShortUrl(new ShortUrlIdentifier($shortCode))->willReturn(
|
||||
$apiKey = new ApiKey();
|
||||
$this->urlResolver->resolveShortUrl(new ShortUrlIdentifier($shortCode), $apiKey)->willReturn(
|
||||
new ShortUrl('http://domain.com/foo/bar'),
|
||||
)->shouldBeCalledOnce();
|
||||
|
||||
$request = (new ServerRequest())->withAttribute('shortCode', $shortCode);
|
||||
$request = (new ServerRequest())->withAttribute('shortCode', $shortCode)->withAttribute(ApiKey::class, $apiKey);
|
||||
$response = $this->action->handle($request);
|
||||
|
||||
self::assertEquals(200, $response->getStatusCode());
|
||||
self::assertTrue(strpos($response->getBody()->getContents(), 'http://domain.com/foo/bar') > 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user