@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

When a subscriber can't see an object, clearly show that they're missing the permission in the curtain UI

Summary:
Ref T13602. When a subscriber can't see an object, it's currently hard to figure it out.

Show this status clearly in the curtain UI.

Test Plan: {F8382865}

Maniphest Tasks: T13602

Differential Revision: https://secure.phabricator.com/D21547

+184 -4
+3 -3
resources/celerity/map.php
··· 9 9 'names' => array( 10 10 'conpherence.pkg.css' => '0e3cf785', 11 11 'conpherence.pkg.js' => '020aebcf', 12 - 'core.pkg.css' => '937616c0', 12 + 'core.pkg.css' => '970b3ceb', 13 13 'core.pkg.js' => 'adc34883', 14 14 'dark-console.pkg.js' => '187792c2', 15 15 'differential.pkg.css' => '5c459f92', ··· 151 151 'rsrc/css/phui/phui-comment-form.css' => '68a2d99a', 152 152 'rsrc/css/phui/phui-comment-panel.css' => 'ec4e31c0', 153 153 'rsrc/css/phui/phui-crumbs-view.css' => '614f43cf', 154 - 'rsrc/css/phui/phui-curtain-object-ref-view.css' => '12404744', 154 + 'rsrc/css/phui/phui-curtain-object-ref-view.css' => '5f752bdb', 155 155 'rsrc/css/phui/phui-curtain-view.css' => '68c5efb6', 156 156 'rsrc/css/phui/phui-document-pro.css' => 'b9613a10', 157 157 'rsrc/css/phui/phui-document-summary.css' => 'b068eed1', ··· 845 845 'phui-comment-form-css' => '68a2d99a', 846 846 'phui-comment-panel-css' => 'ec4e31c0', 847 847 'phui-crumbs-view-css' => '614f43cf', 848 - 'phui-curtain-object-ref-view-css' => '12404744', 848 + 'phui-curtain-object-ref-view-css' => '5f752bdb', 849 849 'phui-curtain-view-css' => '68c5efb6', 850 850 'phui-document-summary-view-css' => 'b068eed1', 851 851 'phui-document-view-css' => '52b748a5',
+63
src/applications/phid/PhabricatorObjectHandle.php
··· 32 32 private $tokenIcon; 33 33 private $commandLineObjectName; 34 34 private $mailStampName; 35 + private $capabilities = array(); 35 36 36 37 public function setIcon($icon) { 37 38 $this->icon = $icon; ··· 386 387 protected function getPHIDType() { 387 388 $types = PhabricatorPHIDType::getAllTypes(); 388 389 return idx($types, $this->getType()); 390 + } 391 + 392 + public function hasCapabilities() { 393 + return ($this->getType() === PhabricatorPeopleUserPHIDType::TYPECONST); 394 + } 395 + 396 + public function attachCapability( 397 + PhabricatorPolicyInterface $object, 398 + $capability, 399 + $has_capability) { 400 + 401 + if (!$this->hasCapabilities()) { 402 + throw new Exception( 403 + pht( 404 + 'Attempting to attach capability ("%s") for object ("%s") to '. 405 + 'handle, but this handle (of type "%s") can not have '. 406 + 'capabilities.', 407 + $capability, 408 + get_class($object), 409 + $this->getType())); 410 + } 411 + 412 + $object_key = $this->getObjectCapabilityKey($object); 413 + $this->capabilities[$object_key][$capability] = $has_capability; 414 + 415 + return $this; 416 + } 417 + 418 + public function hasViewCapability(PhabricatorPolicyInterface $object) { 419 + return $this->hasCapability($object, PhabricatorPolicyCapability::CAN_VIEW); 420 + } 421 + 422 + private function hasCapability( 423 + PhabricatorPolicyInterface $object, 424 + $capability) { 425 + 426 + $object_key = $this->getObjectCapabilityKey($object); 427 + 428 + if (!isset($this->capabilities[$object_key][$capability])) { 429 + throw new Exception( 430 + pht( 431 + 'Attempting to test capability "%s" for handle of type "%s", but '. 432 + 'this capability has not been attached.', 433 + $capability, 434 + $this->getType())); 435 + } 436 + 437 + return $this->capabilities[$object_key][$capability]; 438 + } 439 + 440 + private function getObjectCapabilityKey(PhabricatorPolicyInterface $object) { 441 + $object_phid = $object->getPHID(); 442 + 443 + if (!$object_phid) { 444 + throw new Exception( 445 + pht( 446 + 'Object (of class "%s") has no PHID, so handles can not interact '. 447 + 'with capabilities for it.', 448 + get_class($object))); 449 + } 450 + 451 + return $object_phid; 389 452 } 390 453 391 454
+62
src/applications/policy/filter/PhabricatorPolicyFilterSet.php
··· 102 102 $this->queue = array(); 103 103 } 104 104 105 + public static function loadHandleViewCapabilities( 106 + $viewer, 107 + $handles, 108 + array $objects) { 109 + 110 + $capabilities = array( 111 + PhabricatorPolicyCapability::CAN_VIEW, 112 + ); 113 + 114 + assert_instances_of($objects, 'PhabricatorPolicyInterface'); 115 + 116 + if (!$objects) { 117 + return; 118 + } 119 + 120 + $viewer_map = array(); 121 + foreach ($handles as $handle_key => $handle) { 122 + if (!$handle->hasCapabilities()) { 123 + continue; 124 + } 125 + $viewer_map[$handle->getPHID()] = $handle_key; 126 + } 127 + 128 + if (!$viewer_map) { 129 + return; 130 + } 131 + 132 + $users = id(new PhabricatorPeopleQuery()) 133 + ->setViewer($viewer) 134 + ->withPHIDs(array_keys($viewer_map)) 135 + ->execute(); 136 + $users = mpull($users, null, 'getPHID'); 137 + 138 + $filter_set = new self(); 139 + 140 + foreach ($users as $user_phid => $user) { 141 + foreach ($objects as $object) { 142 + foreach ($capabilities as $capability) { 143 + $filter_set->addCapability($user, $object, $capability); 144 + } 145 + } 146 + } 147 + 148 + foreach ($users as $user_phid => $user) { 149 + $handle_key = $viewer_map[$user_phid]; 150 + $handle = $handles[$handle_key]; 151 + foreach ($objects as $object) { 152 + foreach ($capabilities as $capability) { 153 + $has_capability = $filter_set->hasCapability( 154 + $user, 155 + $object, 156 + $capability); 157 + 158 + $handle->attachCapability( 159 + $object, 160 + $capability, 161 + $has_capability); 162 + } 163 + } 164 + } 165 + } 166 + 105 167 }
+14 -1
src/applications/subscriptions/engineextension/PhabricatorSubscriptionsCurtainExtension.php
··· 62 62 $handles = $viewer->loadHandles($visible_phids); 63 63 } 64 64 65 + PhabricatorPolicyFilterSet::loadHandleViewCapabilities( 66 + $viewer, 67 + $handles, 68 + array($object)); 69 + 65 70 $ref_list = id(new PHUICurtainObjectRefListView()) 66 71 ->setViewer($viewer) 67 72 ->setEmptyMessage(pht('None')); 68 73 69 74 foreach ($visible_phids as $phid) { 75 + $handle = $handles[$phid]; 76 + 70 77 $ref = $ref_list->newObjectRefView() 71 - ->setHandle($handles[$phid]); 78 + ->setHandle($handle); 72 79 73 80 if ($phid === $viewer_phid) { 74 81 $ref->setHighlighted(true); 82 + } 83 + 84 + if ($handle->hasCapabilities()) { 85 + if (!$handle->hasViewCapability($object)) { 86 + $ref->setExiled(true); 87 + } 75 88 } 76 89 } 77 90
+29
src/view/phui/PHUICurtainObjectRefView.php
··· 6 6 private $handle; 7 7 private $epoch; 8 8 private $highlighted; 9 + private $exiled; 9 10 10 11 public function setHandle(PhabricatorObjectHandle $handle) { 11 12 $this->handle = $handle; ··· 22 23 return $this; 23 24 } 24 25 26 + public function setExiled($is_exiled) { 27 + $this->exiled = $is_exiled; 28 + return $this; 29 + } 30 + 25 31 protected function getTagAttributes() { 26 32 $classes = array(); 27 33 $classes[] = 'phui-curtain-object-ref-view'; ··· 29 35 if ($this->highlighted) { 30 36 $classes[] = 'phui-curtain-object-ref-view-highlighted'; 31 37 } 38 + 39 + if ($this->exiled) { 40 + $classes[] = 'phui-curtain-object-ref-view-exiled'; 41 + } 42 + 32 43 $classes = implode(' ', $classes); 33 44 34 45 return array( ··· 58 69 $epoch_view); 59 70 60 71 $more_rows[] = phutil_tag('tr', array(), $epoch_cells); 72 + } 73 + 74 + if ($this->exiled) { 75 + $exiled_view = array( 76 + id(new PHUIIconView())->setIcon('fa-eye-slash red'), 77 + ' ', 78 + pht('No View Permission'), 79 + ); 80 + 81 + $exiled_cells = array(); 82 + $exiled_cells[] = phutil_tag( 83 + 'td', 84 + array( 85 + 'class' => 'phui-curtain-object-ref-view-exiled-cell', 86 + ), 87 + $exiled_view); 88 + 89 + $more_rows[] = phutil_tag('tr', array(), $exiled_cells); 61 90 } 62 91 63 92 $header_cells = array();
+13
webroot/rsrc/css/phui/phui-curtain-object-ref-view.css
··· 12 12 border-radius: 3px; 13 13 } 14 14 15 + .phui-curtain-object-ref-view + .phui-curtain-object-ref-view { 16 + margin-top: 1px; 17 + } 18 + 15 19 .phui-curtain-object-ref-view-image-cell { 16 20 min-width: 32px; 17 21 padding-bottom: 24px; ··· 82 86 .phui-curtain-object-ref-view-highlighted { 83 87 background: {$bluebackground}; 84 88 } 89 + 90 + .phui-curtain-object-ref-view-exiled { 91 + background: {$lightred}; 92 + opacity: 0.75; 93 + } 94 + 95 + .phui-curtain-object-ref-view-exiled-cell { 96 + color: {$red}; 97 + }