private function buildExceptionsSection(PhabricatorPolicyInterface $object, $capability)
 {
     $viewer = $this->getViewer();
     $exceptions = PhabricatorPolicy::getSpecialRules($object, $viewer, $capability, false);
     if (!$exceptions) {
         return null;
     }
     return id(new PHUIPolicySectionView())->setViewer($viewer)->setIcon('fa-unlock-alt red')->setHeader(pht('Special Rules'))->appendParagraph(pht('This object has special rules which override normal object ' . 'policy rules:'))->appendList($exceptions);
 }
 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);
     $more = (array) $more;
     $more = array_filter($more);
     $exceptions = PhabricatorPolicy::getSpecialRules($object, $this->viewer, $capability, true);
     $details = array_filter(array_merge($more, $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;
 }