From 6a40bbdcb54cf603eb96a6a5cd923a84aaada269 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Fri, 30 Jul 2021 18:53:57 +0200 Subject: [PATCH] Created new action to set redirects for a domain --- docs/swagger/paths/v2_domains_redirects.json | 33 ++++++++++ module/Core/src/Config/NotFoundRedirects.php | 13 +++- module/Rest/config/dependencies.config.php | 2 + module/Rest/config/routes.config.php | 1 + .../Action/Domain/DomainRedirectsAction.php | 41 +++++++++++++ .../src/Action/Domain/ListDomainsAction.php | 2 + .../Domain/Request/DomainRedirectsRequest.php | 60 +++++++++++++++++++ 7 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 module/Rest/src/Action/Domain/DomainRedirectsAction.php create mode 100644 module/Rest/src/Action/Domain/Request/DomainRedirectsRequest.php diff --git a/docs/swagger/paths/v2_domains_redirects.json b/docs/swagger/paths/v2_domains_redirects.json index 0868504e..bba6fbb7 100644 --- a/docs/swagger/paths/v2_domains_redirects.json +++ b/docs/swagger/paths/v2_domains_redirects.json @@ -66,6 +66,39 @@ } } }, + "400": { + "description": "Provided data is invalid.", + "content": { + "application/problem+json": { + "schema": { + "type": "object", + "allOf": [ + { + "$ref": "../definitions/Error.json" + }, + { + "type": "object", + "required": ["invalidElements"], + "properties": { + "invalidElements": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "domain", + "baseUrlRedirect", + "regular404Redirect", + "invalidShortUrlRedirect" + ] + } + } + } + } + ] + } + } + } + }, "500": { "description": "Unexpected error.", "content": { diff --git a/module/Core/src/Config/NotFoundRedirects.php b/module/Core/src/Config/NotFoundRedirects.php index 2a1e68d4..bb8c578c 100644 --- a/module/Core/src/Config/NotFoundRedirects.php +++ b/module/Core/src/Config/NotFoundRedirects.php @@ -4,7 +4,9 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\Config; -final class NotFoundRedirects +use JsonSerializable; + +final class NotFoundRedirects implements JsonSerializable { public function __construct( private ?string $baseUrlRedirect = null, @@ -27,4 +29,13 @@ final class NotFoundRedirects { return $this->invalidShortUrlRedirect; } + + public function jsonSerialize(): array + { + return [ + 'baseUrlRedirect' => $this->baseUrlRedirect, + 'regular404Redirect' => $this->regular404Redirect, + 'invalidShortUrlRedirect' => $this->invalidShortUrlRedirect, + ]; + } } diff --git a/module/Rest/config/dependencies.config.php b/module/Rest/config/dependencies.config.php index e1a869df..5e0267d6 100644 --- a/module/Rest/config/dependencies.config.php +++ b/module/Rest/config/dependencies.config.php @@ -40,6 +40,7 @@ return [ Action\Tag\CreateTagsAction::class => ConfigAbstractFactory::class, Action\Tag\UpdateTagAction::class => ConfigAbstractFactory::class, Action\Domain\ListDomainsAction::class => ConfigAbstractFactory::class, + Action\Domain\DomainRedirectsAction::class => ConfigAbstractFactory::class, ImplicitOptionsMiddleware::class => Middleware\EmptyResponseImplicitOptionsMiddlewareFactory::class, Middleware\BodyParserMiddleware::class => InvokableFactory::class, @@ -81,6 +82,7 @@ return [ Action\Tag\CreateTagsAction::class => [TagService::class], Action\Tag\UpdateTagAction::class => [TagService::class], Action\Domain\ListDomainsAction::class => [DomainService::class], + Action\Domain\DomainRedirectsAction::class => [DomainService::class], Middleware\CrossDomainMiddleware::class => ['config.cors'], Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class => ['config.url_shortener.domain.hostname'], diff --git a/module/Rest/config/routes.config.php b/module/Rest/config/routes.config.php index 9b09a266..991f4bb3 100644 --- a/module/Rest/config/routes.config.php +++ b/module/Rest/config/routes.config.php @@ -44,6 +44,7 @@ return [ // Domains Action\Domain\ListDomainsAction::getRouteDef(), + Action\Domain\DomainRedirectsAction::getRouteDef(), Action\MercureInfoAction::getRouteDef(), ], diff --git a/module/Rest/src/Action/Domain/DomainRedirectsAction.php b/module/Rest/src/Action/Domain/DomainRedirectsAction.php new file mode 100644 index 00000000..d9259582 --- /dev/null +++ b/module/Rest/src/Action/Domain/DomainRedirectsAction.php @@ -0,0 +1,41 @@ +getParsedBody(); + $requestData = DomainRedirectsRequest::fromRawData($body); + $apiKey = AuthenticationMiddleware::apiKeyFromRequest($request); + + $authority = $requestData->authority(); + $domain = $this->domainService->getOrCreate($authority); + $notFoundRedirects = $requestData->toNotFoundRedirects($domain); + + $this->domainService->configureNotFoundRedirects($authority, $notFoundRedirects, $apiKey); + + return new JsonResponse($notFoundRedirects); + } +} diff --git a/module/Rest/src/Action/Domain/ListDomainsAction.php b/module/Rest/src/Action/Domain/ListDomainsAction.php index c8f9a475..3d9205f8 100644 --- a/module/Rest/src/Action/Domain/ListDomainsAction.php +++ b/module/Rest/src/Action/Domain/ListDomainsAction.php @@ -25,6 +25,8 @@ class ListDomainsAction extends AbstractRestAction $apiKey = AuthenticationMiddleware::apiKeyFromRequest($request); $domainItems = $this->domainService->listDomains($apiKey); + // TODO Support including not found redirects if requested via query param + return new JsonResponse([ 'domains' => [ 'data' => $domainItems, diff --git a/module/Rest/src/Action/Domain/Request/DomainRedirectsRequest.php b/module/Rest/src/Action/Domain/Request/DomainRedirectsRequest.php new file mode 100644 index 00000000..d43ca223 --- /dev/null +++ b/module/Rest/src/Action/Domain/Request/DomainRedirectsRequest.php @@ -0,0 +1,60 @@ +validateAndInit($payload); + return $instance; + } + + private function validateAndInit(array $payload): void + { + // TODO Validate data + $this->baseUrlRedirectWasProvided = array_key_exists('baseUrlRedirect', $payload); + $this->regular404RedirectWasProvided = array_key_exists('regular404Redirect', $payload); + $this->invalidShortUrlRedirectWasProvided = array_key_exists('invalidShortUrlRedirect', $payload); + + $this->authority = $payload['domain']; + $this->baseUrlRedirect = $payload['baseUrlRedirect'] ?? null; + $this->regular404Redirect = $payload['regular404Redirect'] ?? null; + $this->invalidShortUrlRedirect = $payload['invalidShortUrlRedirect'] ?? null; + } + + public function authority(): string + { + return $this->authority; + } + + public function toNotFoundRedirects(?NotFoundRedirectConfigInterface $defaults = null): NotFoundRedirects + { + return new NotFoundRedirects( + $this->baseUrlRedirectWasProvided ? $this->baseUrlRedirect : $defaults?->baseUrlRedirect(), + $this->regular404RedirectWasProvided ? $this->regular404Redirect : $defaults?->regular404Redirect(), + $this->invalidShortUrlRedirectWasProvided + ? $this->invalidShortUrlRedirect + : $defaults?->invalidShortUrlRedirect(), + ); + } +}