1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-29 18:22:41 +01:00

When users fail a "CAN_SEE" check, give them an "opaque" policy explanation

Summary:
Ref T13411. Currently, if you hit a policy exception because you can't view an object, we disclose details about the view policy of the object, particularly which project's members can see the object for project policies.

Although there's a large amount of grey area here, this feels like a more substantial disclosure than we offer in other contexts. Instead, if you encounter a policy exception while testing "CAN_VIEW" or don't have "CAN_VIEW", present an "opaque" explanation which omits details that viewers who can't view the object shouldn't have access to. Today, this is the name of "Project" policies (and, implicitly, the rulesets of custom policies, which we now disclose in other similar contexts).

Test Plan:
  - Hit policy exceptions for "CAN_VIEW" on an object with a project view policy, saw an opaque explanation.
  - Hit policy exceptions for "CAN_EDIT" on an object with a project edit policy and a view policy I satisfied, saw a more detailed explanation.

Maniphest Tasks: T13411

Differential Revision: https://secure.phabricator.com/D20806
This commit is contained in:
epriestley 2019-09-12 08:53:14 -07:00
parent 9a36e6931c
commit 0c7ea8c942
2 changed files with 48 additions and 3 deletions

View file

@ -602,12 +602,13 @@ final class PhabricatorPolicyFilter extends Phobject {
PhabricatorPolicyInterface $object, PhabricatorPolicyInterface $object,
$policy, $policy,
$capability) { $capability) {
$viewer = $this->viewer;
if (!$this->raisePolicyExceptions) { if (!$this->raisePolicyExceptions) {
return; return;
} }
if ($this->viewer->isOmnipotent()) { if ($viewer->isOmnipotent()) {
// Never raise policy exceptions for the omnipotent viewer. Although we // Never raise policy exceptions for the omnipotent viewer. Although we
// will never normally issue a policy rejection for the omnipotent // will never normally issue a policy rejection for the omnipotent
// viewer, we can end up here when queries blanket reject objects that // viewer, we can end up here when queries blanket reject objects that
@ -634,7 +635,30 @@ final class PhabricatorPolicyFilter extends Phobject {
$capability); $capability);
} }
$more = PhabricatorPolicy::getPolicyExplanation($this->viewer, $policy); // See T13411. If you receive a policy exception because you can't view
// an object, we also want to avoid disclosing too many details about the
// actual policy (for example, the names of projects in the policy).
// If you failed a "CAN_VIEW" check, or failed some other check and don't
// have "CAN_VIEW" on the object, we give you an "opaque" explanation.
// Otherwise, we give you a more detailed explanation.
$view_capability = PhabricatorPolicyCapability::CAN_VIEW;
if ($capability === $view_capability) {
$show_details = false;
} else {
$show_details = self::hasCapability(
$viewer,
$object,
$view_capability);
}
if ($show_details) {
$more = PhabricatorPolicy::getPolicyExplanation($viewer, $policy);
} else {
$more = PhabricatorPolicy::getOpaquePolicyExplanation($viewer, $policy);
}
$more = (array)$more; $more = (array)$more;
$more = array_filter($more); $more = array_filter($more);

View file

@ -220,6 +220,25 @@ final class PhabricatorPolicy
PhabricatorUser $viewer, PhabricatorUser $viewer,
$policy) { $policy) {
$type = phid_get_type($policy);
if ($type === PhabricatorProjectProjectPHIDType::TYPECONST) {
$handle = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs(array($policy))
->executeOne();
return pht(
'Members of the project "%s" can take this action.',
$handle->getFullName());
}
return self::getOpaquePolicyExplanation($viewer, $policy);
}
public static function getOpaquePolicyExplanation(
PhabricatorUser $viewer,
$policy) {
$rule = PhabricatorPolicyQuery::getObjectPolicyRule($policy); $rule = PhabricatorPolicyQuery::getObjectPolicyRule($policy);
if ($rule) { if ($rule) {
return $rule->getPolicyExplanation(); return $rule->getPolicyExplanation();
@ -245,7 +264,9 @@ final class PhabricatorPolicy
$type = phid_get_type($policy); $type = phid_get_type($policy);
if ($type == PhabricatorProjectProjectPHIDType::TYPECONST) { if ($type == PhabricatorProjectProjectPHIDType::TYPECONST) {
return pht( return pht(
'Members of the project "%s" can take this action.', 'Members of a particular project can take this action. (You '.
'can not see this object, so the name of this project is '.
'restricted.)',
$handle->getFullName()); $handle->getFullName());
} else if ($type == PhabricatorPeopleUserPHIDType::TYPECONST) { } else if ($type == PhabricatorPeopleUserPHIDType::TYPECONST) {
return pht( return pht(