From 434b56fa8cdf313300062ae7f1414babd8a53b2b Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 31 Dec 2019 15:38:37 +0100 Subject: [PATCH] Removed several deprecated components --- config/autoload/app_options.global.php | 3 - config/autoload/error-handler.global.php | 4 - .../autoload/middleware-pipeline.global.php | 2 - docker/README.md | 6 +- docker/config/shlink_in_docker.local.php | 46 +-------- module/CLI/config/cli.config.php | 4 - module/CLI/config/dependencies.config.php | 5 - .../Command/Config/GenerateCharsetCommand.php | 40 -------- .../Command/Config/GenerateSecretCommand.php | 39 -------- .../CLI/src/Command/Visit/UpdateDbCommand.php | 91 ------------------ .../Config/GenerateCharsetCommandTest.php | 47 ---------- .../Command/Visit/UpdateDbCommandTest.php | 75 --------------- module/Core/config/app_options.config.php | 9 -- .../src/Config/SimplifiedConfigParser.php | 1 - module/Core/src/Entity/Visit.php | 3 - .../EventDispatcher/NotifyVisitToWebHooks.php | 2 +- module/Core/src/Options/AppOptions.php | 19 ---- .../Transformer/ShortUrlDataTransformer.php | 10 +- .../Config/SimplifiedConfigParserTest.php | 28 +----- module/Core/test/Entity/VisitTest.php | 3 - module/Rest/config/auth.config.php | 1 - module/Rest/config/dependencies.config.php | 8 -- module/Rest/config/routes.config.php | 1 - module/Rest/src/Action/AuthenticateAction.php | 64 ------------- module/Rest/src/Authentication/JWTService.php | 4 +- ...ardsCompatibleProblemDetailsMiddleware.php | 63 ------------- .../ShortUrl/ShortCodePathMiddleware.php | 34 ------- .../Action/CreateShortUrlActionTest.php | 6 +- .../Action/DeleteShortUrlActionTest.php | 4 - .../Action/EditShortUrlActionTest.php | 4 - .../Action/EditShortUrlTagsActionTest.php | 4 - .../test-api/Action/GetVisitsActionTest.php | 2 - .../test-api/Action/ListShortUrlsTest.php | 9 -- .../Action/ResolveShortUrlActionTest.php | 2 - .../test-api/Action/UpdateTagActionTest.php | 6 -- .../Middleware/AuthenticationTest.php | 12 +-- .../test/Action/AuthenticateActionTest.php | 72 -------------- .../test/Authentication/JWTServiceTest.php | 86 ----------------- .../AuthenticationMiddlewareTest.php | 6 +- ...CompatibleProblemDetailsMiddlewareTest.php | 94 ------------------- .../ShortUrl/ShortCodePathMiddlewareTest.php | 49 ---------- 41 files changed, 16 insertions(+), 952 deletions(-) delete mode 100644 module/CLI/src/Command/Config/GenerateCharsetCommand.php delete mode 100644 module/CLI/src/Command/Config/GenerateSecretCommand.php delete mode 100644 module/CLI/src/Command/Visit/UpdateDbCommand.php delete mode 100644 module/CLI/test/Command/Config/GenerateCharsetCommandTest.php delete mode 100644 module/CLI/test/Command/Visit/UpdateDbCommandTest.php delete mode 100644 module/Core/config/app_options.config.php delete mode 100644 module/Rest/src/Action/AuthenticateAction.php delete mode 100644 module/Rest/src/Middleware/BackwardsCompatibleProblemDetailsMiddleware.php delete mode 100644 module/Rest/src/Middleware/ShortUrl/ShortCodePathMiddleware.php delete mode 100644 module/Rest/test/Action/AuthenticateActionTest.php delete mode 100644 module/Rest/test/Authentication/JWTServiceTest.php delete mode 100644 module/Rest/test/Middleware/BackwardsCompatibleProblemDetailsMiddlewareTest.php delete mode 100644 module/Rest/test/Middleware/ShortUrl/ShortCodePathMiddlewareTest.php diff --git a/config/autoload/app_options.global.php b/config/autoload/app_options.global.php index e10f1b20..f64f9cff 100644 --- a/config/autoload/app_options.global.php +++ b/config/autoload/app_options.global.php @@ -2,14 +2,11 @@ declare(strict_types=1); -use function Shlinkio\Shlink\Common\env; - return [ 'app_options' => [ 'name' => 'Shlink', 'version' => '%SHLINK_VERSION%', - 'secret_key' => env('SECRET_KEY', ''), 'disable_track_param' => null, ], diff --git a/config/autoload/error-handler.global.php b/config/autoload/error-handler.global.php index 7f5c91c9..69a54f03 100644 --- a/config/autoload/error-handler.global.php +++ b/config/autoload/error-handler.global.php @@ -15,10 +15,6 @@ return [ ], ], - 'backwards_compatible_problem_details' => [ - 'json_flags' => JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION, - ], - 'error_handler' => [ 'listeners' => [Logger\ErrorLogger::class], ], diff --git a/config/autoload/middleware-pipeline.global.php b/config/autoload/middleware-pipeline.global.php index 35a9a16b..279417bb 100644 --- a/config/autoload/middleware-pipeline.global.php +++ b/config/autoload/middleware-pipeline.global.php @@ -21,7 +21,6 @@ return [ 'path' => '/rest', 'middleware' => [ Rest\Middleware\CrossDomainMiddleware::class, - Rest\Middleware\BackwardsCompatibleProblemDetailsMiddleware::class, ProblemDetails\ProblemDetailsMiddleware::class, ], ], @@ -35,7 +34,6 @@ return [ 'path' => '/rest', 'middleware' => [ Rest\Middleware\PathVersionMiddleware::class, - Rest\Middleware\ShortUrl\ShortCodePathMiddleware::class, ], ], diff --git a/docker/README.md b/docker/README.md index b600c268..584e4e99 100644 --- a/docker/README.md +++ b/docker/README.md @@ -119,7 +119,6 @@ This is the complete list of supported env vars: In the future, these redis servers could be used for other caching operations performed by shlink. -* `NOT_FOUND_REDIRECT_TO`: **Deprecated since v1.20 in favor of `INVALID_SHORT_URL_REDIRECT_TO`** If a URL is provided here, when a user tries to access an invalid short URL, he/she will be redirected to this value. If this env var is not provided, the user will see a generic `404 - not found` page. * `SHORTCODE_CHARS`: **Ignored when using Shlink 1.20 or newer**. A charset to use when building short codes. Only needed when using more than one shlink instance ([Multi instance considerations](#multi-instance-considerations)). An example using all env vars could look like this: @@ -186,15 +185,12 @@ The whole configuration should have this format, but it can be split into multip "password": "123abc", "host": "something.rds.amazonaws.com", "port": "3306" - }, - "not_found_redirect_to": "https://my-landing-page.com" + } } ``` > This is internally parsed to how shlink expects the config. If you are using a version previous to 1.17.0, this parser is not present and you need to provide a config structure like the one [documented previously](https://github.com/shlinkio/shlink-docker-image/tree/v1.16.3#provide-config-via-volumes). -> The `not_found_redirect_to` option has been deprecated in v1.20. Use `invalid_short_url_redirect_to` instead (however, it will still work for backwards compatibility). - Once created just run shlink with the volume: ```bash diff --git a/docker/config/shlink_in_docker.local.php b/docker/config/shlink_in_docker.local.php index 6d3367ac..5b4db1e1 100644 --- a/docker/config/shlink_in_docker.local.php +++ b/docker/config/shlink_in_docker.local.php @@ -8,19 +8,10 @@ use Monolog\Handler\StreamHandler; use Monolog\Logger; use function explode; -use function file_exists; -use function file_get_contents; -use function file_put_contents; use function Functional\contains; -use function implode; use function Shlinkio\Shlink\Common\env; -use function sprintf; -use function str_shuffle; -use function substr; -use function sys_get_temp_dir; $helper = new class { - private const BASE62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; private const DB_DRIVERS_MAP = [ 'mysql' => 'pdo_mysql', 'maria' => 'pdo_mysql', @@ -32,40 +23,6 @@ $helper = new class { 'postgres' => '5432', ]; - /** @var string */ - private $secretKey; - - public function __construct() - { - [, $this->secretKey] = $this->initShlinkSecretKey(); - } - - private function initShlinkSecretKey(): array - { - $keysFile = sprintf('%s/shlink.keys', sys_get_temp_dir()); - if (file_exists($keysFile)) { - return explode(',', file_get_contents($keysFile)); - } - - $keys = [ - '', // This was the SHORTCODE_CHARS. Kept as empty string for BC - env('SECRET_KEY', $this->generateSecretKey()), // Deprecated - ]; - - file_put_contents($keysFile, implode(',', $keys)); - return $keys; - } - - private function generateSecretKey(): string - { - return substr(str_shuffle(self::BASE62), 0, 32); - } - - public function getSecretKey(): string - { - return $this->secretKey; - } - public function getDbConfig(): array { $driver = env('DB_DRIVER'); @@ -94,7 +51,7 @@ $helper = new class { public function getNotFoundRedirectsConfig(): array { return [ - 'invalid_short_url' => env('INVALID_SHORT_URL_REDIRECT_TO', env('NOT_FOUND_REDIRECT_TO')), + 'invalid_short_url' => env('INVALID_SHORT_URL_REDIRECT_TO'), 'regular_404' => env('REGULAR_404_REDIRECT_TO'), 'base_url' => env('BASE_URL_REDIRECT_TO'), ]; @@ -112,7 +69,6 @@ return [ 'config_cache_enabled' => false, 'app_options' => [ - 'secret_key' => $helper->getSecretKey(), 'disable_track_param' => env('DISABLE_TRACK_PARAM'), ], diff --git a/module/CLI/config/cli.config.php b/module/CLI/config/cli.config.php index 255b215f..fa9efc69 100644 --- a/module/CLI/config/cli.config.php +++ b/module/CLI/config/cli.config.php @@ -15,10 +15,6 @@ return [ Command\ShortUrl\DeleteShortUrlCommand::NAME => Command\ShortUrl\DeleteShortUrlCommand::class, Command\Visit\LocateVisitsCommand::NAME => Command\Visit\LocateVisitsCommand::class, - Command\Visit\UpdateDbCommand::NAME => Command\Visit\UpdateDbCommand::class, - - Command\Config\GenerateCharsetCommand::NAME => Command\Config\GenerateCharsetCommand::class, - Command\Config\GenerateSecretCommand::NAME => Command\Config\GenerateSecretCommand::class, Command\Api\GenerateKeyCommand::NAME => Command\Api\GenerateKeyCommand::class, Command\Api\DisableKeyCommand::NAME => Command\Api\DisableKeyCommand::class, diff --git a/module/CLI/config/dependencies.config.php b/module/CLI/config/dependencies.config.php index feb1eeae..c7eea7b2 100644 --- a/module/CLI/config/dependencies.config.php +++ b/module/CLI/config/dependencies.config.php @@ -36,10 +36,6 @@ return [ Command\ShortUrl\DeleteShortUrlCommand::class => ConfigAbstractFactory::class, Command\Visit\LocateVisitsCommand::class => ConfigAbstractFactory::class, - Command\Visit\UpdateDbCommand::class => ConfigAbstractFactory::class, - - Command\Config\GenerateCharsetCommand::class => InvokableFactory::class, - Command\Config\GenerateSecretCommand::class => InvokableFactory::class, Command\Api\GenerateKeyCommand::class => ConfigAbstractFactory::class, Command\Api\DisableKeyCommand::class => ConfigAbstractFactory::class, @@ -70,7 +66,6 @@ return [ LockFactory::class, GeolocationDbUpdater::class, ], - Command\Visit\UpdateDbCommand::class => [DbUpdater::class], Command\Api\GenerateKeyCommand::class => [ApiKeyService::class], Command\Api\DisableKeyCommand::class => [ApiKeyService::class], diff --git a/module/CLI/src/Command/Config/GenerateCharsetCommand.php b/module/CLI/src/Command/Config/GenerateCharsetCommand.php deleted file mode 100644 index a285c7f0..00000000 --- a/module/CLI/src/Command/Config/GenerateCharsetCommand.php +++ /dev/null @@ -1,40 +0,0 @@ -setName(self::NAME) - ->setDescription(sprintf( - '[DEPRECATED] Generates a character set sample just by shuffling the default one, "%s". ' - . 'Then it can be set in the SHORTCODE_CHARS environment variable', - self::DEFAULT_CHARS - )) - ->setHelp('This command is deprecated. Better leave shlink generate the charset.'); - } - - protected function execute(InputInterface $input, OutputInterface $output): ?int - { - $charSet = str_shuffle(self::DEFAULT_CHARS); - (new SymfonyStyle($input, $output))->success(sprintf('Character set: "%s"', $charSet)); - return ExitCodes::EXIT_SUCCESS; - } -} diff --git a/module/CLI/src/Command/Config/GenerateSecretCommand.php b/module/CLI/src/Command/Config/GenerateSecretCommand.php deleted file mode 100644 index c0d60eea..00000000 --- a/module/CLI/src/Command/Config/GenerateSecretCommand.php +++ /dev/null @@ -1,39 +0,0 @@ -setName(self::NAME) - ->setDescription('[DEPRECATED] Generates a random secret string that can be used for JWT token encryption') - ->setHelp( - 'This command is deprecated. Better leave shlink generate the secret key.' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output): ?int - { - $secret = $this->generateRandomString(32); - (new SymfonyStyle($input, $output))->success(sprintf('Secret key: "%s"', $secret)); - return ExitCodes::EXIT_SUCCESS; - } -} diff --git a/module/CLI/src/Command/Visit/UpdateDbCommand.php b/module/CLI/src/Command/Visit/UpdateDbCommand.php deleted file mode 100644 index 367423fd..00000000 --- a/module/CLI/src/Command/Visit/UpdateDbCommand.php +++ /dev/null @@ -1,91 +0,0 @@ -geoLiteDbUpdater = $geoLiteDbUpdater; - } - - protected function configure(): void - { - $this - ->setName(self::NAME) - ->setDescription('[DEPRECATED] Updates the GeoLite2 database file used to geolocate IP addresses') - ->setHelp( - 'The GeoLite2 database is updated first Tuesday every month, so this command should be ideally run ' - . 'every first Wednesday' - ) - ->addOption( - 'ignoreErrors', - 'i', - InputOption::VALUE_NONE, - 'Makes the command success even iof the update fails.' - ); - } - - protected function execute(InputInterface $input, OutputInterface $output): ?int - { - $io = new SymfonyStyle($input, $output); - $progressBar = new ProgressBar($output); - $progressBar->start(); - - try { - $this->geoLiteDbUpdater->downloadFreshCopy(function (int $total, int $downloaded) use ($progressBar) { - $progressBar->setMaxSteps($total); - $progressBar->setProgress($downloaded); - }); - - $progressBar->finish(); - $io->newLine(); - - $io->success('GeoLite2 database properly updated'); - return ExitCodes::EXIT_SUCCESS; - } catch (RuntimeException $e) { - $progressBar->finish(); - $io->newLine(); - - return $this->handleError($e, $io, $input); - } - } - - private function handleError(RuntimeException $e, SymfonyStyle $io, InputInterface $input): int - { - $ignoreErrors = $input->getOption('ignoreErrors'); - $baseErrorMsg = 'An error occurred while updating GeoLite2 database'; - - if ($ignoreErrors) { - $io->warning(sprintf('%s, but it was ignored', $baseErrorMsg)); - return ExitCodes::EXIT_SUCCESS; - } - - $io->error($baseErrorMsg); - if ($io->isVerbose()) { - $this->getApplication()->renderThrowable($e, $io); - } - return ExitCodes::EXIT_FAILURE; - } -} diff --git a/module/CLI/test/Command/Config/GenerateCharsetCommandTest.php b/module/CLI/test/Command/Config/GenerateCharsetCommandTest.php deleted file mode 100644 index e5430e4a..00000000 --- a/module/CLI/test/Command/Config/GenerateCharsetCommandTest.php +++ /dev/null @@ -1,47 +0,0 @@ -add($command); - - $this->commandTester = new CommandTester($command); - } - - /** @test */ - public function charactersAreGeneratedFromDefault() - { - $prefix = 'Character set: '; - - $this->commandTester->execute([]); - $output = $this->commandTester->getDisplay(); - - // Both default character set and the new one should have the same length - $this->assertStringContainsString($prefix, $output); - } - - protected function orderStringLetters($string) - { - $letters = str_split($string); - sort($letters); - return implode('', $letters); - } -} diff --git a/module/CLI/test/Command/Visit/UpdateDbCommandTest.php b/module/CLI/test/Command/Visit/UpdateDbCommandTest.php deleted file mode 100644 index 2d6fc478..00000000 --- a/module/CLI/test/Command/Visit/UpdateDbCommandTest.php +++ /dev/null @@ -1,75 +0,0 @@ -dbUpdater = $this->prophesize(DbUpdaterInterface::class); - - $command = new UpdateDbCommand($this->dbUpdater->reveal()); - $app = new Application(); - $app->add($command); - - $this->commandTester = new CommandTester($command); - } - - /** @test */ - public function successMessageIsPrintedIfEverythingWorks(): void - { - $download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->will(function () { - }); - - $this->commandTester->execute([]); - $output = $this->commandTester->getDisplay(); - $exitCode = $this->commandTester->getStatusCode(); - - $this->assertStringContainsString('GeoLite2 database properly updated', $output); - $this->assertEquals(ExitCodes::EXIT_SUCCESS, $exitCode); - $download->shouldHaveBeenCalledOnce(); - } - - /** @test */ - public function errorMessageIsPrintedIfAnExceptionIsThrown(): void - { - $download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->willThrow(RuntimeException::class); - - $this->commandTester->execute([]); - $output = $this->commandTester->getDisplay(); - $exitCode = $this->commandTester->getStatusCode(); - - $this->assertStringContainsString('An error occurred while updating GeoLite2 database', $output); - $this->assertEquals(ExitCodes::EXIT_FAILURE, $exitCode); - $download->shouldHaveBeenCalledOnce(); - } - - /** @test */ - public function warningMessageIsPrintedIfAnExceptionIsThrownAndErrorsAreIgnored(): void - { - $download = $this->dbUpdater->downloadFreshCopy(Argument::type('callable'))->willThrow(RuntimeException::class); - - $this->commandTester->execute(['--ignoreErrors' => true]); - $output = $this->commandTester->getDisplay(); - $exitCode = $this->commandTester->getStatusCode(); - - $this->assertStringContainsString('ignored', $output); - $this->assertEquals(ExitCodes::EXIT_SUCCESS, $exitCode); - $download->shouldHaveBeenCalledOnce(); - } -} diff --git a/module/Core/config/app_options.config.php b/module/Core/config/app_options.config.php deleted file mode 100644 index ccab5752..00000000 --- a/module/Core/config/app_options.config.php +++ /dev/null @@ -1,9 +0,0 @@ - [], - -]; diff --git a/module/Core/src/Config/SimplifiedConfigParser.php b/module/Core/src/Config/SimplifiedConfigParser.php index e9c2ae7b..19fe4fb4 100644 --- a/module/Core/src/Config/SimplifiedConfigParser.php +++ b/module/Core/src/Config/SimplifiedConfigParser.php @@ -22,7 +22,6 @@ class SimplifiedConfigParser 'short_domain_schema' => ['url_shortener', 'domain', 'schema'], 'short_domain_host' => ['url_shortener', 'domain', 'hostname'], 'validate_url' => ['url_shortener', 'validate_url'], - 'not_found_redirect_to' => ['not_found_redirects', 'invalid_short_url'], // Deprecated 'invalid_short_url_redirect_to' => ['not_found_redirects', 'invalid_short_url'], 'regular_404_redirect_to' => ['not_found_redirects', 'regular_404'], 'base_url_redirect_to' => ['not_found_redirects', 'base_path'], diff --git a/module/Core/src/Entity/Visit.php b/module/Core/src/Entity/Visit.php index c4ee97a2..38c17565 100644 --- a/module/Core/src/Entity/Visit.php +++ b/module/Core/src/Entity/Visit.php @@ -90,9 +90,6 @@ class Visit extends AbstractEntity implements JsonSerializable 'date' => $this->date->toAtomString(), 'userAgent' => $this->userAgent, 'visitLocation' => $this->visitLocation, - - // Deprecated - 'remoteAddr' => null, ]; } diff --git a/module/Core/src/EventDispatcher/NotifyVisitToWebHooks.php b/module/Core/src/EventDispatcher/NotifyVisitToWebHooks.php index 7f901d33..646f1757 100644 --- a/module/Core/src/EventDispatcher/NotifyVisitToWebHooks.php +++ b/module/Core/src/EventDispatcher/NotifyVisitToWebHooks.php @@ -78,7 +78,7 @@ class NotifyVisitToWebHooks 'User-Agent' => (string) $this->appOptions, ], RequestOptions::JSON => [ - 'shortUrl' => $this->transformer->transform($visit->getShortUrl(), false), + 'shortUrl' => $this->transformer->transform($visit->getShortUrl()), 'visit' => $visit->jsonSerialize(), ], ]; diff --git a/module/Core/src/Options/AppOptions.php b/module/Core/src/Options/AppOptions.php index 36b6d58b..06810a68 100644 --- a/module/Core/src/Options/AppOptions.php +++ b/module/Core/src/Options/AppOptions.php @@ -15,8 +15,6 @@ class AppOptions extends AbstractOptions private string $name = ''; private string $version = '1.0'; - /** @deprecated */ - private string $secretKey = ''; private ?string $disableTrackParam = null; public function getName(): string @@ -41,23 +39,6 @@ class AppOptions extends AbstractOptions return $this; } - /** - * @deprecated - */ - public function getSecretKey(): string - { - return $this->secretKey; - } - - /** - * @deprecated - */ - protected function setSecretKey(string $secretKey): self - { - $this->secretKey = $secretKey; - return $this; - } - /** * @return string|null */ diff --git a/module/Core/src/Transformer/ShortUrlDataTransformer.php b/module/Core/src/Transformer/ShortUrlDataTransformer.php index f734cf01..bb19f997 100644 --- a/module/Core/src/Transformer/ShortUrlDataTransformer.php +++ b/module/Core/src/Transformer/ShortUrlDataTransformer.php @@ -22,11 +22,11 @@ class ShortUrlDataTransformer implements DataTransformerInterface /** * @param ShortUrl $shortUrl */ - public function transform($shortUrl, bool $includeDeprecated = true): array + public function transform($shortUrl): array { $longUrl = $shortUrl->getLongUrl(); - $rawData = [ + return [ 'shortCode' => $shortUrl->getShortCode(), 'shortUrl' => $shortUrl->toString($this->domainConfig), 'longUrl' => $longUrl, @@ -35,12 +35,6 @@ class ShortUrlDataTransformer implements DataTransformerInterface 'tags' => invoke($shortUrl->getTags(), '__toString'), 'meta' => $this->buildMeta($shortUrl), ]; - - if ($includeDeprecated) { - $rawData['originalUrl'] = $longUrl; - } - - return $rawData; } private function buildMeta(ShortUrl $shortUrl): array diff --git a/module/Core/test/Config/SimplifiedConfigParserTest.php b/module/Core/test/Config/SimplifiedConfigParserTest.php index 76ba9b1b..d1b27302 100644 --- a/module/Core/test/Config/SimplifiedConfigParserTest.php +++ b/module/Core/test/Config/SimplifiedConfigParserTest.php @@ -11,7 +11,7 @@ use function array_merge; class SimplifiedConfigParserTest extends TestCase { - private $postProcessor; + private SimplifiedConfigParser $postProcessor; public function setUp(): void { @@ -40,7 +40,7 @@ class SimplifiedConfigParserTest extends TestCase 'short_domain_host' => 'doma.in', 'validate_url' => false, 'delete_short_url_threshold' => 50, - 'not_found_redirect_to' => 'foobar.com', + 'invalid_short_url_redirect_to' => 'foobar.com', 'redis_servers' => [ 'tcp://1.1.1.1:1111', 'tcp://1.2.2.2:2222', @@ -125,28 +125,4 @@ class SimplifiedConfigParserTest extends TestCase $this->assertEquals(array_merge($expected, $simplified), $result); } - - /** - * @test - * @dataProvider provideConfigWithDeprecates - */ - public function properlyMapsDeprecatedConfigs(array $config, string $expected): void - { - $result = ($this->postProcessor)($config); - $this->assertEquals($expected, $result['not_found_redirects']['invalid_short_url']); - } - - public function provideConfigWithDeprecates(): iterable - { - yield 'only deprecated config' => [['not_found_redirect_to' => 'old_value'], 'old_value']; - yield 'only new config' => [['invalid_short_url_redirect_to' => 'new_value'], 'new_value']; - yield 'both configs, new first' => [ - ['invalid_short_url_redirect_to' => 'new_value', 'not_found_redirect_to' => 'old_value'], - 'new_value', - ]; - yield 'both configs, deprecated first' => [ - ['not_found_redirect_to' => 'old_value', 'invalid_short_url_redirect_to' => 'new_value'], - 'new_value', - ]; - } } diff --git a/module/Core/test/Entity/VisitTest.php b/module/Core/test/Entity/VisitTest.php index ff2c4cec..9af71a09 100644 --- a/module/Core/test/Entity/VisitTest.php +++ b/module/Core/test/Entity/VisitTest.php @@ -25,9 +25,6 @@ class VisitTest extends TestCase 'date' => ($date ?? $visit->getDate())->toAtomString(), 'userAgent' => 'Chrome', 'visitLocation' => null, - - // Deprecated - 'remoteAddr' => null, ], $visit->jsonSerialize()); } diff --git a/module/Rest/config/auth.config.php b/module/Rest/config/auth.config.php index 9d0987e0..8cebff6e 100644 --- a/module/Rest/config/auth.config.php +++ b/module/Rest/config/auth.config.php @@ -10,7 +10,6 @@ return [ 'auth' => [ 'routes_whitelist' => [ - Action\AuthenticateAction::class, Action\HealthAction::class, Action\ShortUrl\SingleStepCreateShortUrlAction::class, ], diff --git a/module/Rest/config/dependencies.config.php b/module/Rest/config/dependencies.config.php index ace2fda7..70bb0556 100644 --- a/module/Rest/config/dependencies.config.php +++ b/module/Rest/config/dependencies.config.php @@ -20,7 +20,6 @@ return [ Authentication\JWTService::class => ConfigAbstractFactory::class, ApiKeyService::class => ConfigAbstractFactory::class, - Action\AuthenticateAction::class => ConfigAbstractFactory::class, Action\HealthAction::class => ConfigAbstractFactory::class, Action\ShortUrl\CreateShortUrlAction::class => ConfigAbstractFactory::class, Action\ShortUrl\SingleStepCreateShortUrlAction::class => ConfigAbstractFactory::class, @@ -39,9 +38,7 @@ return [ Middleware\BodyParserMiddleware::class => InvokableFactory::class, Middleware\CrossDomainMiddleware::class => InvokableFactory::class, Middleware\PathVersionMiddleware::class => InvokableFactory::class, - Middleware\BackwardsCompatibleProblemDetailsMiddleware::class => ConfigAbstractFactory::class, Middleware\ShortUrl\CreateShortUrlContentNegotiationMiddleware::class => InvokableFactory::class, - Middleware\ShortUrl\ShortCodePathMiddleware::class => InvokableFactory::class, ], ], @@ -49,7 +46,6 @@ return [ Authentication\JWTService::class => [AppOptions::class], ApiKeyService::class => ['em'], - Action\AuthenticateAction::class => [ApiKeyService::class, Authentication\JWTService::class, 'Logger_Shlink'], Action\HealthAction::class => [Connection::class, AppOptions::class, 'Logger_Shlink'], Action\ShortUrl\CreateShortUrlAction::class => [ Service\UrlShortener::class, @@ -76,10 +72,6 @@ return [ Action\Tag\DeleteTagsAction::class => [Service\Tag\TagService::class, LoggerInterface::class], Action\Tag\CreateTagsAction::class => [Service\Tag\TagService::class, LoggerInterface::class], Action\Tag\UpdateTagAction::class => [Service\Tag\TagService::class, LoggerInterface::class], - - Middleware\BackwardsCompatibleProblemDetailsMiddleware::class => [ - 'config.backwards_compatible_problem_details.json_flags', - ], ], ]; diff --git a/module/Rest/config/routes.config.php b/module/Rest/config/routes.config.php index 3583a091..d210f13b 100644 --- a/module/Rest/config/routes.config.php +++ b/module/Rest/config/routes.config.php @@ -7,7 +7,6 @@ namespace Shlinkio\Shlink\Rest; return [ 'routes' => [ - Action\AuthenticateAction::getRouteDef(), Action\HealthAction::getRouteDef(), // Short codes diff --git a/module/Rest/src/Action/AuthenticateAction.php b/module/Rest/src/Action/AuthenticateAction.php deleted file mode 100644 index b0919aae..00000000 --- a/module/Rest/src/Action/AuthenticateAction.php +++ /dev/null @@ -1,64 +0,0 @@ -apiKeyService = $apiKeyService; - $this->jwtService = $jwtService; - } - - /** - * @param Request $request - * @return Response - * @throws \InvalidArgumentException - */ - public function handle(Request $request): Response - { - $authData = $request->getParsedBody(); - if (! isset($authData['apiKey'])) { - return new JsonResponse([ - 'error' => 'INVALID_ARGUMENT', - 'message' => 'You have to provide a valid API key under the "apiKey" param name.', - ], self::STATUS_BAD_REQUEST); - } - - // Authenticate using provided API key - $apiKey = $this->apiKeyService->getByKey($authData['apiKey']); - if ($apiKey === null || ! $apiKey->isValid()) { - return new JsonResponse([ - 'error' => 'INVALID_API_KEY', - 'message' => 'Provided API key does not exist or is invalid.', - ], self::STATUS_UNAUTHORIZED); - } - - // Generate a JSON Web Token that will be used for authorization in next requests - $token = $this->jwtService->create($apiKey); - return new JsonResponse(['token' => $token]); - } -} diff --git a/module/Rest/src/Authentication/JWTService.php b/module/Rest/src/Authentication/JWTService.php index 77ec6728..cb985456 100644 --- a/module/Rest/src/Authentication/JWTService.php +++ b/module/Rest/src/Authentication/JWTService.php @@ -97,7 +97,7 @@ class JWTService implements JWTServiceInterface */ private function encode(array $data): string { - return JWT::encode($data, $this->appOptions->getSecretKey(), self::DEFAULT_ENCRYPTION_ALG); + return JWT::encode($data, '', self::DEFAULT_ENCRYPTION_ALG); } /** @@ -106,6 +106,6 @@ class JWTService implements JWTServiceInterface */ private function decode(string $jwt): array { - return (array) JWT::decode($jwt, $this->appOptions->getSecretKey(), [self::DEFAULT_ENCRYPTION_ALG]); + return (array) JWT::decode($jwt, '', [self::DEFAULT_ENCRYPTION_ALG]); } } diff --git a/module/Rest/src/Middleware/BackwardsCompatibleProblemDetailsMiddleware.php b/module/Rest/src/Middleware/BackwardsCompatibleProblemDetailsMiddleware.php deleted file mode 100644 index 11fce5c9..00000000 --- a/module/Rest/src/Middleware/BackwardsCompatibleProblemDetailsMiddleware.php +++ /dev/null @@ -1,63 +0,0 @@ - 'type', - 'message' => 'detail', - ]; - - private int $jsonFlags; - - public function __construct(int $jsonFlags) - { - $this->jsonFlags = $jsonFlags; - } - - public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface - { - $resp = $handler->handle($request); - if ($resp->getHeaderLine('Content-type') !== 'application/problem+json' || ! $this->isVersionOne($request)) { - return $resp; - } - - try { - $body = (string) $resp->getBody(); - $payload = $this->makePayloadBackwardsCompatible(json_decode($body)); - } catch (Throwable $e) { - return $resp; - } - - return new JsonResponse($payload, $resp->getStatusCode(), $resp->getHeaders(), $this->jsonFlags); - } - - private function isVersionOne(ServerRequestInterface $request): bool - { - $path = $request->getUri()->getPath(); - return strpos($path, '/v') === false || strpos($path, '/v1') === 0; - } - - private function makePayloadBackwardsCompatible(array $payload): array - { - return reduce_left(self::BACKWARDS_COMPATIBLE_FIELDS, function (string $newKey, string $oldKey, $c, $acc) { - $acc[$oldKey] = $acc[$newKey]; - return $acc; - }, $payload); - } -} diff --git a/module/Rest/src/Middleware/ShortUrl/ShortCodePathMiddleware.php b/module/Rest/src/Middleware/ShortUrl/ShortCodePathMiddleware.php deleted file mode 100644 index 683c3af5..00000000 --- a/module/Rest/src/Middleware/ShortUrl/ShortCodePathMiddleware.php +++ /dev/null @@ -1,34 +0,0 @@ -getUri(); - $path = $uri->getPath(); - - // If the path starts with the old prefix, replace it by the new one - return $handler->handle( - $request->withUri($uri->withPath(str_replace(self::OLD_PATH_PREFIX, self::NEW_PATH_PREFIX, $path))) - ); - } -} diff --git a/module/Rest/test-api/Action/CreateShortUrlActionTest.php b/module/Rest/test-api/Action/CreateShortUrlActionTest.php index efff5f33..9ec8e8e2 100644 --- a/module/Rest/test-api/Action/CreateShortUrlActionTest.php +++ b/module/Rest/test-api/Action/CreateShortUrlActionTest.php @@ -49,9 +49,7 @@ class CreateShortUrlActionTest extends ApiTestCase $this->assertEquals(self::STATUS_BAD_REQUEST, $statusCode); $this->assertEquals(self::STATUS_BAD_REQUEST, $payload['status']); $this->assertEquals($detail, $payload['detail']); - $this->assertEquals($detail, $payload['message']); // Deprecated $this->assertEquals('INVALID_SLUG', $payload['type']); - $this->assertEquals('INVALID_SLUG', $payload['error']); // Deprecated $this->assertEquals('Invalid custom slug', $payload['title']); $this->assertEquals($slug, $payload['customSlug']); @@ -215,7 +213,7 @@ class CreateShortUrlActionTest extends ApiTestCase } /** @test */ - public function failsToCreateShortUrlWithInvalidOriginalUrl(): void + public function failsToCreateShortUrlWithInvalidLongUrl(): void { $url = 'https://this-has-to-be-invalid.com'; $expectedDetail = sprintf('Provided URL %s is invalid. Try with a different one.', $url); @@ -225,9 +223,7 @@ class CreateShortUrlActionTest extends ApiTestCase $this->assertEquals(self::STATUS_BAD_REQUEST, $statusCode); $this->assertEquals(self::STATUS_BAD_REQUEST, $payload['status']); $this->assertEquals('INVALID_URL', $payload['type']); - $this->assertEquals('INVALID_URL', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Invalid URL', $payload['title']); $this->assertEquals($url, $payload['url']); } diff --git a/module/Rest/test-api/Action/DeleteShortUrlActionTest.php b/module/Rest/test-api/Action/DeleteShortUrlActionTest.php index 4680a6f6..7bf01c51 100644 --- a/module/Rest/test-api/Action/DeleteShortUrlActionTest.php +++ b/module/Rest/test-api/Action/DeleteShortUrlActionTest.php @@ -19,9 +19,7 @@ class DeleteShortUrlActionTest extends ApiTestCase $this->assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode()); $this->assertEquals(self::STATUS_NOT_FOUND, $payload['status']); $this->assertEquals('INVALID_SHORTCODE', $payload['type']); - $this->assertEquals('INVALID_SHORTCODE', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Short URL not found', $payload['title']); $this->assertEquals('invalid', $payload['shortCode']); } @@ -41,9 +39,7 @@ class DeleteShortUrlActionTest extends ApiTestCase $this->assertEquals(self::STATUS_UNPROCESSABLE_ENTITY, $resp->getStatusCode()); $this->assertEquals(self::STATUS_UNPROCESSABLE_ENTITY, $payload['status']); $this->assertEquals('INVALID_SHORTCODE_DELETION', $payload['type']); - $this->assertEquals('INVALID_SHORTCODE_DELETION', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Cannot delete short URL', $payload['title']); } } diff --git a/module/Rest/test-api/Action/EditShortUrlActionTest.php b/module/Rest/test-api/Action/EditShortUrlActionTest.php index bbcb043a..024ffb79 100644 --- a/module/Rest/test-api/Action/EditShortUrlActionTest.php +++ b/module/Rest/test-api/Action/EditShortUrlActionTest.php @@ -20,9 +20,7 @@ class EditShortUrlActionTest extends ApiTestCase $this->assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode()); $this->assertEquals(self::STATUS_NOT_FOUND, $payload['status']); $this->assertEquals('INVALID_SHORTCODE', $payload['type']); - $this->assertEquals('INVALID_SHORTCODE', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Short URL not found', $payload['title']); $this->assertEquals('invalid', $payload['shortCode']); } @@ -40,9 +38,7 @@ class EditShortUrlActionTest extends ApiTestCase $this->assertEquals(self::STATUS_BAD_REQUEST, $resp->getStatusCode()); $this->assertEquals(self::STATUS_BAD_REQUEST, $payload['status']); $this->assertEquals('INVALID_ARGUMENT', $payload['type']); - $this->assertEquals('INVALID_ARGUMENT', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Invalid data', $payload['title']); } } diff --git a/module/Rest/test-api/Action/EditShortUrlTagsActionTest.php b/module/Rest/test-api/Action/EditShortUrlTagsActionTest.php index e2922092..d48ffc5f 100644 --- a/module/Rest/test-api/Action/EditShortUrlTagsActionTest.php +++ b/module/Rest/test-api/Action/EditShortUrlTagsActionTest.php @@ -20,9 +20,7 @@ class EditShortUrlTagsActionTest extends ApiTestCase $this->assertEquals(self::STATUS_BAD_REQUEST, $resp->getStatusCode()); $this->assertEquals(self::STATUS_BAD_REQUEST, $payload['status']); $this->assertEquals('INVALID_ARGUMENT', $payload['type']); - $this->assertEquals('INVALID_ARGUMENT', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Invalid data', $payload['title']); } @@ -39,9 +37,7 @@ class EditShortUrlTagsActionTest extends ApiTestCase $this->assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode()); $this->assertEquals(self::STATUS_NOT_FOUND, $payload['status']); $this->assertEquals('INVALID_SHORTCODE', $payload['type']); - $this->assertEquals('INVALID_SHORTCODE', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Short URL not found', $payload['title']); $this->assertEquals('invalid', $payload['shortCode']); } diff --git a/module/Rest/test-api/Action/GetVisitsActionTest.php b/module/Rest/test-api/Action/GetVisitsActionTest.php index 0db06848..f6167f78 100644 --- a/module/Rest/test-api/Action/GetVisitsActionTest.php +++ b/module/Rest/test-api/Action/GetVisitsActionTest.php @@ -19,9 +19,7 @@ class GetVisitsActionTest extends ApiTestCase $this->assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode()); $this->assertEquals(self::STATUS_NOT_FOUND, $payload['status']); $this->assertEquals('INVALID_SHORTCODE', $payload['type']); - $this->assertEquals('INVALID_SHORTCODE', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Short URL not found', $payload['title']); $this->assertEquals('invalid', $payload['shortCode']); } diff --git a/module/Rest/test-api/Action/ListShortUrlsTest.php b/module/Rest/test-api/Action/ListShortUrlsTest.php index 0952a627..f8d8c542 100644 --- a/module/Rest/test-api/Action/ListShortUrlsTest.php +++ b/module/Rest/test-api/Action/ListShortUrlsTest.php @@ -24,7 +24,6 @@ class ListShortUrlsTest extends ApiTestCase 'validUntil' => null, 'maxVisits' => null, ], - 'originalUrl' => 'https://shlink.io', ]; private const SHORT_URL_CUSTOM_SLUG_AND_DOMAIN = [ 'shortCode' => 'custom-with-domain', @@ -38,7 +37,6 @@ class ListShortUrlsTest extends ApiTestCase 'validUntil' => null, 'maxVisits' => null, ], - 'originalUrl' => 'https://google.com', ]; private const SHORT_URL_META = [ 'shortCode' => 'def456', @@ -54,9 +52,6 @@ class ListShortUrlsTest extends ApiTestCase 'validUntil' => null, 'maxVisits' => null, ], - 'originalUrl' => - 'https://blog.alejandrocelaya.com/2017/12/09' - . '/acmailer-7-0-the-most-important-release-in-a-long-time/', ]; private const SHORT_URL_CUSTOM_SLUG = [ 'shortCode' => 'custom', @@ -70,7 +65,6 @@ class ListShortUrlsTest extends ApiTestCase 'validUntil' => null, 'maxVisits' => 2, ], - 'originalUrl' => 'https://shlink.io', ]; private const SHORT_URL_CUSTOM_DOMAIN = [ 'shortCode' => 'ghi789', @@ -86,9 +80,6 @@ class ListShortUrlsTest extends ApiTestCase 'validUntil' => null, 'maxVisits' => null, ], - 'originalUrl' => - 'https://blog.alejandrocelaya.com/2019/04/27' - . '/considerations-to-properly-use-open-source-software-projects/', ]; /** diff --git a/module/Rest/test-api/Action/ResolveShortUrlActionTest.php b/module/Rest/test-api/Action/ResolveShortUrlActionTest.php index e4d45f4a..09f48113 100644 --- a/module/Rest/test-api/Action/ResolveShortUrlActionTest.php +++ b/module/Rest/test-api/Action/ResolveShortUrlActionTest.php @@ -19,9 +19,7 @@ class ResolveShortUrlActionTest extends ApiTestCase $this->assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode()); $this->assertEquals(self::STATUS_NOT_FOUND, $payload['status']); $this->assertEquals('INVALID_SHORTCODE', $payload['type']); - $this->assertEquals('INVALID_SHORTCODE', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Short URL not found', $payload['title']); $this->assertEquals('invalid', $payload['shortCode']); } diff --git a/module/Rest/test-api/Action/UpdateTagActionTest.php b/module/Rest/test-api/Action/UpdateTagActionTest.php index fa07fcd1..eb70685a 100644 --- a/module/Rest/test-api/Action/UpdateTagActionTest.php +++ b/module/Rest/test-api/Action/UpdateTagActionTest.php @@ -23,9 +23,7 @@ class UpdateTagActionTest extends ApiTestCase $this->assertEquals(self::STATUS_BAD_REQUEST, $resp->getStatusCode()); $this->assertEquals(self::STATUS_BAD_REQUEST, $payload['status']); $this->assertEquals('INVALID_ARGUMENT', $payload['type']); - $this->assertEquals('INVALID_ARGUMENT', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Invalid data', $payload['title']); } @@ -50,9 +48,7 @@ class UpdateTagActionTest extends ApiTestCase $this->assertEquals(self::STATUS_NOT_FOUND, $resp->getStatusCode()); $this->assertEquals(self::STATUS_NOT_FOUND, $payload['status']); $this->assertEquals('TAG_NOT_FOUND', $payload['type']); - $this->assertEquals('TAG_NOT_FOUND', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Tag not found', $payload['title']); } @@ -70,9 +66,7 @@ class UpdateTagActionTest extends ApiTestCase $this->assertEquals(self::STATUS_CONFLICT, $resp->getStatusCode()); $this->assertEquals(self::STATUS_CONFLICT, $payload['status']); $this->assertEquals('TAG_CONFLICT', $payload['type']); - $this->assertEquals('TAG_CONFLICT', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Tag conflict', $payload['title']); } diff --git a/module/Rest/test-api/Middleware/AuthenticationTest.php b/module/Rest/test-api/Middleware/AuthenticationTest.php index d92f4a44..24cd8138 100644 --- a/module/Rest/test-api/Middleware/AuthenticationTest.php +++ b/module/Rest/test-api/Middleware/AuthenticationTest.php @@ -21,15 +21,13 @@ class AuthenticationTest extends ApiTestCase implode('", "', RequestToHttpAuthPlugin::SUPPORTED_AUTH_HEADERS) ); - $resp = $this->callApi(self::METHOD_GET, '/short-codes'); + $resp = $this->callApi(self::METHOD_GET, '/short-urls'); $payload = $this->getJsonResponsePayload($resp); $this->assertEquals(self::STATUS_UNAUTHORIZED, $resp->getStatusCode()); $this->assertEquals(self::STATUS_UNAUTHORIZED, $payload['status']); $this->assertEquals('INVALID_AUTHORIZATION', $payload['type']); - $this->assertEquals('INVALID_AUTHORIZATION', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Invalid authorization', $payload['title']); } @@ -41,7 +39,7 @@ class AuthenticationTest extends ApiTestCase { $expectedDetail = 'Provided API key does not exist or is invalid.'; - $resp = $this->callApi(self::METHOD_GET, '/short-codes', [ + $resp = $this->callApi(self::METHOD_GET, '/short-urls', [ 'headers' => [ Plugin\ApiKeyHeaderPlugin::HEADER_NAME => $apiKey, ], @@ -51,9 +49,7 @@ class AuthenticationTest extends ApiTestCase $this->assertEquals(self::STATUS_UNAUTHORIZED, $resp->getStatusCode()); $this->assertEquals(self::STATUS_UNAUTHORIZED, $payload['status']); $this->assertEquals('INVALID_API_KEY', $payload['type']); - $this->assertEquals('INVALID_API_KEY', $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals('Invalid API key', $payload['title']); } @@ -74,7 +70,7 @@ class AuthenticationTest extends ApiTestCase string $expectedType, string $expectedTitle ): void { - $resp = $this->callApi(self::METHOD_GET, '/short-codes', [ + $resp = $this->callApi(self::METHOD_GET, '/short-urls', [ 'headers' => [ Plugin\AuthorizationHeaderPlugin::HEADER_NAME => $authValue, ], @@ -84,9 +80,7 @@ class AuthenticationTest extends ApiTestCase $this->assertEquals(self::STATUS_UNAUTHORIZED, $resp->getStatusCode()); $this->assertEquals(self::STATUS_UNAUTHORIZED, $payload['status']); $this->assertEquals($expectedType, $payload['type']); - $this->assertEquals($expectedType, $payload['error']); // Deprecated $this->assertEquals($expectedDetail, $payload['detail']); - $this->assertEquals($expectedDetail, $payload['message']); // Deprecated $this->assertEquals($expectedTitle, $payload['title']); } diff --git a/module/Rest/test/Action/AuthenticateActionTest.php b/module/Rest/test/Action/AuthenticateActionTest.php deleted file mode 100644 index 84aa8fbe..00000000 --- a/module/Rest/test/Action/AuthenticateActionTest.php +++ /dev/null @@ -1,72 +0,0 @@ -apiKeyService = $this->prophesize(ApiKeyService::class); - $this->jwtService = $this->prophesize(JWTService::class); - $this->jwtService->create(Argument::cetera())->willReturn(''); - - $this->action = new AuthenticateAction($this->apiKeyService->reveal(), $this->jwtService->reveal()); - } - - /** @test */ - public function notProvidingAuthDataReturnsError() - { - $resp = $this->action->handle(new ServerRequest()); - $this->assertEquals(400, $resp->getStatusCode()); - } - - /** @test */ - public function properApiKeyReturnsTokenInResponse() - { - $this->apiKeyService->getByKey('foo')->willReturn((new ApiKey())->setId('5')) - ->shouldBeCalledOnce(); - - $request = (new ServerRequest())->withParsedBody([ - 'apiKey' => 'foo', - ]); - $response = $this->action->handle($request); - $this->assertEquals(200, $response->getStatusCode()); - - $response->getBody()->rewind(); - $this->assertTrue(strpos($response->getBody()->getContents(), '"token"') > 0); - } - - /** @test */ - public function invalidApiKeyReturnsErrorResponse() - { - $this->apiKeyService->getByKey('foo')->willReturn((new ApiKey())->disable()) - ->shouldBeCalledOnce(); - - $request = (new ServerRequest())->withParsedBody([ - 'apiKey' => 'foo', - ]); - $response = $this->action->handle($request); - $this->assertEquals(401, $response->getStatusCode()); - } -} diff --git a/module/Rest/test/Authentication/JWTServiceTest.php b/module/Rest/test/Authentication/JWTServiceTest.php deleted file mode 100644 index 76375fdc..00000000 --- a/module/Rest/test/Authentication/JWTServiceTest.php +++ /dev/null @@ -1,86 +0,0 @@ -service = new JWTService(new AppOptions([ - 'name' => 'ShlinkTest', - 'version' => '10000.3.1', - 'secret_key' => 'foo', - ])); - } - - /** @test */ - public function tokenIsProperlyCreated() - { - $id = '34'; - $token = $this->service->create((new ApiKey())->setId($id)); - $payload = (array) JWT::decode($token, 'foo', [JWTService::DEFAULT_ENCRYPTION_ALG]); - $this->assertGreaterThanOrEqual($payload['iat'], time()); - $this->assertGreaterThan(time(), $payload['exp']); - $this->assertEquals($id, $payload['key']); - $this->assertEquals('auth', $payload['sub']); - $this->assertEquals('ShlinkTest:v10000.3.1', $payload['iss']); - } - - /** @test */ - public function refreshIncreasesExpiration() - { - $originalLifetime = 10; - $newLifetime = 30; - $originalPayload = ['exp' => time() + $originalLifetime]; - $token = JWT::encode($originalPayload, 'foo'); - $newToken = $this->service->refresh($token, $newLifetime); - $newPayload = (array) JWT::decode($newToken, 'foo', [JWTService::DEFAULT_ENCRYPTION_ALG]); - - $this->assertGreaterThan($originalPayload['exp'], $newPayload['exp']); - } - - /** @test */ - public function verifyReturnsTrueWhenTheTokenIsCorrect() - { - $this->assertTrue($this->service->verify(JWT::encode([], 'foo'))); - } - - /** @test */ - public function verifyReturnsFalseWhenTheTokenIsCorrect() - { - $this->assertFalse($this->service->verify('invalidToken')); - } - - /** @test */ - public function getPayloadWorksWithCorrectTokens() - { - $originalPayload = [ - 'exp' => time() + 10, - 'sub' => 'testing', - ]; - $token = JWT::encode($originalPayload, 'foo'); - $this->assertEquals($originalPayload, $this->service->getPayload($token)); - } - - /** @test */ - public function getPayloadThrowsExceptionWithIncorrectTokens() - { - $this->expectException(AuthenticationException::class); - $this->service->getPayload('invalidToken'); - } -} diff --git a/module/Rest/test/Middleware/AuthenticationMiddlewareTest.php b/module/Rest/test/Middleware/AuthenticationMiddlewareTest.php index 8bef98a1..1d306fdc 100644 --- a/module/Rest/test/Middleware/AuthenticationMiddlewareTest.php +++ b/module/Rest/test/Middleware/AuthenticationMiddlewareTest.php @@ -13,7 +13,7 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\Log\LoggerInterface; -use Shlinkio\Shlink\Rest\Action\AuthenticateAction; +use Shlinkio\Shlink\Rest\Action\HealthAction; use Shlinkio\Shlink\Rest\Authentication\Plugin\AuthenticationPluginInterface; use Shlinkio\Shlink\Rest\Authentication\RequestToHttpAuthPluginInterface; use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware; @@ -37,7 +37,7 @@ class AuthenticationMiddlewareTest extends TestCase $this->middleware = new AuthenticationMiddleware( $this->requestToPlugin->reveal(), - [AuthenticateAction::class], + [HealthAction::class], $this->logger->reveal() ); } @@ -72,7 +72,7 @@ class AuthenticationMiddlewareTest extends TestCase yield 'with whitelisted route' => [(new ServerRequest())->withAttribute( RouteResult::class, RouteResult::fromRoute( - new Route('foo', $dummyMiddleware, Route::HTTP_METHOD_ANY, AuthenticateAction::class) + new Route('foo', $dummyMiddleware, Route::HTTP_METHOD_ANY, HealthAction::class) ) )]; yield 'with OPTIONS method' => [(new ServerRequest())->withAttribute( diff --git a/module/Rest/test/Middleware/BackwardsCompatibleProblemDetailsMiddlewareTest.php b/module/Rest/test/Middleware/BackwardsCompatibleProblemDetailsMiddlewareTest.php deleted file mode 100644 index 20a5b04d..00000000 --- a/module/Rest/test/Middleware/BackwardsCompatibleProblemDetailsMiddlewareTest.php +++ /dev/null @@ -1,94 +0,0 @@ -handler = $this->prophesize(RequestHandlerInterface::class); - $this->middleware = new BackwardsCompatibleProblemDetailsMiddleware(0); - } - - /** - * @test - * @dataProvider provideNonProcessableResponses - */ - public function nonProblemDetailsOrInvalidResponsesAreReturnedAsTheyAre( - Response $response, - ?ServerRequest $request = null - ): void { - $request = $request ?? ServerRequestFactory::fromGlobals(); - $handle = $this->handler->handle($request)->willReturn($response); - - $result = $this->middleware->process($request, $this->handler->reveal()); - - $this->assertSame($response, $result); - $handle->shouldHaveBeenCalledOnce(); - } - - public function provideNonProcessableResponses(): iterable - { - yield 'no problem details' => [new Response()]; - yield 'invalid JSON' => [(new Response('data://text/plain,{invalid-json'))->withHeader( - 'Content-Type', - 'application/problem+json' - )]; - yield 'version 2' => [ - (new Response())->withHeader('Content-type', 'application/problem+json'), - ServerRequestFactory::fromGlobals()->withUri(new Uri('/v2/something')), - ]; - } - - /** - * @test - * @dataProvider provideRequestPath - */ - public function mapsDeprecatedPropertiesWhenRequestIsPerformedToVersionOne(string $requestPath): void - { - $request = ServerRequestFactory::fromGlobals()->withUri(new Uri($requestPath)); - $response = $this->jsonResponse([ - 'type' => 'the_type', - 'detail' => 'the_detail', - ]); - $handle = $this->handler->handle($request)->willReturn($response); - - /** @var Response\JsonResponse $result */ - $result = $this->middleware->process($request, $this->handler->reveal()); - $payload = $result->getPayload(); - - $this->assertEquals([ - 'type' => 'the_type', - 'detail' => 'the_detail', - 'error' => 'the_type', - 'message' => 'the_detail', - ], $payload); - $handle->shouldHaveBeenCalledOnce(); - } - - public function provideRequestPath(): iterable - { - yield 'no version' => ['/foo']; - yield 'version one' => ['/v1/foo']; - } - - private function jsonResponse(array $payload, int $status = 200): Response\JsonResponse - { - $headers = ['Content-Type' => 'application/problem+json']; - return new Response\JsonResponse($payload, $status, $headers); - } -} diff --git a/module/Rest/test/Middleware/ShortUrl/ShortCodePathMiddlewareTest.php b/module/Rest/test/Middleware/ShortUrl/ShortCodePathMiddlewareTest.php deleted file mode 100644 index fb1ae215..00000000 --- a/module/Rest/test/Middleware/ShortUrl/ShortCodePathMiddlewareTest.php +++ /dev/null @@ -1,49 +0,0 @@ -middleware = new ShortCodePathMiddleware(); - $this->requestHandler = $this->prophesize(RequestHandlerInterface::class); - $this->requestHandler->handle(Argument::type(ServerRequestInterface::class))->willReturn(new Response()); - } - - /** @test */ - public function properlyReplacesTheOldPathByTheNewOne() - { - $uri = new Uri('/short-codes/foo'); - - $request = $this->prophesize(ServerRequestInterface::class); - $request->getUri()->willReturn($uri); - $withUri = $request->withUri(Argument::that(function (UriInterface $uri) { - $path = $uri->getPath(); - - Assert::assertStringContainsString('/short-urls', $path); - Assert::assertStringNotContainsString('/short-codes', $path); - - return $uri; - }))->willReturn($request->reveal()); - - $this->middleware->process($request->reveal(), $this->requestHandler->reveal()); - - $withUri->shouldHaveBeenCalledOnce(); - } -}