diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 9c63744e58..48571ca4c7 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -3523,7 +3523,7 @@ celerity_register_resource_map(array( ), 'phabricator-standard-page-view' => array( - 'uri' => '/res/59c804b1/rsrc/css/application/base/standard-page-view.css', + 'uri' => '/res/eebd59cd/rsrc/css/application/base/standard-page-view.css', 'type' => 'css', 'requires' => array( @@ -4297,7 +4297,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - 'deb31815' => + '13fde8cd' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -4346,7 +4346,7 @@ celerity_register_resource_map(array( 41 => 'phabricator-tag-view-css', 42 => 'phui-list-view-css', ), - 'uri' => '/res/pkg/deb31815/core.pkg.css', + 'uri' => '/res/pkg/13fde8cd/core.pkg.css', 'type' => 'css', ), '6041c6c8' => @@ -4538,15 +4538,15 @@ celerity_register_resource_map(array( ), 'reverse' => array( - 'aphront-dialog-view-css' => 'deb31815', - 'aphront-error-view-css' => 'deb31815', - 'aphront-list-filter-view-css' => 'deb31815', - 'aphront-pager-view-css' => 'deb31815', - 'aphront-panel-view-css' => 'deb31815', - 'aphront-table-view-css' => 'deb31815', - 'aphront-tokenizer-control-css' => 'deb31815', - 'aphront-tooltip-css' => 'deb31815', - 'aphront-typeahead-control-css' => 'deb31815', + 'aphront-dialog-view-css' => '13fde8cd', + 'aphront-error-view-css' => '13fde8cd', + 'aphront-list-filter-view-css' => '13fde8cd', + 'aphront-pager-view-css' => '13fde8cd', + 'aphront-panel-view-css' => '13fde8cd', + 'aphront-table-view-css' => '13fde8cd', + 'aphront-tokenizer-control-css' => '13fde8cd', + 'aphront-tooltip-css' => '13fde8cd', + 'aphront-typeahead-control-css' => '13fde8cd', 'differential-changeset-view-css' => '7cd7e387', 'differential-core-view-css' => '7cd7e387', 'differential-inline-comment-editor' => '5e9e5c4e', @@ -4560,7 +4560,7 @@ celerity_register_resource_map(array( 'differential-table-of-contents-css' => '7cd7e387', 'diffusion-commit-view-css' => '270f4eb4', 'diffusion-icons-css' => '270f4eb4', - 'global-drag-and-drop-css' => 'deb31815', + 'global-drag-and-drop-css' => '13fde8cd', 'inline-comment-summary-css' => '7cd7e387', 'javelin-aphlict' => '6041c6c8', 'javelin-behavior' => '3e3be199', @@ -4635,56 +4635,56 @@ celerity_register_resource_map(array( 'javelin-util' => '3e3be199', 'javelin-vector' => '3e3be199', 'javelin-workflow' => '3e3be199', - 'lightbox-attachment-css' => 'deb31815', + 'lightbox-attachment-css' => '13fde8cd', 'maniphest-task-summary-css' => '49898640', - 'phabricator-action-list-view-css' => 'deb31815', - 'phabricator-application-launch-view-css' => 'deb31815', + 'phabricator-action-list-view-css' => '13fde8cd', + 'phabricator-application-launch-view-css' => '13fde8cd', 'phabricator-busy' => '6041c6c8', 'phabricator-content-source-view-css' => '7cd7e387', - 'phabricator-core-css' => 'deb31815', - 'phabricator-crumbs-view-css' => 'deb31815', + 'phabricator-core-css' => '13fde8cd', + 'phabricator-crumbs-view-css' => '13fde8cd', 'phabricator-drag-and-drop-file-upload' => '5e9e5c4e', 'phabricator-dropdown-menu' => '6041c6c8', 'phabricator-file-upload' => '6041c6c8', - 'phabricator-filetree-view-css' => 'deb31815', - 'phabricator-flag-css' => 'deb31815', + 'phabricator-filetree-view-css' => '13fde8cd', + 'phabricator-flag-css' => '13fde8cd', 'phabricator-hovercard' => '6041c6c8', - 'phabricator-jump-nav' => 'deb31815', + 'phabricator-jump-nav' => '13fde8cd', 'phabricator-keyboard-shortcut' => '6041c6c8', 'phabricator-keyboard-shortcut-manager' => '6041c6c8', - 'phabricator-main-menu-view' => 'deb31815', + 'phabricator-main-menu-view' => '13fde8cd', 'phabricator-menu-item' => '6041c6c8', - 'phabricator-nav-view-css' => 'deb31815', + 'phabricator-nav-view-css' => '13fde8cd', 'phabricator-notification' => '6041c6c8', - 'phabricator-notification-css' => 'deb31815', - 'phabricator-notification-menu-css' => 'deb31815', + 'phabricator-notification-css' => '13fde8cd', + 'phabricator-notification-menu-css' => '13fde8cd', 'phabricator-object-selector-css' => '7cd7e387', 'phabricator-phtize' => '6041c6c8', 'phabricator-prefab' => '6041c6c8', 'phabricator-project-tag-css' => '49898640', - 'phabricator-remarkup-css' => 'deb31815', + 'phabricator-remarkup-css' => '13fde8cd', 'phabricator-shaped-request' => '5e9e5c4e', - 'phabricator-side-menu-view-css' => 'deb31815', - 'phabricator-standard-page-view' => 'deb31815', - 'phabricator-tag-view-css' => 'deb31815', + 'phabricator-side-menu-view-css' => '13fde8cd', + 'phabricator-standard-page-view' => '13fde8cd', + 'phabricator-tag-view-css' => '13fde8cd', 'phabricator-textareautils' => '6041c6c8', 'phabricator-tooltip' => '6041c6c8', - 'phabricator-transaction-view-css' => 'deb31815', - 'phabricator-zindex-css' => 'deb31815', - 'phui-button-css' => 'deb31815', - 'phui-form-css' => 'deb31815', - 'phui-form-view-css' => 'deb31815', - 'phui-header-view-css' => 'deb31815', - 'phui-icon-view-css' => 'deb31815', - 'phui-list-view-css' => 'deb31815', - 'phui-object-item-list-view-css' => 'deb31815', - 'phui-property-list-view-css' => 'deb31815', - 'phui-spacing-css' => 'deb31815', - 'sprite-apps-large-css' => 'deb31815', - 'sprite-gradient-css' => 'deb31815', - 'sprite-icons-css' => 'deb31815', - 'sprite-menu-css' => 'deb31815', - 'sprite-status-css' => 'deb31815', - 'syntax-highlighting-css' => 'deb31815', + 'phabricator-transaction-view-css' => '13fde8cd', + 'phabricator-zindex-css' => '13fde8cd', + 'phui-button-css' => '13fde8cd', + 'phui-form-css' => '13fde8cd', + 'phui-form-view-css' => '13fde8cd', + 'phui-header-view-css' => '13fde8cd', + 'phui-icon-view-css' => '13fde8cd', + 'phui-list-view-css' => '13fde8cd', + 'phui-object-item-list-view-css' => '13fde8cd', + 'phui-property-list-view-css' => '13fde8cd', + 'phui-spacing-css' => '13fde8cd', + 'sprite-apps-large-css' => '13fde8cd', + 'sprite-gradient-css' => '13fde8cd', + 'sprite-icons-css' => '13fde8cd', + 'sprite-menu-css' => '13fde8cd', + 'sprite-status-css' => '13fde8cd', + 'syntax-highlighting-css' => '13fde8cd', ), )); diff --git a/src/applications/phid/PhabricatorObjectHandle.php b/src/applications/phid/PhabricatorObjectHandle.php index 2788fe9cfc..85f355e8c4 100644 --- a/src/applications/phid/PhabricatorObjectHandle.php +++ b/src/applications/phid/PhabricatorObjectHandle.php @@ -15,6 +15,16 @@ final class PhabricatorObjectHandle private $complete; private $disabled; private $objectName; + private $policyFiltered; + + public function setPolicyFiltered($policy_filered) { + $this->policyFiltered = $policy_filered; + return $this; + } + + public function getPolicyFiltered() { + return $this->policyFiltered; + } public function setObjectName($object_name) { $this->objectName = $object_name; @@ -53,7 +63,11 @@ final class PhabricatorObjectHandle public function getName() { if ($this->name === null) { - return pht('Unknown Object (%s)', $this->getTypeName()); + if ($this->getPolicyFiltered()) { + return pht('Restricted %s', $this->getTypeName()); + } else { + return pht('Unknown Object (%s)', $this->getTypeName()); + } } return $this->name; } @@ -186,6 +200,7 @@ final class PhabricatorObjectHandle $name = $this->getLinkName(); } $classes = array(); + $classes[] = 'phui-handle'; $title = $this->title; if ($this->status != PhabricatorObjectHandleStatus::STATUS_OPEN) { @@ -195,21 +210,30 @@ final class PhabricatorObjectHandle if ($this->disabled) { $classes[] = 'handle-disabled'; - $title = 'disabled'; // Overwrite status. + $title = pht('Disabled'); // Overwrite status. } if ($this->getType() == PhabricatorPeoplePHIDTypeUser::TYPECONST) { $classes[] = 'phui-link-person'; } + $uri = $this->getURI(); + + $icon = null; + if ($this->getPolicyFiltered()) { + $icon = id(new PHUIIconView()) + ->setSpriteSheet(PHUIIconView::SPRITE_ICONS) + ->setSpriteIcon('lock-grey'); + } + return phutil_tag( - 'a', + $uri ? 'a' : 'span', array( - 'href' => $this->getURI(), + 'href' => $uri, 'class' => implode(' ', $classes), 'title' => $title, ), - $name); + array($icon, $name)); } public function getLinkName() { diff --git a/src/applications/phid/query/PhabricatorHandleQuery.php b/src/applications/phid/query/PhabricatorHandleQuery.php index c34fcfd3a0..5e089b1ed1 100644 --- a/src/applications/phid/query/PhabricatorHandleQuery.php +++ b/src/applications/phid/query/PhabricatorHandleQuery.php @@ -18,10 +18,12 @@ final class PhabricatorHandleQuery return array(); } - $objects = id(new PhabricatorObjectQuery()) + $object_query = id(new PhabricatorObjectQuery()) ->withPHIDs($phids) - ->setViewer($this->getViewer()) - ->execute(); + ->setViewer($this->getViewer()); + + $objects = $object_query->execute(); + $filtered = $object_query->getPolicyFilteredPHIDs(); $groups = array(); foreach ($phids as $phid) { @@ -43,6 +45,8 @@ final class PhabricatorHandleQuery ->setPHID($phid); if (isset($objects[$phid])) { $handles[$phid]->setComplete(true); + } else if (isset($filtered[$phid])) { + $handles[$phid]->setPolicyFiltered(true); } } diff --git a/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php b/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php index ad0d7b2a33..20b45df42d 100644 --- a/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php +++ b/src/infrastructure/query/policy/PhabricatorPolicyAwareQuery.php @@ -34,6 +34,7 @@ abstract class PhabricatorPolicyAwareQuery extends PhabricatorOffsetPagedQuery { private $rawResultLimit; private $capabilities; private $workspace = array(); + private $policyFilteredPHIDs = array(); /* -( Query Configuration )------------------------------------------------ */ @@ -228,6 +229,17 @@ abstract class PhabricatorPolicyAwareQuery extends PhabricatorOffsetPagedQuery { $visible = $maybe_visible; } else { $visible = $filter->apply($maybe_visible); + + $policy_filtered = array(); + foreach ($maybe_visible as $key => $object) { + if (empty($visible[$key])) { + $phid = $object->getPHID(); + if ($phid) { + $policy_filtered[$phid] = $phid; + } + } + } + $this->addPolicyFilteredPHIDs($policy_filtered); } if ($visible) { @@ -305,6 +317,28 @@ abstract class PhabricatorPolicyAwareQuery extends PhabricatorOffsetPagedQuery { PhabricatorPolicyCapability::CAN_VIEW); } + protected function addPolicyFilteredPHIDs(array $phids) { + $this->policyFilteredPHIDs += $phids; + if ($this->getParentQuery()) { + $this->getParentQuery()->addPolicyFilteredPHIDs($phids); + } + return $this; + } + + /** + * Return a map of all object PHIDs which were loaded in the query but + * filtered out by policy constraints. This allows a caller to distinguish + * between objects which do not exist (or, at least, were filtered at the + * content level) and objects which exist but aren't visible. + * + * @return map Map of object PHIDs which were filtered + * by policies. + * @task exec + */ + public function getPolicyFilteredPHIDs() { + return $this->policyFilteredPHIDs; + } + /* -( Query Workspace )---------------------------------------------------- */ diff --git a/webroot/rsrc/css/application/base/standard-page-view.css b/webroot/rsrc/css/application/base/standard-page-view.css index faa21a3656..77ecefd1a7 100644 --- a/webroot/rsrc/css/application/base/standard-page-view.css +++ b/webroot/rsrc/css/application/base/standard-page-view.css @@ -95,3 +95,8 @@ a.handle-disabled { padding: 8px 16px; background: {$lightyellow}; } + +.phui-handle .phui-icon-view { + display: inline-block; + margin: 2px 2px -2px 0; +}