From efa49136ea14de437a2ae4be26b6f2f373056a58 Mon Sep 17 00:00:00 2001 From: Alexander Berl Date: Wed, 14 Apr 2021 18:13:40 +0200 Subject: [PATCH] TASK: Add RedirectMiddleware --- Classes/Http/RedirectMiddleware.php | 95 +++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 Classes/Http/RedirectMiddleware.php diff --git a/Classes/Http/RedirectMiddleware.php b/Classes/Http/RedirectMiddleware.php new file mode 100644 index 0000000..033cdb5 --- /dev/null +++ b/Classes/Http/RedirectMiddleware.php @@ -0,0 +1,95 @@ +handle($request); + // TODO: Find a better solution to communicate from TokenProvider to this middleware + $redirectTarget = $response->getHeaderLine(static::class . '.redirect'); + if ($redirectTarget === null) { + return $response; + } + if ($redirectTarget === self::REDIRECT_LOGIN) { + return $this->redirectToLogin($request); + } elseif ($redirectTarget === self::REDIRECT_SETUP) { + return $this->redirectToSetup($request); + } else { + throw new \RuntimeException(sprintf('Invalid redirect target "%s"', $redirectTarget), 1568189192); + } + } + + /** + * Triggers a redirect to the 2FA login route configured at routes.login or throws an exception if the configuration is missing/incorrect + */ + private function redirectToLogin(ServerRequestInterface $request): ResponseInterface + { + try { + $this->validateRouteValues($this->loginRouteValues); + } catch (\InvalidArgumentException $exception) { + throw new \RuntimeException('Missing/invalid routes.login configuration: ' . $exception->getMessage(), 1550660144, $exception); + } + return $this->redirect($request, $this->loginRouteValues); + } + + /** + * Triggers a redirect to the 2FA setup route configured at routes.setup or throws an exception if the configuration is missing/incorrect + */ + private function redirectToSetup(ServerRequestInterface $request): ResponseInterface + { + try { + $this->validateRouteValues($this->setupRouteValue); + } catch (\InvalidArgumentException $exception) { + throw new \RuntimeException('Missing/invalid routes.setup configuration: ' . $exception->getMessage(), 1550660178, $exception); + } + return $this->redirect($request, $this->setupRouteValue); + } + + private function validateRouteValues(array $routeValues): void + { + $requiredRouteValues = ['@package', '@controller', '@action']; + foreach ($requiredRouteValues as $routeValue) { + if (!array_key_exists($routeValue, $routeValues)) { + throw new \InvalidArgumentException(sprintf('Missing "%s" route value', $routeValue), 1550660039); + } + } + } + + private function redirect(ServerRequestInterface $httpRequest, array $routeValues): ResponseInterface + { + $actionRequest = ActionRequest::fromHttpRequest($httpRequest); + $uriBuilder = new UriBuilder(); + $uriBuilder->setRequest($actionRequest); + $redirectUrl = $uriBuilder->setCreateAbsoluteUri(true)->setFormat('html')->build($routeValues); + + return (new Response())->withStatus(303)->withHeader('Location', $redirectUrl); + } +}