From 58eceafd0c372235c4010348608a256d50926313 Mon Sep 17 00:00:00 2001
From: Benni Mack <benni@typo3.org>
Date: Mon, 19 Apr 2021 19:14:38 +0200
Subject: [PATCH] [BUGFIX] Check if site language is enabled before redirecting

Only if a site language is enabled, it should be taken into account for
redirecting.
To keep the interface valid, the 1st site language is returned if no
other site language is found.

Resolves: #93920
Releases: master, 10.4
Change-Id: I304c845012d3d76cd230e775030ac08a8d003e6b
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/68775
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: core-ci <typo3@b13.com>
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
---
 .../Middleware/SiteBaseRedirectResolver.php   |  8 +-
 .../SiteBaseRedirectResolverTest.php          | 76 +++++++++++++++++++
 2 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/typo3/sysext/frontend/Classes/Middleware/SiteBaseRedirectResolver.php b/typo3/sysext/frontend/Classes/Middleware/SiteBaseRedirectResolver.php
index 8a89cd474cb2..825dd95d6105 100644
--- a/typo3/sysext/frontend/Classes/Middleware/SiteBaseRedirectResolver.php
+++ b/typo3/sysext/frontend/Classes/Middleware/SiteBaseRedirectResolver.php
@@ -58,7 +58,13 @@ class SiteBaseRedirectResolver implements MiddlewareInterface
         if ($site instanceof Site && !($language instanceof SiteLanguage)) {
             if ($routeResult instanceof SiteRouteResult && $routeResult->getTail() === '') {
                 $language = $site->getDefaultLanguage();
-                return new RedirectResponse($language->getBase(), 307);
+                if ($language->isEnabled()) {
+                    return new RedirectResponse($language->getBase(), 307);
+                }
+                // Default language is disabled, check for the first (enabled) language in list to redirect to that
+                foreach ($site->getLanguages() as $language) {
+                    return new RedirectResponse($language->getBase(), 307);
+                }
             }
             return GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
                 $request,
diff --git a/typo3/sysext/frontend/Tests/Unit/Middleware/SiteBaseRedirectResolverTest.php b/typo3/sysext/frontend/Tests/Unit/Middleware/SiteBaseRedirectResolverTest.php
index 50d7385f8c2d..b05636722ce4 100644
--- a/typo3/sysext/frontend/Tests/Unit/Middleware/SiteBaseRedirectResolverTest.php
+++ b/typo3/sysext/frontend/Tests/Unit/Middleware/SiteBaseRedirectResolverTest.php
@@ -301,4 +301,80 @@ class SiteBaseRedirectResolverTest extends UnitTestCase
         $response = $subject->process($request, $this->siteFoundRequestHandler);
         self::assertEquals(200, $response->getStatusCode());
     }
+
+    /**
+     * @test
+     */
+    public function useDefaultLanguageIfNoLanguageIsGiven(): void
+    {
+        $incomingUrl = 'https://twenty.one/';
+        $site = new Site('random-site', 13, [
+            'base' => 'https://twenty.one/',
+            'languages' => [
+                0 => [
+                    'languageId' => 0,
+                    'locale' => 'en_US.UTF-8',
+                    'base' => '/en/'
+                ],
+                1 => [
+                    'languageId' => 1,
+                    'locale' => 'fr_FR.UTF-8',
+                    'base' => '/fr'
+                ],
+                2 => [
+                    'languageId' => 2,
+                    'locale' => 'fr_CA.UTF-8',
+                    'base' => '/fr_ca'
+                ]
+            ]
+        ]);
+
+        $routeResult = new SiteRouteResult(new Uri($incomingUrl), $site);
+        $request = new ServerRequest($incomingUrl, 'GET');
+        $request = $request->withAttribute('site', $site);
+        $request = $request->withAttribute('routing', $routeResult);
+
+        $subject = new SiteBaseRedirectResolver();
+        $response = $subject->process($request, $this->siteFoundRequestHandler);
+        self::assertEquals('https://twenty.one/en/', $response->getHeader('Location')[0]);
+    }
+
+    /**
+     * @test
+     */
+    public function useFirstAvailableLanguageIfDefaultLanguageIsNotEnabledAndLanguageIsGiven(): void
+    {
+        $incomingUrl = 'https://twenty.one/';
+        $site = new Site('random-site', 13, [
+            'base' => 'https://twenty.one/',
+            'languages' => [
+                0 => [
+                    'languageId' => 0,
+                    'enabled' => false,
+                    'locale' => 'en_US.UTF-8',
+                    'base' => '/en/'
+                ],
+                1 => [
+                    'languageId' => 1,
+                    'enabled' => false,
+                    'locale' => 'fr_FR.UTF-8',
+                    'base' => '/fr'
+                ],
+                2 => [
+                    'languageId' => 2,
+                    'locale' => 'fr_CA.UTF-8',
+                    'base' => '/fr_ca'
+                ]
+            ]
+        ]);
+
+        $routeResult = new SiteRouteResult(new Uri($incomingUrl), $site);
+        $request = new ServerRequest($incomingUrl, 'GET');
+        $request = $request->withAttribute('site', $site);
+        $request = $request->withAttribute('routing', $routeResult);
+
+        $subject = new SiteBaseRedirectResolver();
+        $response = $subject->process($request, $this->siteFoundRequestHandler);
+        self::assertEquals('https://twenty.one/fr_ca', $response->getHeader('Location')[0]);
+    }
 }
-- 
GitLab