Ensured delete/rename tags cannot be done with non-admin API keys

This commit is contained in:
Alejandro Celaya
2021-01-06 17:31:49 +01:00
parent b5710f87e2
commit a8b68f07b5
9 changed files with 177 additions and 29 deletions

View File

@@ -9,6 +9,7 @@ use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Core\Tag\TagServiceInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class DeleteTagsAction extends AbstractRestAction
{
@@ -26,8 +27,9 @@ class DeleteTagsAction extends AbstractRestAction
{
$query = $request->getQueryParams();
$tags = $query['tags'] ?? [];
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$this->tagService->deleteTags($tags);
$this->tagService->deleteTags($tags, $apiKey);
return new EmptyResponse();
}
}

View File

@@ -10,6 +10,7 @@ use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Core\Tag\Model\TagRenaming;
use Shlinkio\Shlink\Core\Tag\TagServiceInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class UpdateTagAction extends AbstractRestAction
{
@@ -23,17 +24,12 @@ class UpdateTagAction extends AbstractRestAction
$this->tagService = $tagService;
}
/**
* Process an incoming server request and return a response, optionally delegating
* to the next middleware component to create the response.
*
*
* @throws \InvalidArgumentException
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
$body = $request->getParsedBody();
$this->tagService->renameTag(TagRenaming::fromArray($body));
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$this->tagService->renameTag(TagRenaming::fromArray($body), $apiKey);
return new EmptyResponse();
}
}

View File

@@ -6,10 +6,12 @@ namespace ShlinkioTest\Shlink\Rest\Action\Tag;
use Laminas\Diactoros\ServerRequest;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Core\Tag\TagServiceInterface;
use Shlinkio\Shlink\Rest\Action\Tag\DeleteTagsAction;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
class DeleteTagsActionTest extends TestCase
{
@@ -30,8 +32,10 @@ class DeleteTagsActionTest extends TestCase
*/
public function processDelegatesIntoService(?array $tags): void
{
$request = (new ServerRequest())->withQueryParams(['tags' => $tags]);
$deleteTags = $this->tagService->deleteTags($tags ?: []);
$request = (new ServerRequest())
->withQueryParams(['tags' => $tags])
->withAttribute(ApiKey::class, new ApiKey());
$deleteTags = $this->tagService->deleteTags($tags ?: [], Argument::type(ApiKey::class));
$response = $this->action->handle($request);

View File

@@ -4,15 +4,18 @@ declare(strict_types=1);
namespace ShlinkioTest\Shlink\Rest\Action\Tag;
use Laminas\Diactoros\ServerRequest;
use Laminas\Diactoros\ServerRequestFactory;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Core\Entity\Tag;
use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\Tag\Model\TagRenaming;
use Shlinkio\Shlink\Core\Tag\TagServiceInterface;
use Shlinkio\Shlink\Rest\Action\Tag\UpdateTagAction;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
class UpdateTagActionTest extends TestCase
{
@@ -33,7 +36,7 @@ class UpdateTagActionTest extends TestCase
*/
public function whenInvalidParamsAreProvidedAnErrorIsReturned(array $bodyParams): void
{
$request = (new ServerRequest())->withParsedBody($bodyParams);
$request = $this->requestWithApiKey()->withParsedBody($bodyParams);
$this->expectException(ValidationException::class);
@@ -50,15 +53,23 @@ class UpdateTagActionTest extends TestCase
/** @test */
public function correctInvocationRenamesTag(): void
{
$request = (new ServerRequest())->withParsedBody([
$request = $this->requestWithApiKey()->withParsedBody([
'oldName' => 'foo',
'newName' => 'bar',
]);
$rename = $this->tagService->renameTag(TagRenaming::fromNames('foo', 'bar'))->willReturn(new Tag('bar'));
$rename = $this->tagService->renameTag(
TagRenaming::fromNames('foo', 'bar'),
Argument::type(ApiKey::class),
)->willReturn(new Tag('bar'));
$resp = $this->action->handle($request);
self::assertEquals(204, $resp->getStatusCode());
$rename->shouldHaveBeenCalled();
}
private function requestWithApiKey(): ServerRequestInterface
{
return ServerRequestFactory::fromGlobals()->withAttribute(ApiKey::class, new ApiKey());
}
}