mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API CHANGE Changed SiteTree->Viewers to SiteTree->CanViewType, Changed SiteTree->Editors to SiteTree->CanEditType (see #2847)
API CHANGE Changed SiteTree->ViewersGroup has_one relationship to SiteTree->ViewerGroups has_many relationship (see #2847) API CHANGE Changed SiteTree->EditorsGroup has_one relationship to SiteTree->EditorGroups has_many relationship (see #2847) ENHANCEMENT Added 'Inherit' flag to SiteTree->CanViewType and SiteTree->CanEditType (see #2419) ENHANCEMENT Added unit tests for SiteTree permissions BUGFIX Checking recursively for permissions on children with SiteTree->canDelete() BUGFIX Disallow SiteTree->canEdit() if SiteTree->canView() is not granted Note: Use dev/tasks/UpgradeSiteTreePermissionSchemaTask/run to migrate legacy data to the new schema as outlined above git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@65150 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
ab3ef0196d
commit
ca6d92341e
@ -80,10 +80,8 @@ class SiteTree extends DataObject {
|
|||||||
"ReportClass" => "Varchar",
|
"ReportClass" => "Varchar",
|
||||||
"Priority" => "Float",
|
"Priority" => "Float",
|
||||||
|
|
||||||
"Viewers" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers', 'Anyone')",
|
"CanViewType" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers, Inherit', 'Anyone')",
|
||||||
"Editors" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
|
"CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers, Inherit', 'LoggedInUsers')",
|
||||||
"ViewersGroup" => "Int",
|
|
||||||
"EditorsGroup" => "Int",
|
|
||||||
|
|
||||||
// Simple task tracking
|
// Simple task tracking
|
||||||
"ToDo" => "Text",
|
"ToDo" => "Text",
|
||||||
@ -101,7 +99,9 @@ class SiteTree extends DataObject {
|
|||||||
|
|
||||||
static $many_many = array(
|
static $many_many = array(
|
||||||
"LinkTracking" => "SiteTree",
|
"LinkTracking" => "SiteTree",
|
||||||
"ImageTracking" => "File"
|
"ImageTracking" => "File",
|
||||||
|
"ViewerGroups" => "Group",
|
||||||
|
"EditorGroups" => "Group",
|
||||||
);
|
);
|
||||||
|
|
||||||
static $belongs_many_many = array(
|
static $belongs_many_many = array(
|
||||||
@ -123,9 +123,8 @@ class SiteTree extends DataObject {
|
|||||||
"ShowInMenus" => 1,
|
"ShowInMenus" => 1,
|
||||||
"ShowInSearch" => 1,
|
"ShowInSearch" => 1,
|
||||||
"Status" => "New page",
|
"Status" => "New page",
|
||||||
"CanCreateChildren" => array(10),
|
"CanViewType" => "Anyone",
|
||||||
"Viewers" => "Anyone",
|
"CanEditType" => "LoggedInUsers"
|
||||||
"Editors" => "LoggedInUsers"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
static $has_one = array(
|
static $has_one = array(
|
||||||
@ -545,11 +544,18 @@ class SiteTree extends DataObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should return true if the current user can add children
|
* This function should return true if the current user can add children
|
||||||
* to this page.
|
* to this page. It can be overloaded to customise the security model for an
|
||||||
*
|
|
||||||
* It can be overloaded to customise the security model for an
|
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
|
* - alternateCanAddChildren() on a decorator returns FALSE
|
||||||
|
* - canEdit() is not granted
|
||||||
|
* - There are no classes defined in {@link $allowed_children}
|
||||||
|
*
|
||||||
|
* @uses alternateCanAddChildren()
|
||||||
|
* @uses canEdit()
|
||||||
|
* @uses $allowed_children
|
||||||
|
*
|
||||||
* @return boolean True if the current user can add children.
|
* @return boolean True if the current user can add children.
|
||||||
*/
|
*/
|
||||||
public function canAddChildren($member = null) {
|
public function canAddChildren($member = null) {
|
||||||
@ -570,77 +576,116 @@ class SiteTree extends DataObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should return true if the current user can view this
|
* This function should return true if the current user can view this
|
||||||
* page.
|
* page. It can be overloaded to customise the security model for an
|
||||||
*
|
|
||||||
* It can be overloaded to customise the security model for an
|
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
|
* - alternateCanView() on any decorator returns FALSE
|
||||||
|
* - "CanViewType" directive is set to "Inherit" and any parent page return false for canView()
|
||||||
|
* - "CanViewType" directive is set to "LoggedInUsers" and no user is logged in
|
||||||
|
* - "CanViewType" directive is set to "OnlyTheseUsers" and user is not in the given groups
|
||||||
|
*
|
||||||
|
* @uses alternateCanView()
|
||||||
|
* @uses ViewerGroups()
|
||||||
|
*
|
||||||
* @return boolean True if the current user can view this page.
|
* @return boolean True if the current user can view this page.
|
||||||
*/
|
*/
|
||||||
public function canView($member = null) {
|
public function canView($member = null) {
|
||||||
if(!isset($member)) {
|
if(!isset($member)) $member = Member::currentUser();
|
||||||
$member = Member::currentUser();
|
|
||||||
}
|
|
||||||
if($member && $member->isAdmin()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// admin override
|
||||||
|
if($member && $member->isAdmin()) return true;
|
||||||
|
|
||||||
|
// decorated access checks
|
||||||
$args = array($member, true);
|
$args = array($member, true);
|
||||||
$this->extend('alternateCanView', $args);
|
$this->extend('alternateCanView', $args);
|
||||||
if($args[1] == false) return false;
|
if($args[1] == false) return false;
|
||||||
|
|
||||||
if(((!$this->Viewers) || ($this->Viewers == 'Anyone') ||
|
// check for empty spec
|
||||||
($this->Viewers == 'LoggedInUsers' && $member) ||
|
if(
|
||||||
($this->Viewers == 'OnlyTheseUsers' && $member &&
|
!$this->CanViewType || $this->CanViewType == 'Anyone'
|
||||||
$member->inGroup($this->ViewersGroup))) == false)
|
) return true;
|
||||||
return false;
|
|
||||||
return true;
|
// check for inherit
|
||||||
|
if(
|
||||||
|
$this->CanViewType == 'Inherit' && $this->Parent()
|
||||||
|
) return $this->Parent()->canView($member);
|
||||||
|
|
||||||
|
// check for any logged-in users
|
||||||
|
if(
|
||||||
|
$this->CanViewType == 'LoggedInUsers'
|
||||||
|
&& Member::currentUser()
|
||||||
|
) return true;
|
||||||
|
|
||||||
|
// check for specific groups
|
||||||
|
if(
|
||||||
|
$this->CanViewType == 'OnlyTheseUsers'
|
||||||
|
&& $member
|
||||||
|
&& $member->inGroups($this->ViewerGroups())
|
||||||
|
) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should return true if the current user can delete this
|
* This function should return true if the current user can delete this
|
||||||
* page.
|
* page. It can be overloaded to customise the security model for an
|
||||||
*
|
|
||||||
* It can be overloaded to customise the security model for an
|
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
|
* - alternateCanDelete() returns FALSE on any decorator
|
||||||
|
* - canEdit() returns FALSE
|
||||||
|
* - any descendant page returns FALSE for canDelete()
|
||||||
|
*
|
||||||
|
* @todo Check if all children can be deleted as well
|
||||||
|
* @uses alternateCanDelete()
|
||||||
|
* @uses canEdit()
|
||||||
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return boolean True if the current user can delete this page.
|
* @return boolean True if the current user can delete this page.
|
||||||
*/
|
*/
|
||||||
public function canDelete($member = null) {
|
public function canDelete($member = null) {
|
||||||
if(!isset($member)) {
|
if(!isset($member)) $member = Member::currentUser();
|
||||||
$member = Member::currentUser();
|
|
||||||
}
|
if($member && $member->isAdmin()) return true;
|
||||||
if($member && $member->isAdmin()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$args = array($member, true);
|
$args = array($member, true);
|
||||||
$this->extend('alternateCanDelete', $args);
|
$this->extend('alternateCanDelete', $args);
|
||||||
if($args[1] == false) return false;
|
if($args[1] == false) return false;
|
||||||
|
|
||||||
|
// if page can't be edited, don't grant delete permissions
|
||||||
|
if(!$this->canEdit()) return false;
|
||||||
|
|
||||||
|
$children = $this->AllChildren();
|
||||||
|
if($children) foreach($children as $child) {
|
||||||
|
if(!$child->canDelete()) return false;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->stat('can_create') != false;
|
return $this->stat('can_create') != false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should return true if the current user can create new
|
* This function should return true if the current user can create new
|
||||||
* pages of this class.
|
* pages of this class. It can be overloaded to customise the security model for an
|
||||||
*
|
|
||||||
* It can be overloaded to customise the security model for an
|
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
|
* - alternateCanCreate() returns FALSE on any decorator
|
||||||
|
* - $can_create is set to FALSE and the site is not in "dev mode"
|
||||||
|
*
|
||||||
|
* Use {@link canAddChildren()} to control behaviour of creating children under this page.
|
||||||
|
*
|
||||||
|
* @uses alternateCanCreate()
|
||||||
|
* @uses $can_create
|
||||||
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return boolean True if the current user can create pages on this
|
* @return boolean True if the current user can create pages on this class.
|
||||||
* class.
|
|
||||||
*/
|
*/
|
||||||
public function canCreate($member = null) {
|
public function canCreate($member = null) {
|
||||||
if(!isset($member)) {
|
if(!isset($member)) $member = Member::currentUser();
|
||||||
$member = Member::currentUser();
|
|
||||||
}
|
if($member && $member->isAdmin()) return true;
|
||||||
if($member && $member->isAdmin()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$args = array($member, true);
|
$args = array($member, true);
|
||||||
$this->extend('alternateCanCreate', $args);
|
$this->extend('alternateCanCreate', $args);
|
||||||
@ -652,52 +697,81 @@ class SiteTree extends DataObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should return true if the current user can edit this
|
* This function should return true if the current user can edit this
|
||||||
* page.
|
* page. It can be overloaded to customise the security model for an
|
||||||
*
|
|
||||||
* It can be overloaded to customise the security model for an
|
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
|
* - alternateCanEdit() on any decorator returns FALSE
|
||||||
|
* - canView() return false
|
||||||
|
* - "CanEditType" directive is set to "Inherit" and any parent page return false for canEdit()
|
||||||
|
* - "CanEditType" directive is set to "LoggedInUsers" and no user is logged in or doesn't have the CMS_Access_CMSMAIN permission code
|
||||||
|
* - "CanEditType" directive is set to "OnlyTheseUsers" and user is not in the given groups
|
||||||
|
*
|
||||||
|
* @uses alternateCanEdit()
|
||||||
|
* @uses canView()
|
||||||
|
* @uses EditorGroups()
|
||||||
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return boolean True if the current user can edit this page.
|
* @return boolean True if the current user can edit this page.
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = null) {
|
public function canEdit($member = null) {
|
||||||
if(!isset($member)) {
|
if(!isset($member)) $member = Member::currentUser();
|
||||||
$member = Member::currentUser();
|
|
||||||
}
|
|
||||||
if($member && $member->isAdmin()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// admin override
|
||||||
|
if($member && $member->isAdmin()) return true;
|
||||||
|
|
||||||
|
// decorated access checks
|
||||||
$args = array($member, true);
|
$args = array($member, true);
|
||||||
$this->extend('alternateCanEdit', $args);
|
$this->extend('alternateCanEdit', $args);
|
||||||
if($args[1] == false) return false;
|
if($args[1] == false) return false;
|
||||||
|
|
||||||
if((Permission::check('CMS_ACCESS_CMSMain') &&
|
// if page can't be viewed, don't grant edit permissions
|
||||||
(($this->Editors == 'LoggedInUsers' && $member) ||
|
if(!$this->canView()) return false;
|
||||||
($this->Editors == 'OnlyTheseUsers' && $member &&
|
|
||||||
$member->inGroup($this->EditorsGroup)))) == false)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
// check for empty spec
|
||||||
|
if(
|
||||||
|
!$this->CanEditType || $this->CanEditType == 'Anyone'
|
||||||
|
) return true;
|
||||||
|
|
||||||
|
// check for inherit
|
||||||
|
if(
|
||||||
|
$this->CanEditType == 'Inherit' && $this->Parent()
|
||||||
|
) return $this->Parent()->canEdit($member);
|
||||||
|
|
||||||
|
// check for any logged-in users
|
||||||
|
if(
|
||||||
|
$this->CanEditType == 'LoggedInUsers'
|
||||||
|
&& Permission::checkMember($member, 'CMS_ACCESS_CMSMain')
|
||||||
|
) return true;
|
||||||
|
|
||||||
|
// check for specific groups
|
||||||
|
if(
|
||||||
|
$this->CanEditType == 'OnlyTheseUsers'
|
||||||
|
&& $member
|
||||||
|
&& $member->inGroups($this->EditorGroups())
|
||||||
|
) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should return true if the current user can publish this
|
* This function should return true if the current user can publish this
|
||||||
* page.
|
* page. It can be overloaded to customise the security model for an
|
||||||
*
|
|
||||||
* It can be overloaded to customise the security model for an
|
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
|
* - alternateCanPublish() on any decorator returns FALSE
|
||||||
|
* - canEdit() returns FALSE
|
||||||
|
*
|
||||||
|
* @uses alternateCanPublish()
|
||||||
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return boolean True if the current user can publish this page.
|
* @return boolean True if the current user can publish this page.
|
||||||
*/
|
*/
|
||||||
public function canPublish($member = null) {
|
public function canPublish($member = null) {
|
||||||
if(!isset($member)) {
|
if(!isset($member)) $member = Member::currentUser();
|
||||||
$member = Member::currentUser();
|
|
||||||
}
|
if($member && $member->isAdmin()) return true;
|
||||||
if($member && $member->isAdmin()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$args = array($member, true);
|
$args = array($member, true);
|
||||||
$this->extend('alternateCanPublish', $args);
|
$this->extend('alternateCanPublish', $args);
|
||||||
@ -1146,32 +1220,36 @@ class SiteTree extends DataObject {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
$tabAccess = new Tab('Access',
|
$tabAccess = new Tab('Access',
|
||||||
new HeaderField('WhoCanViewHeader',_t('SiteTree.ACCESSHEADER', "Who can view this page on my site?"), 2),
|
new HeaderField('WhoCanViewHeader',_t('SiteTree.ACCESSHEADER', "Who can view this page?"), 2),
|
||||||
new OptionsetField(
|
$viewersOptionsField = new OptionsetField(
|
||||||
"Viewers",
|
"CanViewType",
|
||||||
"",
|
""
|
||||||
array(
|
|
||||||
"Anyone" => _t('SiteTree.ACCESSANYONE', "Anyone"),
|
|
||||||
"LoggedInUsers" => _t('SiteTree.ACCESSLOGGEDIN', "Logged-in users"),
|
|
||||||
"OnlyTheseUsers" => _t('SiteTree.ACCESSONLYTHESE', "Only these people (choose from list)")
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
new DropdownField("ViewersGroup", $this->fieldLabel('ViewersGroup'), Group::map()),
|
new TreeMultiselectField("ViewerGroups", $this->fieldLabel('ViewerGroups')),
|
||||||
new HeaderField('WhoCanEditHeader',_t('SiteTree.EDITHEADER', "Who can edit this inside the CMS?"), 2),
|
new HeaderField('WhoCanEditHeader',_t('SiteTree.EDITHEADER', "Who can edit this page?"), 2),
|
||||||
new OptionsetField(
|
$editorsOptionsField = new OptionsetField(
|
||||||
"Editors",
|
"CanEditType",
|
||||||
"",
|
""
|
||||||
array(
|
|
||||||
"LoggedInUsers" => _t('SiteTree.EDITANYONE', "Anyone who can log-in to the CMS"),
|
|
||||||
"OnlyTheseUsers" => _t('SiteTree.EDITONLYTHESE', "Only these people (choose from list)")
|
|
||||||
)
|
|
||||||
),
|
),
|
||||||
new DropdownField("EditorsGroup", $this->fieldLabel('EditorsGroup'), Group::map())
|
new TreeMultiselectField("EditorGroups", $this->fieldLabel('EditorGroups'))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
//new NamedLabelField("Status", $message, "pageStatusMessage", true)
|
//new NamedLabelField("Status", $message, "pageStatusMessage", true)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$viewersOptionsSource = array();
|
||||||
|
if($this->Parent()->ID) $viewersOptionsSource["Inherit"] = _t('SiteTree.INHERIT', "Inherit from parent page");
|
||||||
|
$viewersOptionsSource["Anyone"] = _t('SiteTree.ACCESSANYONE', "Anyone");
|
||||||
|
$viewersOptionsSource["LoggedInUsers"] = _t('SiteTree.ACCESSLOGGEDIN', "Logged-in users");
|
||||||
|
$viewersOptionsSource["OnlyTheseUsers"] = _t('SiteTree.ACCESSONLYTHESE', "Only these people (choose from list)");
|
||||||
|
$viewersOptionsField->setSource($viewersOptionsSource);
|
||||||
|
|
||||||
|
$editorsOptionsSource = array();
|
||||||
|
if($this->Parent()->ID) $editorsOptionsSource["Inherit"] = _t('SiteTree.INHERIT', "Inherit from parent page");
|
||||||
|
$editorsOptionsSource["LoggedInUsers"] = _t('SiteTree.EDITANYONE', "Anyone who can log-in to the CMS");
|
||||||
|
$editorsOptionsSource["OnlyTheseUsers"] = _t('SiteTree.EDITONLYTHESE', "Only these people (choose from list)");
|
||||||
|
$editorsOptionsField->setSource($editorsOptionsSource);
|
||||||
|
|
||||||
$tabContent->setTitle(_t('SiteTree.TABCONTENT', "Content"));
|
$tabContent->setTitle(_t('SiteTree.TABCONTENT', "Content"));
|
||||||
$tabMain->setTitle(_t('SiteTree.TABMAIN', "Main"));
|
$tabMain->setTitle(_t('SiteTree.TABMAIN', "Main"));
|
||||||
$tabMeta->setTitle(_t('SiteTree.TABMETA', "Meta-data"));
|
$tabMeta->setTitle(_t('SiteTree.TABMETA', "Meta-data"));
|
||||||
@ -1205,8 +1283,8 @@ class SiteTree extends DataObject {
|
|||||||
$labels['URLSegment'] = _t('SiteTree.URLSegment', 'URL Segment', PR_MEDIUM, 'URL for this page');
|
$labels['URLSegment'] = _t('SiteTree.URLSegment', 'URL Segment', PR_MEDIUM, 'URL for this page');
|
||||||
$labels['Content'] = _t('SiteTree.Content', 'Content', PR_MEDIUM, 'Main HTML Content for a page');
|
$labels['Content'] = _t('SiteTree.Content', 'Content', PR_MEDIUM, 'Main HTML Content for a page');
|
||||||
$labels['HomepageForDomain'] = _t('SiteTree.HomepageForDomain', 'Hompage for this domain');
|
$labels['HomepageForDomain'] = _t('SiteTree.HomepageForDomain', 'Hompage for this domain');
|
||||||
$labels['Viewers'] = _t('SiteTree.Viewers', 'Viewers Group');
|
$labels['CanViewType'] = _t('SiteTree.Viewers', 'Viewers Groups');
|
||||||
$labels['Editors'] = _t('SiteTree.Editors', 'Editors Group');
|
$labels['CanEditType'] = _t('SiteTree.Editors', 'Editors Groups');
|
||||||
$labels['ToDo'] = _t('SiteTree.ToDo', 'Todo Notes');
|
$labels['ToDo'] = _t('SiteTree.ToDo', 'Todo Notes');
|
||||||
$labels['Parent'] = _t('SiteTree.has_one_Parent', 'Parent Page', PR_MEDIUM, 'The parent page in the site hierarchy');
|
$labels['Parent'] = _t('SiteTree.has_one_Parent', 'Parent Page', PR_MEDIUM, 'The parent page in the site hierarchy');
|
||||||
$labels['Comments'] = _t('SiteTree.Comments', 'Comments');
|
$labels['Comments'] = _t('SiteTree.Comments', 'Comments');
|
||||||
|
159
tests/SiteTreePermissionsTest.php
Normal file
159
tests/SiteTreePermissionsTest.php
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package sapphire
|
||||||
|
* @subpackage tests
|
||||||
|
*
|
||||||
|
* @todo Test canAddChildren()
|
||||||
|
* @todo Test canCreate()
|
||||||
|
*/
|
||||||
|
class SiteTreePermissionsTest extends SapphireTest {
|
||||||
|
static $fixture_file = "sapphire/tests/SiteTreePermissionsTest.yml";
|
||||||
|
|
||||||
|
function testRestrictedViewLoggedInUsers() {
|
||||||
|
$page = $this->objFromFixture('Page', 'restrictedViewLoggedInUsers');
|
||||||
|
|
||||||
|
$randomUnauthedMember = new Member();
|
||||||
|
$randomUnauthedMember->ID = 99;
|
||||||
|
$this->assertFalse(
|
||||||
|
$page->canView($randomUnauthedMember),
|
||||||
|
'Unauthenticated members cant view a page marked as "Viewable for any logged in users"'
|
||||||
|
);
|
||||||
|
|
||||||
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
|
$websiteuser->logIn();
|
||||||
|
$this->assertTrue(
|
||||||
|
$page->canView($websiteuser),
|
||||||
|
'Authenticated members can view a page marked as "Viewable for any logged in users" even if they dont have access to the CMS'
|
||||||
|
);
|
||||||
|
|
||||||
|
$websiteuser->logOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRestrictedViewOnlyTheseUsers() {
|
||||||
|
$page = $this->objFromFixture('Page', 'restrictedViewOnlyWebsiteUsers');
|
||||||
|
|
||||||
|
$randomUnauthedMember = new Member();
|
||||||
|
$randomUnauthedMember->ID = 99;
|
||||||
|
$this->assertFalse(
|
||||||
|
$page->canView($randomUnauthedMember),
|
||||||
|
'Unauthenticated members cant view a page marked as "Viewable by these groups"'
|
||||||
|
);
|
||||||
|
|
||||||
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
|
$this->assertFalse(
|
||||||
|
$page->canView($subadminuser),
|
||||||
|
'Authenticated members cant view a page marked as "Viewable by these groups" if theyre not in the listed groups'
|
||||||
|
);
|
||||||
|
|
||||||
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
|
$this->assertTrue(
|
||||||
|
$page->canView($websiteuser),
|
||||||
|
'Authenticated members can view a page marked as "Viewable by these groups" if theyre in the listed groups'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRestrictedEditLoggedInUsers() {
|
||||||
|
$page = $this->objFromFixture('Page', 'restrictedEditLoggedInUsers');
|
||||||
|
|
||||||
|
$randomUnauthedMember = new Member();
|
||||||
|
$randomUnauthedMember->ID = 99;
|
||||||
|
$this->assertFalse(
|
||||||
|
$page->canEdit($randomUnauthedMember),
|
||||||
|
'Unauthenticated members cant edit a page marked as "Editable by logged in users"'
|
||||||
|
);
|
||||||
|
|
||||||
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
|
$websiteuser->logIn();
|
||||||
|
$this->assertFalse(
|
||||||
|
$page->canEdit($websiteuser),
|
||||||
|
'Authenticated members cant edit a page marked as "Editable by logged in users" if they dont have cms permissions'
|
||||||
|
);
|
||||||
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
|
$this->assertTrue(
|
||||||
|
$page->canEdit($subadminuser),
|
||||||
|
'Authenticated members can edit a page marked as "Editable by logged in users" if they have cms permissions and belong to any of these groups'
|
||||||
|
);
|
||||||
|
|
||||||
|
$websiteuser->logOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRestrictedEditOnlySubadminGroup() {
|
||||||
|
$page = $this->objFromFixture('Page', 'restrictedEditOnlySubadminGroup');
|
||||||
|
|
||||||
|
$randomUnauthedMember = new Member();
|
||||||
|
$randomUnauthedMember->ID = 99;
|
||||||
|
$this->assertFalse(
|
||||||
|
$page->canEdit($randomUnauthedMember),
|
||||||
|
'Unauthenticated members cant edit a page marked as "Editable by these groups"'
|
||||||
|
);
|
||||||
|
|
||||||
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
|
$this->assertTrue(
|
||||||
|
$page->canEdit($subadminuser),
|
||||||
|
'Authenticated members can view a page marked as "Editable by these groups" if theyre in the listed groups'
|
||||||
|
);
|
||||||
|
|
||||||
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
|
$websiteuser->logIn();
|
||||||
|
$this->assertFalse(
|
||||||
|
$page->canEdit($websiteuser),
|
||||||
|
'Authenticated members cant edit a page marked as "Editable by these groups" if theyre not in the listed groups'
|
||||||
|
);
|
||||||
|
|
||||||
|
$websiteuser->logOut();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRestrictedViewInheritance() {
|
||||||
|
$parentPage = $this->objFromFixture('Page', 'parent_restrictedViewOnlySubadminGroup');
|
||||||
|
$childPage = $this->objFromFixture('Page', 'child_restrictedViewOnlySubadminGroup');
|
||||||
|
|
||||||
|
$randomUnauthedMember = new Member();
|
||||||
|
$randomUnauthedMember->ID = 99;
|
||||||
|
$this->assertFalse(
|
||||||
|
$childPage->canView($randomUnauthedMember),
|
||||||
|
'Unauthenticated members cant view a page marked as "Viewable by these groups" by inherited permission'
|
||||||
|
);
|
||||||
|
|
||||||
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
|
$this->assertTrue(
|
||||||
|
$childPage->canView($subadminuser),
|
||||||
|
'Authenticated members can view a page marked as "Viewable by these groups" if theyre in the listed groups by inherited permission'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRestrictedEditInheritance() {
|
||||||
|
$parentPage = $this->objFromFixture('Page', 'parent_restrictedEditOnlySubadminGroup');
|
||||||
|
$childPage = $this->objFromFixture('Page', 'child_restrictedEditOnlySubadminGroup');
|
||||||
|
|
||||||
|
$randomUnauthedMember = new Member();
|
||||||
|
$randomUnauthedMember->ID = 99;
|
||||||
|
$this->assertFalse(
|
||||||
|
$childPage->canEdit($randomUnauthedMember),
|
||||||
|
'Unauthenticated members cant edit a page marked as "Editable by these groups" by inherited permission'
|
||||||
|
);
|
||||||
|
|
||||||
|
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||||
|
$this->assertTrue(
|
||||||
|
$childPage->canEdit($subadminuser),
|
||||||
|
'Authenticated members can edit a page marked as "Editable by these groups" if theyre in the listed groups by inherited permission'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testDeleteRestrictedChild() {
|
||||||
|
$parentPage = $this->objFromFixture('Page', 'deleteTestParentPage');
|
||||||
|
$childPage = $this->objFromFixture('Page', 'deleteTestChildPage');
|
||||||
|
|
||||||
|
$randomUnauthedMember = new Member();
|
||||||
|
$randomUnauthedMember->ID = 99;
|
||||||
|
$this->assertFalse(
|
||||||
|
$parentPage->canDelete($randomUnauthedMember),
|
||||||
|
'Unauthenticated members cant delete a page if it doesnt have delete permissions on any of its descendants'
|
||||||
|
);
|
||||||
|
$this->assertFalse(
|
||||||
|
$childPage->canDelete($randomUnauthedMember),
|
||||||
|
'Unauthenticated members cant delete a child page marked as "Editable by these groups"'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
60
tests/SiteTreePermissionsTest.yml
Normal file
60
tests/SiteTreePermissionsTest.yml
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
Permission:
|
||||||
|
cmsmain1:
|
||||||
|
Code: CMS_ACCESS_CMSMain
|
||||||
|
cmsmain2:
|
||||||
|
Code: CMS_ACCESS_CMSMain
|
||||||
|
Group:
|
||||||
|
subadmingroup:
|
||||||
|
Title: Create, edit and delete pages
|
||||||
|
Code: subadmingroup
|
||||||
|
Permissions: =>Permission.cmsmain1
|
||||||
|
editorgroup:
|
||||||
|
Title: Edit existing pages
|
||||||
|
Code: editorgroup
|
||||||
|
Permissions: =>Permission.cmsmain2
|
||||||
|
websiteusers:
|
||||||
|
Title: View certain restricted pages
|
||||||
|
Member:
|
||||||
|
subadmin:
|
||||||
|
Email: subadmin@test.com
|
||||||
|
Password: test
|
||||||
|
Groups: =>Group.subadmingroup
|
||||||
|
editor:
|
||||||
|
Email: editor@test.com
|
||||||
|
Password: test
|
||||||
|
Groups: =>Group.editorgroup
|
||||||
|
websiteuser:
|
||||||
|
Email: websiteuser@test.com
|
||||||
|
Password: test
|
||||||
|
Groups: =>Group.websiteusers
|
||||||
|
Page:
|
||||||
|
restrictedViewLoggedInUsers:
|
||||||
|
CanViewType: LoggedInUsers
|
||||||
|
restrictedViewOnlyWebsiteUsers:
|
||||||
|
CanViewType: OnlyTheseUsers
|
||||||
|
ViewerGroups: =>Group.websiteusers
|
||||||
|
restrictedViewOnlySubadminGroup:
|
||||||
|
CanViewType: OnlyTheseUsers
|
||||||
|
ViewerGroups: =>Group.subadmingroup
|
||||||
|
restrictedEditLoggedInUsers:
|
||||||
|
CanEditType: LoggedInUsers
|
||||||
|
restrictedEditOnlySubadminGroup:
|
||||||
|
CanEditType: OnlyTheseUsers
|
||||||
|
EditorGroups: =>Group.subadmingroup
|
||||||
|
parent_restrictedViewOnlySubadminGroup:
|
||||||
|
CanViewType: OnlyTheseUsers
|
||||||
|
ViewerGroups: =>Group.subadmingroup
|
||||||
|
child_restrictedViewOnlySubadminGroup:
|
||||||
|
CanViewType: Inherit
|
||||||
|
Parent: =>Page.parent_restrictedViewOnlySubadminGroup
|
||||||
|
parent_restrictedEditOnlySubadminGroup:
|
||||||
|
CanEditType: OnlyTheseUsers
|
||||||
|
EditorGroups: =>Group.subadmingroup
|
||||||
|
child_restrictedEditOnlySubadminGroup:
|
||||||
|
CanEditType: Inherit
|
||||||
|
Parent: =>Page.parent_restrictedEditOnlySubadminGroup
|
||||||
|
deleteTestParentPage:
|
||||||
|
CanEditType: Inherit
|
||||||
|
deleteTestChildPage:
|
||||||
|
CanEditType: OnlyTheseUsers
|
||||||
|
EditorGroups: =>Group.subadmingroup
|
Loading…
Reference in New Issue
Block a user