mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
API CHANGE: Moved site tree permission extension to a 3-state system (true, false, null, where null means "no effect") (from r104669)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@112363 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
7164c91de8
commit
3ece3026d1
@ -2371,6 +2371,38 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process tri-state responses from permission-alterting decorators. The decorators are
|
||||||
|
* expected to return one of 3 values
|
||||||
|
*
|
||||||
|
* - false: Disallow this permission, regardless of what other decorators say
|
||||||
|
* - true: Allow this permission, as long as no other decorators return false
|
||||||
|
* - NULL: Don't affect the outcome
|
||||||
|
*
|
||||||
|
* This method itself returns a tri-state value, and is designed to be used like this:
|
||||||
|
*
|
||||||
|
* $extended = $this->extendedCan('canDoSomething', $member);
|
||||||
|
* if($extended !== null) return $extended;
|
||||||
|
* else return $normalValue;
|
||||||
|
*/
|
||||||
|
public function extendedCan($methodName, $member) {
|
||||||
|
$results = $this->extend($methodName, $member);
|
||||||
|
if($results && is_array($results)) {
|
||||||
|
// Remove NULLs
|
||||||
|
$results = array_filter($results, array($this,'isNotNull'));
|
||||||
|
// If there are any non-NULL responses, then return the lowest one of them.
|
||||||
|
// If any explicitly deny the permission, then we don't get access
|
||||||
|
if($results) return min($results);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Helper functon for extendedCan
|
||||||
|
*/
|
||||||
|
private function isNotNull($value) {
|
||||||
|
return !is_null($value);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return boolean
|
* @return boolean
|
||||||
|
@ -727,8 +727,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
|
|
||||||
if($member && Permission::checkMember($member, "ADMIN")) return true;
|
if($member && Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
$results = $this->extend('canAddChildren', $member);
|
// Standard mechanism for accepting permission changes from decorators
|
||||||
if($results && is_array($results)) if(!min($results)) return false;
|
$extended = $this->extendedCan('canAddChildren', $member);
|
||||||
|
if($extended !== null) return $extended;
|
||||||
|
|
||||||
return $this->canEdit($member) && $this->stat('allowed_children') != 'none';
|
return $this->canEdit($member) && $this->stat('allowed_children') != 'none';
|
||||||
}
|
}
|
||||||
@ -758,9 +759,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
// admin override
|
// admin override
|
||||||
if($member && Permission::checkMember($member, array("ADMIN", "SITETREE_VIEW_ALL"))) return true;
|
if($member && Permission::checkMember($member, array("ADMIN", "SITETREE_VIEW_ALL"))) return true;
|
||||||
|
|
||||||
// decorated access checks
|
// Standard mechanism for accepting permission changes from decorators
|
||||||
$results = $this->extend('canView', $member);
|
$extended = $this->extendedCan('canView', $member);
|
||||||
if($results && is_array($results)) if(!min($results)) return false;
|
if($extended != null) return $extended;
|
||||||
|
|
||||||
// check for empty spec
|
// check for empty spec
|
||||||
if(!$this->CanViewType || $this->CanViewType == 'Anyone') return true;
|
if(!$this->CanViewType || $this->CanViewType == 'Anyone') return true;
|
||||||
@ -835,9 +836,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// decorated access checks
|
// Standard mechanism for accepting permission changes from decorators
|
||||||
$results = $this->extend('canDelete', $memberID);
|
$extended = $this->extendedCan('canDelete', $memberID);
|
||||||
if($results && is_array($results)) if(!min($results)) return false;
|
if($extended !== null) return $extended;
|
||||||
|
|
||||||
// Check cache (the can_edit_multiple call below will also do this, but this is quicker)
|
// Check cache (the can_edit_multiple call below will also do this, but this is quicker)
|
||||||
if(isset(self::$cache_permissions['delete'][$this->ID])) {
|
if(isset(self::$cache_permissions['delete'][$this->ID])) {
|
||||||
@ -876,9 +877,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
|
|
||||||
if($member && Permission::checkMember($member, "ADMIN")) return true;
|
if($member && Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
// decorated permission checks
|
// Standard mechanism for accepting permission changes from decorators
|
||||||
$results = $this->extend('canCreate', $member);
|
$extended = $this->extendedCan('canCreate', $member);
|
||||||
if($results && is_array($results)) if(!min($results)) return false;
|
if($extended !== null) return $extended;
|
||||||
|
|
||||||
return $this->stat('can_create') != false || Director::isDev();
|
return $this->stat('can_create') != false || Director::isDev();
|
||||||
}
|
}
|
||||||
@ -910,9 +911,9 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
|
|
||||||
if($memberID && Permission::checkMember($memberID, array("ADMIN", "SITETREE_EDIT_ALL"))) return true;
|
if($memberID && Permission::checkMember($memberID, array("ADMIN", "SITETREE_EDIT_ALL"))) return true;
|
||||||
|
|
||||||
// decorated access checks
|
// Standard mechanism for accepting permission changes from decorators
|
||||||
$results = $this->extend('canEdit', $memberID);
|
$extended = $this->extendedCan('canEdit', $memberID);
|
||||||
if($results && is_array($results)) if(!min($results)) return false;
|
if($extended !== null) return $extended;
|
||||||
|
|
||||||
if($this->ID) {
|
if($this->ID) {
|
||||||
// Check cache (the can_edit_multiple call below will also do this, but this is quicker)
|
// Check cache (the can_edit_multiple call below will also do this, but this is quicker)
|
||||||
@ -952,20 +953,18 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
|
|
||||||
if($member && Permission::checkMember($member, "ADMIN")) return true;
|
if($member && Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
// If we have a result, then that means at least one decorator specified alternateCanPublish
|
// Standard mechanism for accepting permission changes from decorators
|
||||||
// Allow the permission check only if *all* voting decorators allow it.
|
$extended = $this->extendedCan('canPublish', $member);
|
||||||
$results = $this->extend('canPublish', $member);
|
if($extended !== null) return $extended;
|
||||||
if($results && is_array($results)) if(!min($results)) return false;
|
|
||||||
|
|
||||||
// Normal case
|
// Normal case - fail over to canEdit()
|
||||||
return $this->canEdit($member);
|
return $this->canEdit($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function canDeleteFromLive($member = null) {
|
public function canDeleteFromLive($member = null) {
|
||||||
// If we have a result, then that means at least one decorator specified canDeleteFromLive
|
// Standard mechanism for accepting permission changes from decorators
|
||||||
// Allow the permission check only if *all* voting decorators allow it.
|
$extended = $this->extendedCan('canDeleteFromLive', $member);
|
||||||
$results = $this->extend('canDeleteFromLive', $member);
|
if($extended !==null) return $extended;
|
||||||
if($results && is_array($results)) if(!min($results)) return false;
|
|
||||||
|
|
||||||
return $this->canPublish($member);
|
return $this->canPublish($member);
|
||||||
}
|
}
|
||||||
@ -1612,7 +1611,7 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Redirector pages
|
// Redirector pages
|
||||||
$redirectors = DataObject::get("RedirectorPage", "\"RedirectionType\" = 'Internal' AND \"LinkToID\" = $this->ID");
|
$redirectors = DataObject::get("RedirectorPage", "\"RedirectorPage\".\"RedirectionType\" = 'Internal' AND \"LinkToID\" = $this->ID");
|
||||||
if($redirectors) {
|
if($redirectors) {
|
||||||
foreach($redirectors as $item) $item->DependentLinkType = 'Redirector page';
|
foreach($redirectors as $item) $item->DependentLinkType = 'Redirector page';
|
||||||
$items->merge($redirectors);
|
$items->merge($redirectors);
|
||||||
|
Loading…
Reference in New Issue
Block a user