TYPO3-Solr / ext-solr

A TYPO3 extension that integrates the Apache Solr search server with TYPO3 CMS. dkd Internet Service GmbH is developing the extension. Community contributions are welcome. See CONTRIBUTING.md for details.
GNU General Public License v3.0
136 stars 246 forks source link

[BUG] Backend User gets logged out due to changes on pages with `l18n_cfg` field set to 1 #3246

Open DenisMir opened 2 years ago

DenisMir commented 2 years ago

Describe the bug We found a major bug which breaks working with the TYPO3 backend. When you edit pages or add/edit records on pages that have l18n_cfg (Hide default language of page) set to 1 the backend user gets logged out.

The reason for it is the RecordMonitor that tries to add changed pages to the index queue.

In this process it is checking for ApacheSolrForTypo3\Solr\FrontendEnvironment->isAllowedPageType.

This leads to a initialisation of the TSFE with the important code lines being in ApacheSolrForTypo3\Solr\FrontendEnvironment\Tsfe->initializeTsfe from line 191:

            try {
                $tsfe->determineId($serverRequest);
                $serverRequest->withAttribute('frontend.controller', $tsfe);
                $tsfe->no_cache = false;
                $tsfe->getConfigArray($serverRequest);

                $tsfe->newCObj($serverRequest);
                $tsfe->absRefPrefix = self::getAbsRefPrefixFromTSFE($tsfe);
                $tsfe->calculateLinkVars([]);

                $beUser = $context->getAspect('backend.user');
                $loggedIn = $beUser->isLoggedIn();
            } catch (Throwable $exception) {
                // @todo: logging
                $this->serverRequestCache[$cacheIdentifier] = null;
                $this->tsfeCache[$cacheIdentifier] = null;
                // Restore backend user, happens when initializeTsfe() is called from Backend context
                if ($backedUpBackendUser) {
                    $GLOBALS['BE_USER'] = $backedUpBackendUser;
                }
                $beUser = $context->getAspect('backend.user');
                $loggedIn = $beUser->isLoggedIn();
                return;
            }

The $tsfe->determineId($serverRequest); ends up in the TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->settingLanguage which checks for $pageTranslationVisibility = new PageTranslationVisibility((int)($this->page['l18n_cfg'] ?? 0)); and then ends up here:

        // If default language is not available:
        if ((!$languageAspect->getContentId() || !$languageAspect->getId())
            && $pageTranslationVisibility->shouldBeHiddenInDefaultLanguage()
        ) {
            $message = 'Page is not available in default language.';
            $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
                $request,
                $message,
                ['code' => PageAccessFailureReasons::LANGUAGE_DEFAULT_NOT_AVAILABLE]
            );
            throw new PropagateResponseException($response, 1533931423);
        }

This 404 PropagateResponseException leads to the logout of the backend user.

To Reproduce Steps to reproduce the behaviour:

  1. Activate Hide default language of page in page settings
  2. Add a content element to this page
  3. Backend user gets logged out

Expected behavior Record monitoring should never lead to a logout of the backend user.

Screenshots Bildschirmfoto 2022-04-22 um 09 00 29 Bildschirmfoto 2022-04-22 um 09 03 14

Used versions (please complete the following information):

dkd-kaehm commented 2 years ago

Related change: c7c0ba8ad7a96e733d5dd73f2c5746bac95aee6f @bmack do you have some suggestion for that issue?

bmack commented 2 years ago

@dkd-kaehm Cannot reproduce this issue yet, but I have a similar problem in a 11.5.x-dev solr branch, which I cannot update yet to the latest RC-1 due to a missing PR being merged (fluid grouping).

In general, the exception should be caught, and the backend user should be kept, and if the exception is thrown the $GLOBALs['BE_USER'] is empty but the $backedUpBackendUser is still available @DenisMir ?

DenisMir commented 2 years ago

@bmack It is as you said $GLOBALs['BE_USER'] is empty but $backedUpBackendUser is filled and ist seems to recover fine in the catch clause:

Bildschirmfoto 2022-04-26 um 13 09 45 Bildschirmfoto 2022-04-26 um 13 10 33 Bildschirmfoto 2022-04-26 um 13 19 23

I've added these loggedIn vars for debugging purposes.

But when I step only one step further back out to ApacheSolrForTypo3\Solr\FrontendEnvironment\Tsfe->assureIsInitialized after the $this->initializeTsfe($pageId, $language, $rootPageId); call the loggedIn status turns false.

Bildschirmfoto 2022-04-26 um 13 30 01

I don't get what is happening here but this leads to the logout.

DenisMir commented 2 years ago

Ok we can now say that from the moment

            $response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
                $request,
                $message,
                ['code' => PageAccessFailureReasons::LANGUAGE_DEFAULT_NOT_AVAILABLE]
            );

gets executed. (TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->settingLanguage)

The user in the backend.user aspect of the Context is an empty stdClass. (like the pseudo user) This is the case even after resetting the backed up backend user.

dkd-kaehm commented 2 years ago

@DenisMir Some updates on this issue? Do you have time to track to the source of trouble and fix this issue?

dkd-kaehm commented 2 years ago

Can not reproduce this issue on solr-ddev-site within TYPO3 11.5.13 and EXT:solr at 3fa4ff49662a23fc75b02667823e9f1bded0f413 (dev-11.5 @ 2022.07.21) Please ask to reopen this issue if some news or exact steps to reproduce this issue on solr-ddev-site are available.

DenisMir commented 2 years ago

@dkd-kaehm I couldn't find the reason for the error. But I'm checking it now again on the dev-11.5.

DenisMir commented 2 years ago

@dkd-kaehm Trying this on 11.5.13 + dev-release-11.5.x 6196913 still results in the same error. Pages without l18n_cfg set do work and the other ones don't.

Removing the solr extension does immediately stop this error from occurring.

dkd-kaehm commented 2 years ago

@DenisMir I'll reopen this issue. Please try to reproduce within solr-ddev-site and provide exact steps to reproduce. Most probably fallback settings in site-config are player on this issue.

DenisMir commented 2 years ago

@dkd-kaehm I'm setting up the ddev project right now. At the moment I'm a bit lost on why this happens. What I can also say is that hidden = 1 on the page does remove the error (log out on adding/editing of CEs) as well although l18n_cfg keeps being set to 1.

DenisMir commented 2 years ago

@dkd-kaehm @bmack

After a lot of testing I found out the source for the error. The reason for the error is the typo3 feature flag subrequestPageErrors being set to true.

Here is the way to reproduce the error in the solr-ddev-site (https://github.com/TYPO3-Solr/solr-ddev-site) project.

1) Add the error handler in the Site config

Bildschirmfoto 2022-07-28 um 12 44 53

2) Enable the feature subrequestPageErrors

Bildschirmfoto 2022-07-28 um 12 45 15

3) Set l18n_cfg of page Features to 1

Bildschirmfoto 2022-07-28 um 12 47 08

4) Save -> get logged out instantly

So and now comes the weird thing and perhaps @bmack can shed some light on it.

The docs for that feature in 11LTS says (https://docs.typo3.org/m/typo3/reference-coreapi/11.5/en-us/ApiOverview/SiteHandling/ErrorHandling/PageErrorHandler.html)

The internal sub-request is the default behavior. This behavior can be disabled in favor of a curl-based approach by using the feature flag subrequestPageErrors in the Settings module.

And the changelog from 11LTS says (https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/11.4/Feature-94402-GenerateErrorPagesViaTYPO3-internalSubRequest.html)

This feature is disabled by default, as there are some cases where stateful information is not correctly reset for the subrequest. It may be enabled on an experimental basis via a feature flag called subrequestPageErrors in the "Settings" module.

In addition there is also a different issue regarding that feature:

https://forge.typo3.org/issues/95253

And the description in the backend settings UI says

If on, error pages in the Frontend (such as 404 pages) will be requested internally via the TYPO3 Frontend instead of using an external HTTP request. It may be enabled on an experimental basis, as there are some cases where stateful information is not correctly reset for the subrequest. Disable this feature if you have trouble with stateful services or when some custom extensions overriding PHPs global variables.
Default setting: Disabled

So to be honest I'm 100% confused. The descriptions in the docs, changelog, backend UI are conflicting. What is the default behavior? Does it do the internal sub request by default or does it do the external curl call by default like in 10LTS.

From the core code (11.5.13 - https://github.com/TYPO3/typo3/blob/v11.5.13/typo3/sysext/core/Classes/Error/PageErrorHandler/PageContentErrorHandler.php#L98)

            if ($this->useSubrequest) {
                // Create a subrequest and do not take any special query parameters into account
                $subRequest = $request->withQueryParams([])->withUri(new Uri($resolvedUrl))->withMethod('GET');
                $subResponse = $this->stashEnvironment(fn (): ResponseInterface => $this->sendSubRequest($subRequest, $urlParams['pageuid']));
            } else {
                try {
                    $subResponse = $this->cachePageRequest($resolvedUrl, $this->pageUid, fn () => $this->sendRawRequest($resolvedUrl));
                } catch (\Exception $e) {
                    throw new \RuntimeException(sprintf('Error handler could not fetch error page "%s", reason: %s', $resolvedUrl, $e->getMessage()), 1544172838, $e);
                }
            }

I would say that default behavior is the guzzle call (feature disabled) and the internal sub request is optional. So the changelog is right and the docs are wrong.

Nevertheless this is the reason for this bug.

bmack commented 2 years ago

Yes. internal subrequests are "off by default".

liayn commented 2 years ago

So https://github.com/TYPO3-Documentation/TYPO3CMS-Reference-CoreApi/commit/d71d1049439e8ffd888cabbef5e59d143ee8ab6f is the "offending" commit that introduced the wrong information in the docs as it seems. I'll follow-up on that.

The behaviour has been changed with https://review.typo3.org/c/Packages/TYPO3.CMS/+/71107

christophlehmann commented 11 months ago

Same here on v11.5.3. I get logged out when hiding a content element. I need the enabled subrequestPageErrors for a working referrer redirect in felogin, so my workaround is to use delayed updates

delayed-updates