Ensured API key is tracked when creating short URLs from the REST API

This commit is contained in:
Alejandro Celaya 2020-11-07 10:23:08 +01:00
parent 7c9f572eb1
commit 27bc8d4823
4 changed files with 31 additions and 11 deletions

View file

@ -8,6 +8,8 @@ use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\Model\CreateShortUrlData;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
use Shlinkio\Shlink\Rest\Authentication\Plugin\ApiKeyHeaderPlugin;
class CreateShortUrlAction extends AbstractCreateShortUrlAction
{
@ -19,14 +21,16 @@ class CreateShortUrlAction extends AbstractCreateShortUrlAction
*/
protected function buildShortUrlData(Request $request): CreateShortUrlData
{
$postData = (array) $request->getParsedBody();
if (! isset($postData['longUrl'])) {
$payload = (array) $request->getParsedBody();
if (! isset($payload['longUrl'])) {
throw ValidationException::fromArray([
'longUrl' => 'A URL was not provided',
]);
}
$meta = ShortUrlMeta::fromRawData($postData);
return new CreateShortUrlData($postData['longUrl'], (array) ($postData['tags'] ?? []), $meta);
$payload[ShortUrlMetaInputFilter::API_KEY] = $request->getHeaderLine(ApiKeyHeaderPlugin::HEADER_NAME);
$meta = ShortUrlMeta::fromRawData($payload);
return new CreateShortUrlData($payload['longUrl'], (array) ($payload['tags'] ?? []), $meta);
}
}

View file

@ -7,7 +7,9 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\Model\CreateShortUrlData;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface;
class SingleStepCreateShortUrlAction extends AbstractCreateShortUrlAction
@ -32,19 +34,23 @@ class SingleStepCreateShortUrlAction extends AbstractCreateShortUrlAction
protected function buildShortUrlData(Request $request): CreateShortUrlData
{
$query = $request->getQueryParams();
$apiKey = $query['apiKey'] ?? '';
$longUrl = $query['longUrl'] ?? null;
if (! $this->apiKeyService->check($query['apiKey'] ?? '')) {
if (! $this->apiKeyService->check($apiKey)) {
throw ValidationException::fromArray([
'apiKey' => 'No API key was provided or it is not valid',
]);
}
if (! isset($query['longUrl'])) {
if ($longUrl === null) {
throw ValidationException::fromArray([
'longUrl' => 'A URL was not provided',
]);
}
return new CreateShortUrlData($query['longUrl']);
return new CreateShortUrlData($longUrl, [], ShortUrlMeta::fromRawData([
ShortUrlMetaInputFilter::API_KEY => $apiKey,
]));
}
}

View file

@ -48,7 +48,7 @@ class CreateShortUrlActionTest extends TestCase
* @test
* @dataProvider provideRequestBodies
*/
public function properShortcodeConversionReturnsData(array $body, ShortUrlMeta $expectedMeta): void
public function properShortcodeConversionReturnsData(array $body, ShortUrlMeta $expectedMeta, ?string $apiKey): void
{
$shortUrl = new ShortUrl('');
$shorten = $this->urlShortener->shorten(
@ -58,6 +58,10 @@ class CreateShortUrlActionTest extends TestCase
)->willReturn($shortUrl);
$request = ServerRequestFactory::fromGlobals()->withParsedBody($body);
if ($apiKey !== null) {
$request = $request->withHeader('X-Api-Key', $apiKey);
}
$response = $this->action->handle($request);
self::assertEquals(200, $response->getStatusCode());
@ -77,8 +81,14 @@ class CreateShortUrlActionTest extends TestCase
'domain' => 'my-domain.com',
];
yield [['longUrl' => 'http://www.domain.com/foo/bar'], ShortUrlMeta::createEmpty()];
yield [$fullMeta, ShortUrlMeta::fromRawData($fullMeta)];
yield 'no data' => [['longUrl' => 'http://www.domain.com/foo/bar'], ShortUrlMeta::createEmpty(), null];
yield 'all data' => [$fullMeta, ShortUrlMeta::fromRawData($fullMeta), null];
yield 'all data and API key' => (static function (array $meta): array {
$apiKey = 'abc123';
$meta['apiKey'] = $apiKey;
return [$meta, ShortUrlMeta::fromRawData($meta), $apiKey];
})($fullMeta);
}
/**

View file

@ -78,7 +78,7 @@ class SingleStepCreateShortUrlActionTest extends TestCase
return $argument;
}),
[],
ShortUrlMeta::createEmpty(),
ShortUrlMeta::fromRawData(['apiKey' => 'abc123']),
)->willReturn(new ShortUrl(''));
$resp = $this->action->handle($request);