Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TreeDropdownField in SiteConfig CMS fields can cause unexpected subsite switching #477

Open
samthejarvis opened this issue Mar 25, 2022 · 1 comment

Comments

@samthejarvis
Copy link

samthejarvis commented Mar 25, 2022

When loading child pages in a TreeDropdownField with an ID that matches any SiteConfig ID associated with a subsite, the user is automatically switched back to this subsite when loading other subsite's /admin/settings.

Example:
Load the child pages for a page with ID 8 via a TreeDropdownField named PageID.

This fetches: https://localhost/admin/settings/EditForm/field/PageID/tree?**ID=8**&format=json
In this request the session variable SilverStripe\SiteConfig\SiteConfigLeftAndMain is set to {currentPage: 8} (not expected).

From now on, the following code runs on all actions under /admin/settings:

$record = $this->owner->currentPage();
if ($record
&& isset($record->SubsiteID, $this->owner->urlParams['ID'])
&& is_numeric($record->SubsiteID)
&& $this->shouldChangeSubsite(
get_class($this->owner),
$record->SubsiteID,
SubsiteState::singleton()->getSubsiteId()
)
) {
// Update current subsite
$canViewElsewhere = SubsiteState::singleton()->withState(function ($newState) use ($record) {
$newState->setSubsiteId($record->SubsiteID);
return (bool) $this->owner->canView(Security::getCurrentUser());
});
if ($canViewElsewhere) {
// Redirect to clear the current page
return $this->owner->redirect(
Controller::join_links($this->owner->Link('show'), $record->ID, '?SubsiteID=' . $record->SubsiteID)
);
}
// Redirect to the default CMS section
return $this->owner->redirect(AdminRootController::config()->get('url_base') . '/');
}

In this case, $record is now the Subsite that relates to SiteConfig#8. It's ID is 3 in this case.

As the currentPage is the ID of an existing SiteConfig and matches that of a subsite, the current subsite ID is set to the subsite for SiteConfig#8 via a redirect to ?SubsiteID=3.

From now on, accessing /admin/settings on other subsites automatically switches you back to this subsite (if it includes any components that generate requests like TreeDropdownField's tree action GridFieldFilterHeader SearchForm action etc.). Effectively the user can no longer access /admin/settings/ on other subsites.

Clearing the erroneous SiteConfigLeftAndMain entry from the session stops this behaviour.

While the impact is on subsites functionality, the cause is likely in core (to confirm) (the SiteConfigLeftAndMain currentPage session variable should not be set by the above request).

@samthejarvis
Copy link
Author

samthejarvis commented Mar 27, 2022

Root of the issue seems to be that LeftAndMain::currentPageID() assumes any ID request var is the current page ID. This means that for the the TreeDropdownField tree request, LeftAndMain::currentPage() returns a SiteConfig of the ID of the current page requested in the TreeDropdownField. This allows the snippet above to run which switches the current subsite.

A quick fix is to just add an is_int($this->owner->urlParams['ID']) to the condition in the snippet above, as $this->owner->urlParams['ID'] is equal to 'field' in the above request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants