private function appendSpaceInformation(AphrontDialogView $dialog, PhabricatorPolicyInterface $object, PhabricatorPolicy $policy, $capability)
 {
     $viewer = $this->getViewer();
     if (!$object instanceof PhabricatorSpacesInterface) {
         return;
     }
     if (!PhabricatorSpacesNamespaceQuery::getSpacesExist($viewer)) {
         return;
     }
     // NOTE: We're intentionally letting users through here, even if they only
     // have access to one space. The intent is to help users in "space jail"
     // understand who objects they create are visible to:
     $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($object);
     $handles = $viewer->loadHandles(array($space_phid));
     $doc_href = PhabricatorEnv::getDoclink('Spaces User Guide');
     $dialog->appendParagraph(array(pht('This object is in %s, and can only be seen or edited by users with ' . 'access to view objects in the space.', $handles[$space_phid]->renderLink()), ' ', phutil_tag('strong', array(), phutil_tag('a', array('href' => $doc_href, 'target' => '_blank'), pht('Learn More')))));
     $spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer);
     $space = idx($spaces, $space_phid);
     if (!$space) {
         return;
     }
     $space_policies = PhabricatorPolicyQuery::loadPolicies($viewer, $space);
     $space_policy = idx($space_policies, PhabricatorPolicyCapability::CAN_VIEW);
     if (!$space_policy) {
         return;
     }
     $space_explanation = PhabricatorPolicy::getPolicyExplanation($viewer, $space_policy->getPHID());
     $items = array();
     $items[] = $space_explanation;
     foreach ($items as $key => $item) {
         $items[$key] = phutil_tag('li', array(), $item);
     }
     $dialog->appendParagraph(pht('Users who can see objects in this space:'));
     $dialog->appendChild(phutil_tag('ul', array(), $items));
     $view_capability = PhabricatorPolicyCapability::CAN_VIEW;
     if ($capability == $view_capability) {
         $stronger = $space_policy->isStrongerThan($policy);
         if ($stronger) {
             $dialog->appendParagraph(pht('The space this object is in has a more restrictive view ' . 'policy ("%s") than the object does ("%s"), so the space\'s ' . 'view policy is shown as a hint instead of the object policy.', $space_policy->getShortName(), $policy->getShortName()));
         }
     }
     $dialog->appendParagraph(pht('After a user passes space policy checks, they must still pass ' . 'object policy checks.'));
 }
 public function execute(PhutilArgumentParser $args)
 {
     $console = PhutilConsole::getConsole();
     $viewer = $this->getViewer();
     $obj_names = $args->getArg('objects');
     if (!$obj_names) {
         throw new PhutilArgumentUsageException(pht('Specify the name of an object to show policy information for.'));
     } else {
         if (count($obj_names) > 1) {
             throw new PhutilArgumentUsageException(pht('Specify the name of exactly one object to show policy information ' . 'for.'));
         }
     }
     $object = id(new PhabricatorObjectQuery())->setViewer($viewer)->withNames($obj_names)->executeOne();
     if (!$object) {
         $name = head($obj_names);
         throw new PhutilArgumentUsageException(pht("No such object '%s'!", $name));
     }
     $handle = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs(array($object->getPHID()))->executeOne();
     $policies = PhabricatorPolicyQuery::loadPolicies($viewer, $object);
     $console->writeOut("__%s__\n\n", pht('OBJECT'));
     $console->writeOut("  %s\n", $handle->getFullName());
     $console->writeOut("\n");
     $console->writeOut("__%s__\n\n", pht('CAPABILITIES'));
     foreach ($policies as $capability => $policy) {
         $console->writeOut("  **%s**\n", $capability);
         $console->writeOut("    %s\n", $policy->renderDescription());
         $console->writeOut("    %s\n", PhabricatorPolicy::getPolicyExplanation($viewer, $policy->getPHID()));
         $console->writeOut("\n");
         $more = (array) $object->describeAutomaticCapability($capability);
         if ($more) {
             foreach ($more as $line) {
                 $console->writeOut("    %s\n", $line);
             }
             $console->writeOut("\n");
         }
     }
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $phid = $this->phid;
     $capability = $this->capability;
     $object = id(new PhabricatorObjectQuery())->setViewer($viewer)->withPHIDs(array($phid))->executeOne();
     if (!$object) {
         return new Aphront404Response();
     }
     $policies = PhabricatorPolicyQuery::loadPolicies($viewer, $object);
     $policy = idx($policies, $capability);
     if (!$policy) {
         return new Aphront404Response();
     }
     $handle = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs(array($phid))->executeOne();
     $object_uri = nonempty($handle->getURI(), '/');
     $explanation = PhabricatorPolicy::getPolicyExplanation($viewer, $policy->getPHID());
     $auto_info = (array) $object->describeAutomaticCapability($capability);
     $auto_info = array_merge(array($explanation), $auto_info);
     $auto_info = array_filter($auto_info);
     foreach ($auto_info as $key => $info) {
         $auto_info[$key] = phutil_tag('li', array(), $info);
     }
     if ($auto_info) {
         $auto_info = phutil_tag('ul', array(), $auto_info);
     }
     $capability_name = $capability;
     $capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
     if ($capobj) {
         $capability_name = $capobj->getCapabilityName();
     }
     $content = array(pht('Users with the "%s" capability:', $capability_name), $auto_info);
     $object_name = pht('%s %s', $handle->getTypeName(), $handle->getObjectName());
     $dialog = id(new AphrontDialogView())->setUser($viewer)->setClass('aphront-access-dialog')->setTitle(pht('Policy Details: %s', $object_name))->appendChild($content)->addCancelButton($object_uri, pht('Done'));
     return id(new AphrontDialogResponse())->setDialog($dialog);
 }
 public function rejectObject(PhabricatorPolicyInterface $object, $policy, $capability)
 {
     if (!$this->raisePolicyExceptions) {
         return;
     }
     if ($this->viewer->isOmnipotent()) {
         // Never raise policy exceptions for the omnipotent viewer. Although we
         // will never normally issue a policy rejection for the omnipotent
         // viewer, we can end up here when queries blanket reject objects that
         // have failed to load, without distinguishing between nonexistent and
         // nonvisible objects.
         return;
     }
     $capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
     $rejection = null;
     if ($capobj) {
         $rejection = $capobj->describeCapabilityRejection();
         $capability_name = $capobj->getCapabilityName();
     } else {
         $capability_name = $capability;
     }
     if (!$rejection) {
         // We couldn't find the capability object, or it doesn't provide a
         // tailored rejection string.
         $rejection = pht('You do not have the required capability ("%s") to do whatever you ' . 'are trying to do.', $capability);
     }
     $more = PhabricatorPolicy::getPolicyExplanation($this->viewer, $policy);
     $exceptions = $object->describeAutomaticCapability($capability);
     $details = array_filter(array_merge(array($more), (array) $exceptions));
     $access_denied = $this->renderAccessDenied($object);
     $full_message = pht('[%s] (%s) %s // %s', $access_denied, $capability_name, $rejection, implode(' ', $details));
     $exception = id(new PhabricatorPolicyException($full_message))->setTitle($access_denied)->setObjectPHID($object->getPHID())->setRejection($rejection)->setCapability($capability)->setCapabilityName($capability_name)->setMoreInfo($details);
     throw $exception;
 }
 public function rejectObject(PhabricatorPolicyInterface $object, $policy, $capability)
 {
     if (!$this->raisePolicyExceptions) {
         return;
     }
     if ($this->viewer->isOmnipotent()) {
         // Never raise policy exceptions for the omnipotent viewer. Although we
         // will never normally issue a policy rejection for the omnipotent
         // viewer, we can end up here when queries blanket reject objects that
         // have failed to load, without distinguishing between nonexistent and
         // nonvisible objects.
         return;
     }
     $capobj = PhabricatorPolicyCapability::getCapabilityByKey($capability);
     $rejection = null;
     if ($capobj) {
         $rejection = $capobj->describeCapabilityRejection();
         $capability_name = $capobj->getCapabilityName();
     } else {
         $capability_name = $capability;
     }
     if (!$rejection) {
         // We couldn't find the capability object, or it doesn't provide a
         // tailored rejection string.
         $rejection = pht('You do not have the required capability ("%s") to do whatever you ' . 'are trying to do.', $capability);
     }
     $more = PhabricatorPolicy::getPolicyExplanation($this->viewer, $policy);
     $exceptions = $object->describeAutomaticCapability($capability);
     $details = array_filter(array_merge(array($more), (array) $exceptions));
     // NOTE: Not every type of policy object has a real PHID; just load an
     // empty handle if a real PHID isn't available.
     $phid = nonempty($object->getPHID(), PhabricatorPHIDConstants::PHID_VOID);
     $handle = id(new PhabricatorHandleQuery())->setViewer($this->viewer)->withPHIDs(array($phid))->executeOne();
     $object_name = pht('%s %s', $handle->getTypeName(), $handle->getObjectName());
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
     if ($is_serious) {
         $title = pht('Access Denied: %s', $object_name);
     } else {
         $title = pht('You Shall Not Pass: %s', $object_name);
     }
     $full_message = pht('[%s] (%s) %s // %s', $title, $capability_name, $rejection, implode(' ', $details));
     $exception = id(new PhabricatorPolicyException($full_message))->setTitle($title)->setRejection($rejection)->setCapabilityName($capability_name)->setMoreInfo($details);
     throw $exception;
 }
 private function buildObjectSection(PhabricatorPolicyInterface $object, PhabricatorPolicy $policy, $capability, PhabricatorObjectHandle $handle)
 {
     $viewer = $this->getViewer();
     $capability_name = $this->getCapabilityName($capability);
     $object_section = id(new PHUIPolicySectionView())->setViewer($viewer)->setIcon($handle->getIcon() . ' bluegrey')->setHeader(pht('Object Policy'))->appendList(array(array(phutil_tag('strong', array(), pht('%s:', $capability_name)), ' ', $policy->getShortName())))->appendParagraph(pht('In detail, this means that these users can take this action, ' . 'provided they pass all of the checks described above first:'))->appendList(array(PhabricatorPolicy::getPolicyExplanation($viewer, $policy->getPHID())));
     $strength = $this->getStrengthInformation($object, $policy, $capability);
     if ($strength) {
         $object_section->appendHint($strength);
     }
     return $object_section;
 }