From 65c1c758ed261f65c8164d200ce01373ae5b822c Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 1 Jan 2017 08:36:38 -0800 Subject: [PATCH] Use extended policies in Differential diffs Summary: Fixes T9648. Diffs currently use `return $this->getRevision()->getViewPolicy();` to inherit their revision's view policy. After the introduction of object policies, this is wrong for policies like "Subscribers", because it means "Subscribers to this object, the diff". Since Diffs have no subscribers, this always fails. Instead, use extended policies so that the object policy evaluates in the context of the correct object (the revision). Test Plan: - Create a revision. - Subscribe `alice` to it. - Set view policy to "Subscribers". - View revision as `alice`. - Before patch: nonsense fatal about missing diff because of policy error. - After patch: `alice` can see the revision. Reviewers: chad Reviewed By: chad Maniphest Tasks: T9648 Differential Revision: https://secure.phabricator.com/D17123 --- src/__phutil_library_map__.php | 1 + .../DifferentialRevisionViewController.php | 5 ++-- .../differential/storage/DifferentialDiff.php | 26 +++++++++++++++++-- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 318095411b..0e485db0d2 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -5058,6 +5058,7 @@ phutil_register_library_map(array( 'DifferentialDiff' => array( 'DifferentialDAO', 'PhabricatorPolicyInterface', + 'PhabricatorExtendedPolicyInterface', 'HarbormasterBuildableInterface', 'HarbormasterCircleCIBuildableInterface', 'PhabricatorApplicationTransactionInterface', diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php index 168d053c6b..6bf9aaa44f 100644 --- a/src/applications/differential/controller/DifferentialRevisionViewController.php +++ b/src/applications/differential/controller/DifferentialRevisionViewController.php @@ -16,18 +16,17 @@ final class DifferentialRevisionViewController extends DifferentialController { $revision = id(new DifferentialRevisionQuery()) ->withIDs(array($this->revisionID)) - ->setViewer($request->getUser()) + ->setViewer($viewer) ->needRelationships(true) ->needReviewerStatus(true) ->needReviewerAuthority(true) ->executeOne(); - if (!$revision) { return new Aphront404Response(); } $diffs = id(new DifferentialDiffQuery()) - ->setViewer($request->getUser()) + ->setViewer($viewer) ->withRevisionIDs(array($this->revisionID)) ->execute(); $diffs = array_reverse($diffs, $preserve_keys = true); diff --git a/src/applications/differential/storage/DifferentialDiff.php b/src/applications/differential/storage/DifferentialDiff.php index 7ddfc43c5a..3ca6ecca18 100644 --- a/src/applications/differential/storage/DifferentialDiff.php +++ b/src/applications/differential/storage/DifferentialDiff.php @@ -4,6 +4,7 @@ final class DifferentialDiff extends DifferentialDAO implements PhabricatorPolicyInterface, + PhabricatorExtendedPolicyInterface, HarbormasterBuildableInterface, HarbormasterCircleCIBuildableInterface, PhabricatorApplicationTransactionInterface, @@ -429,7 +430,7 @@ final class DifferentialDiff public function getPolicy($capability) { if ($this->hasRevision()) { - return $this->getRevision()->getPolicy($capability); + return PhabricatorPolicies::getMostOpenPolicy(); } return $this->viewPolicy; @@ -440,7 +441,7 @@ final class DifferentialDiff return $this->getRevision()->hasAutomaticCapability($capability, $viewer); } - return ($this->getAuthorPHID() == $viewer->getPhid()); + return ($this->getAuthorPHID() == $viewer->getPHID()); } public function describeAutomaticCapability($capability) { @@ -448,10 +449,31 @@ final class DifferentialDiff return pht( 'This diff is attached to a revision, and inherits its policies.'); } + return pht('The author of a diff can see it.'); } +/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */ + + + public function getExtendedPolicy($capability, PhabricatorUser $viewer) { + $extended = array(); + + switch ($capability) { + case PhabricatorPolicyCapability::CAN_VIEW: + if ($this->hasRevision()) { + $extended[] = array( + $this->getRevision(), + PhabricatorPolicyCapability::CAN_VIEW, + ); + } + break; + } + + return $extended; + } + /* -( HarbormasterBuildableInterface )------------------------------------- */