mirror of
https://github.com/silverstripe/silverstripe-cms
synced 2024-10-22 08:05:56 +02:00
Merge branch '3.6' into 3
This commit is contained in:
commit
a0bf0abe1b
@ -470,10 +470,6 @@ class CMSPageHistoryController extends CMSMain {
|
|||||||
"Version" => $fromVersion,
|
"Version" => $fromVersion,
|
||||||
));
|
));
|
||||||
|
|
||||||
foreach($form->Fields()->dataFields() as $field) {
|
|
||||||
$field->dontEscape = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,13 +106,23 @@ class RedirectorPage extends Page {
|
|||||||
public function onBeforeWrite() {
|
public function onBeforeWrite() {
|
||||||
parent::onBeforeWrite();
|
parent::onBeforeWrite();
|
||||||
|
|
||||||
// Prefix the URL with "http://" if no prefix is found
|
if ($this->ExternalURL && substr($this->ExternalURL, 0, 2) !== '//') {
|
||||||
if(
|
$urlParts = parse_url($this->ExternalURL);
|
||||||
$this->ExternalURL
|
if ($urlParts) {
|
||||||
&& !parse_url($this->ExternalURL, PHP_URL_SCHEME)
|
if (empty($urlParts['scheme'])) {
|
||||||
&& !preg_match('#^//#', $this->ExternalURL)
|
// no scheme, assume http
|
||||||
) {
|
$this->ExternalURL = 'http://' . $this->ExternalURL;
|
||||||
$this->ExternalURL = 'http://' . $this->ExternalURL;
|
} elseif (!in_array($urlParts['scheme'], array(
|
||||||
|
'http',
|
||||||
|
'https',
|
||||||
|
))) {
|
||||||
|
// we only allow http(s) urls
|
||||||
|
$this->ExternalURL = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// malformed URL to reject
|
||||||
|
$this->ExternalURL = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1158,10 +1158,11 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
* @param string $siteConfigMethod Method to call on {@link SiteConfig} for toplevel items, e.g. "canEdit"
|
* @param string $siteConfigMethod Method to call on {@link SiteConfig} for toplevel items, e.g. "canEdit"
|
||||||
* @param string $globalPermission If the member doesn't have this permission code, don't bother iterating deeper
|
* @param string $globalPermission If the member doesn't have this permission code, don't bother iterating deeper
|
||||||
* @param bool $useCached
|
* @param bool $useCached
|
||||||
|
* @param array $stages Which stages to check permissions against, defaults to both Stage and Live
|
||||||
* @return array An map of {@link SiteTree} ID keys to boolean values
|
* @return array An map of {@link SiteTree} ID keys to boolean values
|
||||||
*/
|
*/
|
||||||
public static function batch_permission_check($ids, $memberID, $typeField, $groupJoinTable, $siteConfigMethod,
|
public static function batch_permission_check($ids, $memberID, $typeField, $groupJoinTable, $siteConfigMethod,
|
||||||
$globalPermission = null, $useCached = true) {
|
$globalPermission = null, $useCached = true, $stages = array('Stage', 'Live')) {
|
||||||
if($globalPermission === NULL) $globalPermission = array('CMS_ACCESS_LeftAndMain', 'CMS_ACCESS_CMSMain');
|
if($globalPermission === NULL) $globalPermission = array('CMS_ACCESS_LeftAndMain', 'CMS_ACCESS_CMSMain');
|
||||||
|
|
||||||
// Sanitise the IDs
|
// Sanitise the IDs
|
||||||
@ -1169,7 +1170,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
|
|
||||||
// This is the name used on the permission cache
|
// This is the name used on the permission cache
|
||||||
// converts something like 'CanEditType' to 'edit'.
|
// converts something like 'CanEditType' to 'edit'.
|
||||||
$cacheKey = strtolower(substr($typeField, 3, -4)) . "-$memberID";
|
$cacheKey = strtolower(substr($typeField, 3, -4)) . "-$memberID" . implode('-', $stages);
|
||||||
|
|
||||||
// Default result: nothing editable
|
// Default result: nothing editable
|
||||||
$result = array_fill_keys($ids, false);
|
$result = array_fill_keys($ids, false);
|
||||||
@ -1206,7 +1207,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
|
|
||||||
$combinedStageResult = array();
|
$combinedStageResult = array();
|
||||||
|
|
||||||
foreach(array('Stage', 'Live') as $stage) {
|
foreach($stages as $stage) {
|
||||||
// Start by filling the array with the pages that actually exist
|
// Start by filling the array with the pages that actually exist
|
||||||
$table = ($stage=='Stage') ? "SiteTree" : "SiteTree_$stage";
|
$table = ($stage=='Stage') ? "SiteTree" : "SiteTree_$stage";
|
||||||
|
|
||||||
@ -1257,7 +1258,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($groupedByParent) {
|
if($groupedByParent) {
|
||||||
$actuallyInherited = self::batch_permission_check(array_keys($groupedByParent), $memberID, $typeField, $groupJoinTable, $siteConfigMethod);
|
$actuallyInherited = self::batch_permission_check(array_keys($groupedByParent), $memberID, $typeField, $groupJoinTable, $siteConfigMethod, $globalPermission, $useCached, array($stage));
|
||||||
if($actuallyInherited) {
|
if($actuallyInherited) {
|
||||||
$parentIDs = array_keys(array_filter($actuallyInherited));
|
$parentIDs = array_keys(array_filter($actuallyInherited));
|
||||||
foreach($parentIDs as $parentID) {
|
foreach($parentIDs as $parentID) {
|
||||||
|
@ -80,6 +80,17 @@ class RedirectorPageTest extends FunctionalTest {
|
|||||||
RedirectorPage_Controller::remove_extension('RedirectorPageTest_RedirectExtension');
|
RedirectorPage_Controller::remove_extension('RedirectorPageTest_RedirectExtension');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNoJSLinksAllowed()
|
||||||
|
{
|
||||||
|
$page = new RedirectorPage();
|
||||||
|
$js = 'javascript:alert("hello world")';
|
||||||
|
$page->ExternalURL = $js;
|
||||||
|
$this->assertEquals($js, $page->ExternalURL);
|
||||||
|
|
||||||
|
$page->write();
|
||||||
|
$this->assertEmpty($page->ExternalURL);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class RedirectorPageTest_RedirectExtension extends Extension implements TestOnly {
|
class RedirectorPageTest_RedirectExtension extends Extension implements TestOnly {
|
||||||
|
@ -446,4 +446,46 @@ class SiteTreePermissionsTest extends FunctionalTest {
|
|||||||
$this->assertFalse($page->canEdit($user), 'Website user can\'t edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to OnlyTheseUsers');
|
$this->assertFalse($page->canEdit($user), 'Website user can\'t edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to OnlyTheseUsers');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that flipping parent / child relationship on live doesn't
|
||||||
|
* cause infinite loop
|
||||||
|
*/
|
||||||
|
public function testMobiusHierarchy()
|
||||||
|
{
|
||||||
|
// login as admin to be able to publish
|
||||||
|
$adminID = $this->logInWithPermission('ADMIN');
|
||||||
|
|
||||||
|
$parentPage = new Page();
|
||||||
|
$parentPage->Title = 'Parent Page';
|
||||||
|
$parentPage->doPublish();
|
||||||
|
|
||||||
|
$childPage = new Page();
|
||||||
|
$childPage->Title = 'Child Page';
|
||||||
|
$childPage->ParentID = $parentPage->ID;
|
||||||
|
$childPage->doPublish();
|
||||||
|
|
||||||
|
//flip parent/child relation
|
||||||
|
$childPage->ParentID = 0;
|
||||||
|
$childPage->write();
|
||||||
|
|
||||||
|
$parentPage->ParentID = $childPage->ID;
|
||||||
|
$parentPage->write();
|
||||||
|
|
||||||
|
$this->assertTrue($childPage->isPublished());
|
||||||
|
$this->assertTrue($parentPage->isPublished());
|
||||||
|
|
||||||
|
$result = SiteTree::batch_permission_check(array(
|
||||||
|
$parentPage->ID,
|
||||||
|
$childPage->ID,
|
||||||
|
), $adminID, 'CanEditType', 'SiteTree_EditorGroups', 'canEditPages');
|
||||||
|
|
||||||
|
$this->assertArrayHasKey($childPage->ID, $result);
|
||||||
|
$this->assertArrayHasKey($parentPage->ID, $result);
|
||||||
|
|
||||||
|
// mr potato head can't edit
|
||||||
|
$this->assertTrue($result[$parentPage->ID]);
|
||||||
|
$this->assertTrue($result[$childPage->ID]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user