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; }