Changeset View
Changeset View
Standalone View
Standalone View
src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php
Show All 29 Lines | abstract class PhabricatorPolicyAwareQuery extends PhabricatorOffsetPagedQuery { | ||||
private $viewer; | private $viewer; | ||||
private $raisePolicyExceptions; | private $raisePolicyExceptions; | ||||
private $parentQuery; | private $parentQuery; | ||||
private $rawResultLimit; | private $rawResultLimit; | ||||
private $capabilities; | private $capabilities; | ||||
private $workspace = array(); | private $workspace = array(); | ||||
private $policyFilteredPHIDs = array(); | private $policyFilteredPHIDs = array(); | ||||
private $canUseApplication; | |||||
/* -( Query Configuration )------------------------------------------------ */ | /* -( Query Configuration )------------------------------------------------ */ | ||||
/** | /** | ||||
* Set the viewer who is executing the query. Results will be filtered | * Set the viewer who is executing the query. Results will be filtered | ||||
* according to the viewer's capabilities. You must set a viewer to execute | * according to the viewer's capabilities. You must set a viewer to execute | ||||
▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | final public function execute() { | ||||
do { | do { | ||||
if ($need) { | if ($need) { | ||||
$this->rawResultLimit = min($need - $count, 1024); | $this->rawResultLimit = min($need - $count, 1024); | ||||
} else { | } else { | ||||
$this->rawResultLimit = 0; | $this->rawResultLimit = 0; | ||||
} | } | ||||
if ($this->canViewerUseQueryApplication()) { | |||||
try { | try { | ||||
$page = $this->loadPage(); | $page = $this->loadPage(); | ||||
} catch (PhabricatorEmptyQueryException $ex) { | } catch (PhabricatorEmptyQueryException $ex) { | ||||
$page = array(); | $page = array(); | ||||
} | } | ||||
} else { | |||||
$page = array(); | |||||
} | |||||
if ($page) { | if ($page) { | ||||
$maybe_visible = $this->willFilterPage($page); | $maybe_visible = $this->willFilterPage($page); | ||||
} else { | } else { | ||||
$maybe_visible = array(); | $maybe_visible = array(); | ||||
} | } | ||||
if ($this->shouldDisablePolicyFiltering()) { | if ($this->shouldDisablePolicyFiltering()) { | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | /* -( Query Execution )---------------------------------------------------- */ | ||||
protected function didRejectResult(PhabricatorPolicyInterface $object) { | protected function didRejectResult(PhabricatorPolicyInterface $object) { | ||||
$this->getPolicyFilter()->rejectObject( | $this->getPolicyFilter()->rejectObject( | ||||
$object, | $object, | ||||
$object->getPolicy(PhabricatorPolicyCapability::CAN_VIEW), | $object->getPolicy(PhabricatorPolicyCapability::CAN_VIEW), | ||||
PhabricatorPolicyCapability::CAN_VIEW); | PhabricatorPolicyCapability::CAN_VIEW); | ||||
} | } | ||||
protected function addPolicyFilteredPHIDs(array $phids) { | public function addPolicyFilteredPHIDs(array $phids) { | ||||
$this->policyFilteredPHIDs += $phids; | $this->policyFilteredPHIDs += $phids; | ||||
if ($this->getParentQuery()) { | if ($this->getParentQuery()) { | ||||
$this->getParentQuery()->addPolicyFilteredPHIDs($phids); | $this->getParentQuery()->addPolicyFilteredPHIDs($phids); | ||||
} | } | ||||
return $this; | return $this; | ||||
} | } | ||||
/** | /** | ||||
▲ Show 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | /* -( Policy Query Implementation )---------------------------------------- */ | ||||
* | * | ||||
* @return bool True to disable all policy filtering. | * @return bool True to disable all policy filtering. | ||||
* @task policyimpl | * @task policyimpl | ||||
*/ | */ | ||||
protected function shouldDisablePolicyFiltering() { | protected function shouldDisablePolicyFiltering() { | ||||
return false; | return false; | ||||
} | } | ||||
/** | |||||
* If this query belongs to an application, return the application class name | |||||
* here. This will prevent the query from returning results if the viewer can | |||||
* not access the application. | |||||
* | |||||
* If this query does not belong to an application, return `null`. | |||||
* | |||||
* @return string|null Application class name. | |||||
*/ | |||||
abstract public function getQueryApplicationClass(); | |||||
/** | |||||
* Determine if the viewer has permission to use this query's application. | |||||
* For queries which aren't part of an application, this method always returns | |||||
* true. | |||||
* | |||||
* @return bool True if the viewer has application-level permission to | |||||
* execute the query. | |||||
*/ | |||||
public function canViewerUseQueryApplication() { | |||||
if ($this->canUseApplication === null) { | |||||
$class = $this->getQueryApplicationClass(); | |||||
if (!$class) { | |||||
$this->canUseApplication = true; | |||||
} else { | |||||
$result = id(new PhabricatorApplicationQuery()) | |||||
->setViewer($this->getViewer()) | |||||
->withClasses(array($class)) | |||||
->execute(); | |||||
$this->canUseApplication = (bool)$result; | |||||
} | |||||
} | |||||
return $this->canUseApplication; | |||||
} | |||||
} | } |