diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php index 0301e453a4..cfe468a546 100644 --- a/src/applications/people/storage/PhabricatorUser.php +++ b/src/applications/people/storage/PhabricatorUser.php @@ -26,6 +26,7 @@ final class PhabricatorUser extends PhabricatorUserDAO implements PhutilPerson { protected $isDisabled = 0; private $preferences = null; + private $omnipotent = false; protected function readField($field) { switch ($field) { @@ -661,4 +662,35 @@ EOBODY; $email->getUserPHID()); } + +/* -( Omnipotence )-------------------------------------------------------- */ + + + /** + * Returns true if this user is omnipotent. Omnipotent users bypass all policy + * checks. + * + * @return bool True if the user bypasses policy checks. + */ + public function isOmnipotent() { + return $this->omnipotent; + } + + + /** + * Get an omnipotent user object for use in contexts where there is no acting + * user, notably daemons. + * + * @return PhabricatorUser An omnipotent user. + */ + public static function getOmnipotentUser() { + static $user = null; + if (!$user) { + $user = new PhabricatorUser(); + $user->omnipotent = true; + $user->makeEphemeral(); + } + return $user; + } + } diff --git a/src/applications/policy/__tests__/PhabricatorPolicyTestCase.php b/src/applications/policy/__tests__/PhabricatorPolicyTestCase.php index 13bb00efbd..aff5ee7d6e 100644 --- a/src/applications/policy/__tests__/PhabricatorPolicyTestCase.php +++ b/src/applications/policy/__tests__/PhabricatorPolicyTestCase.php @@ -154,6 +154,24 @@ final class PhabricatorPolicyTestCase extends PhabricatorTestCase { } + /** + * Test that omnipotent users bypass policies. + */ + public function testOmnipotence() { + $results = array( + $this->buildObject(PhabricatorPolicies::POLICY_NOONE), + ); + + $query = new PhabricatorPolicyAwareTestQuery(); + $query->setResults($results); + $query->setViewer(PhabricatorUser::getOmnipotentUser()); + + $this->assertEqual( + 1, + count($query->execute())); + } + + /** * Test an object for visibility across multiple user specifications. */ diff --git a/src/applications/policy/filter/PhabricatorPolicyFilter.php b/src/applications/policy/filter/PhabricatorPolicyFilter.php index 1ce618b8b4..765583b638 100644 --- a/src/applications/policy/filter/PhabricatorPolicyFilter.php +++ b/src/applications/policy/filter/PhabricatorPolicyFilter.php @@ -173,6 +173,10 @@ final class PhabricatorPolicyFilter { $viewer = $this->viewer; + if ($viewer->isOmnipotent()) { + return true; + } + if ($object->hasAutomaticCapability($capability, $viewer)) { return true; }