Skip to content

Commit

Permalink
[BUGFIX] Fix indexing of access protected pages
Browse files Browse the repository at this point in the history
Fixes indexing of access protected pages and/or page contents.

Resolves: #3735
  • Loading branch information
dkd-friedrich authored and dkd-kaehm committed Oct 10, 2023
1 parent f35f652 commit a6168bc
Show file tree
Hide file tree
Showing 13 changed files with 326 additions and 27 deletions.
1 change: 0 additions & 1 deletion Build/Test/phpstan.neon
Expand Up @@ -20,6 +20,5 @@ parameters:
- '#^Variable \$_EXTKEY might not be defined\.#'
- '#^Method .*\\QueryBuilder::buildSuggestQuery\(\) should return .*\\SuggestQuery but returns .*\\Search\\Query\\Query\|null.#'
- '#^Method .*\\QueryBuilder::use.*FromTypoScript\(\) should return .*\\QueryBuilder but returns .*\\AbstractQueryBuilder.#'
- '#^Access to protected property .*\\PageRepository::\$where_groupAccess.#'
- '#^Unreachable statement - code above always terminates.#'
- '#^Parameter \#1 \$queryAlternative of method .*\\DisMax::setQueryAlternative\(\) expects string, null given.#'
11 changes: 9 additions & 2 deletions Classes/EventListener/PageIndexer/FrontendGroupsModifier.php
Expand Up @@ -40,9 +40,13 @@ class FrontendGroupsModifier
public function __invoke(ModifyResolvedFrontendGroupsEvent $event): void
{
$pageIndexerRequest = $event->getRequest()->getAttribute('solr.pageIndexingInstructions');
if (!$pageIndexerRequest instanceof PageIndexerRequest) {
if (!$pageIndexerRequest instanceof PageIndexerRequest
|| ((int)$pageIndexerRequest->getParameter('userGroup') === 0
&& (int)$pageIndexerRequest->getParameter('pageUserGroup') < 1)
) {
return;
}

if (!$pageIndexerRequest->isAuthenticated()) {
$logger = GeneralUtility::makeInstance(SolrLogManager::class, self::class);
$logger->error(
Expand All @@ -58,7 +62,7 @@ public function __invoke(ModifyResolvedFrontendGroupsEvent $event): void
'error' => [
'code' => 403,
'message' => 'Invalid Index Queue Request.',
],
],
],
403
),
Expand All @@ -67,6 +71,9 @@ public function __invoke(ModifyResolvedFrontendGroupsEvent $event): void
}

$groups = $this->resolveFrontendUserGroups($pageIndexerRequest);
if ((int)$pageIndexerRequest->getParameter('pageUserGroup') > 0) {
$groups[] = (int)$pageIndexerRequest->getParameter('pageUserGroup');
}
$groupData = [];
foreach ($groups as $groupUid) {
if (in_array($groupUid, [-2, -1])) {
Expand Down
7 changes: 6 additions & 1 deletion Classes/IndexQueue/FrontendHelper/PageIndexer.php
Expand Up @@ -54,6 +54,8 @@
*/
class PageIndexer implements FrontendHelper, SingletonInterface
{
protected bool $activated = false;

/**
* This frontend helper's executed action.
*/
Expand Down Expand Up @@ -92,6 +94,7 @@ class PageIndexer implements FrontendHelper, SingletonInterface
public function activate(): void
{
$this->logger = GeneralUtility::makeInstance(SolrLogManager::class, __CLASS__);
$this->activated = true;
}

/**
Expand Down Expand Up @@ -141,7 +144,8 @@ protected function generatePageUrl(TypoScriptFrontendController $controller): st
public function __invoke(AfterCacheableContentIsGeneratedEvent $event): void
{
$this->request = $event->getRequest()->getAttribute('solr.pageIndexingInstructions');
if (!$this->request) {

if (!$this->request || $this->activated === false) {
return;
}
$this->setupConfiguration();
Expand Down Expand Up @@ -381,6 +385,7 @@ protected function getEventDispatcher(): EventDispatcherInterface
*/
public function deactivate(PageIndexerResponse $response): void
{
$this->activated = false;
$response->addActionResult($this->action, $this->responseData);
}
}
13 changes: 6 additions & 7 deletions Classes/IndexQueue/FrontendHelper/UserGroupDetector.php
Expand Up @@ -124,17 +124,13 @@ public function deactivateTcaFrontendGroupEnableFields(
* @param int $uid The page ID
* @param bool $disableGroupAccessCheck If set, the check for group access is disabled. VERY rarely used
* @param PageRepository $parentObject parent \TYPO3\CMS\Core\Domain\Repository\PageRepository object
*
* @noinspection PhpMissingReturnTypeInspection
*/
public function getPage_preProcess(
&$uid,
&$disableGroupAccessCheck,
PageRepository $parentObject
) {
): void {
$disableGroupAccessCheck = true;
// @todo: Check if reset "where_groupAccess" really wanted. Most probably the core aspect 'frontend.user' must be used instead.
$parentObject->where_groupAccess = ''; // just to be on the safe side
}

/**
Expand Down Expand Up @@ -190,7 +186,7 @@ protected function findFrontendGroups(array $record, string $table): void
if (isset($this->originalTca[$table]['ctrl']['enablecolumns']['fe_group'])) {
$frontendGroups = $record[$this->originalTca[$table]['ctrl']['enablecolumns']['fe_group']] ?? null;

if (empty($frontendGroups)) {
if (empty($frontendGroups) || $frontendGroups === '-1') {
// default = public access
$frontendGroups = 0;
} elseif ($this->request->getParameter('loggingEnabled')) {
Expand Down Expand Up @@ -222,7 +218,10 @@ protected function getFrontendGroups(): array

// clean up: filter double groups
$frontendGroups = array_unique($frontendGroups);
$frontendGroups = array_values($frontendGroups);
$frontendGroups = array_filter(
array_values($frontendGroups),
static fn (int $val): bool => ($val !== -1)
);

if (empty($frontendGroups)) {
// most likely an empty page with no content elements => public
Expand Down
18 changes: 8 additions & 10 deletions Classes/IndexQueue/PageIndexer.php
Expand Up @@ -59,16 +59,9 @@ public function index(Item $item): bool
return false;
}

$solrConnections = $this->getSolrConnectionsByItem($item);
foreach ($solrConnections as $systemLanguageUid => $solrConnection) {
$systemLanguageUids = array_keys($this->getSolrConnectionsByItem($item));
foreach ($systemLanguageUids as $systemLanguageUid) {
$contentAccessGroups = $this->getAccessGroupsFromContent($item, $systemLanguageUid);

if (empty($contentAccessGroups)) {
// might be an empty page w/no content elements or some TYPO3 error / bug
// FIXME logging needed
continue;
}

foreach ($contentAccessGroups as $userGroup) {
$this->indexPage($item, $systemLanguageUid, $userGroup);
}
Expand Down Expand Up @@ -299,6 +292,12 @@ protected function indexPage(Item $item, ?int $language = 0, ?int $userGroup = 0
$request->setIndexQueueItem($item);
$request->addAction('indexPage');
$request->setParameter('accessRootline', $accessRootline);
$request->setParameter('userGroup', $userGroup);

$feGroupColumn = $GLOBALS['TCA']['pages']['ctrl']['enablecolumns']['fe_group'] ?? '';
if (!empty($feGroupColumn)) {
$request->setParameter('pageUserGroup', $item->getRecord()[$feGroupColumn]);
}

$indexRequestUrl = $this->getDataUrl($item, $language);
$response = $request->send($indexRequestUrl);
Expand Down Expand Up @@ -329,7 +328,6 @@ protected function indexPage(Item $item, ?int $language = 0, ?int $userGroup = 0

if (empty($indexActionResult['pageIndexed'])) {
$message = 'Failed indexing page Index Queue item: ' . $item->getIndexQueueUid() . ' url: ' . $indexRequestUrl;

throw new \RuntimeException($message, 1331837081);
}

Expand Down
2 changes: 1 addition & 1 deletion Configuration/RequestMiddlewares.php
Expand Up @@ -4,7 +4,7 @@
$requestMiddlewares = [
'apache-solr-for-typo3/page-indexer-initialization' => [
'target' => \ApacheSolrForTypo3\Solr\Middleware\PageIndexerInitialization::class,
'before' => ['typo3/cms-frontend/tsfe'],
'before' => ['typo3/cms-frontend/tsfe', 'typo3/cms-frontend/authentication'],

This comment has been minimized.

Copy link
@galinei

galinei Nov 22, 2023

Is there a reason to move this middleware?

This change results into failing to execute the Page Indexer Request.
If you have a form on the page, you will get an error:
Core: Exception handler (WEB): Uncaught TYPO3 Exception: #1460975777: A front-end form protection may only be instantiated if there is an active front-end session. | TYPO3\CMS\Core\Error\Exception thrown in file /var/www/html/vendor/typo3/cms-core/Classes/FormProtection/FrontendFormProtection.php in line 92

This comment has been minimized.

Copy link
@dkd-kaehm

dkd-kaehm Nov 28, 2023

Collaborator

Yes, this was a part of the fix.
Please do not comment the commits, because it will be lost.
Create the issue with our template.

'after' => ['typo3/cms-core/normalized-params-attribute'],
],
];
Expand Down
@@ -0,0 +1,12 @@
"fe_groups",
,"uid","pid","title"
,1,1,"group 1"
"pages",
,"uid","pid","is_siteroot","doktype","slug","title","subtitle","crdate","tstamp","fe_group"
,2,1,0,1,"/protected_page","protected page","",1449151778,1449151778,1
"tt_content",
,"uid","pid","CType","header","fe_group"
,11,"2","header","public content of protected page",0
"tx_solr_indexqueue_item",
,"uid","root","item_type","item_uid","indexing_configuration","changed","indexed","has_indexing_properties","indexing_priority","indexed","errors"
,4711,1,"pages",2,"pages",1449151778,0,0,0,0,0
@@ -0,0 +1,17 @@
"fe_groups",
,"uid","pid","title"
,1,1,"group 1"
,2,1,"group 2"
"pages",
,"uid","pid","sys_language_uid","l10n_parent","is_siteroot","doktype","slug","title","subtitle","crdate","tstamp","fe_group",
,2,1,0,0,0,1,"/protected_page","protected page","",1449151778,1449151778,1
,3,1,1,2,0,1,"/protected_page_de","protected page de","",1449151778,1449151778,1
"tt_content",
,"uid","pid","sys_language_uid","l18n_parent","CType","header","fe_group","sorting"
,11,"2",0,0,"header","public content of protected page",0,10
,12,"2",1,11,"header","public content of protected page de",0,10
,13,"2",0,0,"header","protected content of protected page",2,20
,14,"2",1,13,"header","protected content of protected page de",2,20
"tx_solr_indexqueue_item",
,"uid","root","item_type","item_uid","indexing_configuration","changed","indexed","has_indexing_properties","indexing_priority","indexed","errors"
,4711,1,"pages",2,"pages",1449151778,0,0,0,0,0
@@ -0,0 +1,13 @@
"fe_groups",
,"uid","pid","title"
,1,1,"group 1"
"pages",
,"uid","pid","is_siteroot","doktype","slug","title","subtitle","crdate","tstamp","fe_group"
,2,1,0,1,"/protected_page","protected page","",1449151778,1449151778,0
"tt_content",
,"uid","pid","CType","header","fe_group","sorting"
,10,"2","header","protected ce",1,10
,11,"2","header","hide at login content",-1,20
"tx_solr_indexqueue_item",
,"uid","root","item_type","item_uid","indexing_configuration","changed","indexed","has_indexing_properties","indexing_priority","indexed","errors"
,4711,1,"pages",2,"pages",1449151778,0,0,0,0,0
@@ -0,0 +1,13 @@
"fe_groups",
,"uid","pid","title"
,1,1,"group 1"
"pages",
,"uid","pid","is_siteroot","doktype","slug","title","subtitle","crdate","tstamp","fe_group"
,2,1,0,1,"/protected_page","protected page","",1449151778,1449151778,0
"tt_content",
,"uid","pid","CType","header","fe_group","sorting"
,10,"2","header","protected ce",1,10
,11,"2","header","public ce",0,20
"tx_solr_indexqueue_item",
,"uid","root","item_type","item_uid","indexing_configuration","changed","indexed","has_indexing_properties","indexing_priority","indexed","errors"
,4711,1,"pages",2,"pages",1449151778,0,0,0,0,0
Expand Up @@ -17,10 +17,8 @@

namespace ApacheSolrForTypo3\Solr\Tests\Integration\IndexQueue\FrontendHelper;

use ApacheSolrForTypo3\Solr\IndexQueue\Item;
use ApacheSolrForTypo3\Solr\Tests\Integration\IntegrationTest;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\Page\CacheHashCalculator;
Expand Down Expand Up @@ -352,8 +350,7 @@ protected function indexQueuedPage(int $pageId = 1, string $siteLanguageBase = '
$url = rtrim($domain, '/') . '/' . ltrim($siteLanguageBase, '/') . '?' . $queryString;

// Now add the headers for item 4711 to the request
$connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('tx_solr_indexqueue_item');
$item = $connection->select(['*'], 'tx_solr_indexqueue_item', ['uid' => 4711])->fetchAssociative();
return $this->executePageIndexer($url, new Item($item));
$item = $this->getIndexQueueItem(4711);
return $this->executePageIndexer($url, $item);
}
}

0 comments on commit a6168bc

Please sign in to comment.