@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.

Show when objects have a non-default policy

Summary:
Fixes T6787. I'm kind of cheating a little bit here by not unifying default selection with `initializeNew(...)` methods, but I figure we can let this settle for a bit and then go do that later. It's pretty minor.

Since we're not doing templates I kind of want to swap the `'template'` key to `'type'` so maybe I'll do that too at some point.

@chad, freel free to change these, I was just trying to make them pretty obvious. I //do// think it's good for them to stand out, but my approach is probably a bit inconsistent/heavy-handed in the new design.

Test Plan:
{F525024}

{F525025}

{F525026}

{F525027}

Reviewers: btrahan, chad

Reviewed By: btrahan

Subscribers: johnny-bit, joshuaspence, chad, epriestley

Maniphest Tasks: T6787

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

+214 -22
+3 -3
resources/celerity/map.php
··· 7 7 */ 8 8 return array( 9 9 'names' => array( 10 - 'core.pkg.css' => 'd7ecac6d', 10 + 'core.pkg.css' => 'eb51e6dc', 11 11 'core.pkg.js' => 'e0117d99', 12 12 'darkconsole.pkg.js' => 'e7393ebb', 13 13 'differential.pkg.css' => '02273347', ··· 136 136 'rsrc/css/phui/phui-fontkit.css' => 'dd8ddf27', 137 137 'rsrc/css/phui/phui-form-view.css' => '808329f2', 138 138 'rsrc/css/phui/phui-form.css' => '25876baf', 139 - 'rsrc/css/phui/phui-header-view.css' => '2dd74fe0', 139 + 'rsrc/css/phui/phui-header-view.css' => 'a8e1d0ac', 140 140 'rsrc/css/phui/phui-icon.css' => 'bc766998', 141 141 'rsrc/css/phui/phui-image-mask.css' => '5a8b09c8', 142 142 'rsrc/css/phui/phui-info-panel.css' => '27ea50a1', ··· 779 779 'phui-fontkit-css' => 'dd8ddf27', 780 780 'phui-form-css' => '25876baf', 781 781 'phui-form-view-css' => '808329f2', 782 - 'phui-header-view-css' => '2dd74fe0', 782 + 'phui-header-view-css' => 'a8e1d0ac', 783 783 'phui-icon-view-css' => 'bc766998', 784 784 'phui-image-mask-css' => '5a8b09c8', 785 785 'phui-info-panel-css' => '27ea50a1',
+17
src/applications/base/PhabricatorApplication.php
··· 606 606 return idx($spec, 'template'); 607 607 } 608 608 609 + final public function getDefaultObjectTypePolicyMap() { 610 + $map = array(); 611 + 612 + foreach ($this->getCustomCapabilities() as $capability => $spec) { 613 + if (empty($spec['template'])) { 614 + continue; 615 + } 616 + if (empty($spec['capability'])) { 617 + continue; 618 + } 619 + $default = $this->getPolicy($capability); 620 + $map[$spec['template']][$spec['capability']] = $default; 621 + } 622 + 623 + return $map; 624 + } 625 + 609 626 public function getApplicationSearchDocumentTypes() { 610 627 return array(); 611 628 }
+1
src/applications/countdown/application/PhabricatorCountdownApplication.php
··· 53 53 PhabricatorCountdownDefaultViewCapability::CAPABILITY => array( 54 54 'caption' => pht('Default view policy for new countdowns.'), 55 55 'template' => PhabricatorCountdownCountdownPHIDType::TYPECONST, 56 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 56 57 ), 57 58 ); 58 59 }
+1
src/applications/differential/application/PhabricatorDifferentialApplication.php
··· 187 187 DifferentialDefaultViewCapability::CAPABILITY => array( 188 188 'caption' => pht('Default view policy for newly created revisions.'), 189 189 'template' => DifferentialRevisionPHIDType::TYPECONST, 190 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 190 191 ), 191 192 ); 192 193 }
+2
src/applications/diffusion/application/PhabricatorDiffusionApplication.php
··· 142 142 return array( 143 143 DiffusionDefaultViewCapability::CAPABILITY => array( 144 144 'template' => PhabricatorRepositoryRepositoryPHIDType::TYPECONST, 145 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 145 146 ), 146 147 DiffusionDefaultEditCapability::CAPABILITY => array( 147 148 'default' => PhabricatorPolicies::POLICY_ADMIN, 148 149 'template' => PhabricatorRepositoryRepositoryPHIDType::TYPECONST, 150 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 149 151 ), 150 152 DiffusionDefaultPushCapability::CAPABILITY => array( 151 153 'template' => PhabricatorRepositoryRepositoryPHIDType::TYPECONST,
+2
src/applications/diviner/application/PhabricatorDivinerApplication.php
··· 57 57 return array( 58 58 DivinerDefaultViewCapability::CAPABILITY => array( 59 59 'template' => DivinerBookPHIDType::TYPECONST, 60 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 60 61 ), 61 62 DivinerDefaultEditCapability::CAPABILITY => array( 62 63 'default' => PhabricatorPolicies::POLICY_ADMIN, 63 64 'template' => DivinerBookPHIDType::TYPECONST, 65 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 64 66 ), 65 67 ); 66 68 }
+2
src/applications/drydock/application/PhabricatorDrydockApplication.php
··· 74 74 return array( 75 75 DrydockDefaultViewCapability::CAPABILITY => array( 76 76 'template' => DrydockBlueprintPHIDType::TYPECONST, 77 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 77 78 ), 78 79 DrydockDefaultEditCapability::CAPABILITY => array( 79 80 'default' => PhabricatorPolicies::POLICY_ADMIN, 80 81 'template' => DrydockBlueprintPHIDType::TYPECONST, 82 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 81 83 ), 82 84 DrydockCreateBlueprintsCapability::CAPABILITY => array( 83 85 'default' => PhabricatorPolicies::POLICY_ADMIN,
+1
src/applications/files/application/PhabricatorFilesApplication.php
··· 61 61 FilesDefaultViewCapability::CAPABILITY => array( 62 62 'caption' => pht('Default view policy for newly created files.'), 63 63 'template' => PhabricatorFileFilePHIDType::TYPECONST, 64 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 64 65 ), 65 66 ); 66 67 }
+2
src/applications/legalpad/application/PhabricatorLegalpadApplication.php
··· 77 77 LegalpadCreateDocumentsCapability::CAPABILITY => array(), 78 78 LegalpadDefaultViewCapability::CAPABILITY => array( 79 79 'template' => PhabricatorLegalpadDocumentPHIDType::TYPECONST, 80 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 80 81 ), 81 82 LegalpadDefaultEditCapability::CAPABILITY => array( 82 83 'template' => PhabricatorLegalpadDocumentPHIDType::TYPECONST, 84 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 83 85 ), 84 86 ); 85 87 }
+2
src/applications/maniphest/application/PhabricatorManiphestApplication.php
··· 132 132 ManiphestDefaultViewCapability::CAPABILITY => array( 133 133 'caption' => pht('Default view policy for newly created tasks.'), 134 134 'template' => ManiphestTaskPHIDType::TYPECONST, 135 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 135 136 ), 136 137 ManiphestDefaultEditCapability::CAPABILITY => array( 137 138 'caption' => pht('Default edit policy for newly created tasks.'), 138 139 'template' => ManiphestTaskPHIDType::TYPECONST, 140 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 139 141 ), 140 142 ManiphestEditStatusCapability::CAPABILITY => array(), 141 143 ManiphestEditAssignCapability::CAPABILITY => array(),
+2
src/applications/nuance/application/PhabricatorNuanceApplication.php
··· 73 73 NuanceSourceDefaultViewCapability::CAPABILITY => array( 74 74 'caption' => pht('Default view policy for newly created sources.'), 75 75 'template' => NuanceSourcePHIDType::TYPECONST, 76 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 76 77 ), 77 78 NuanceSourceDefaultEditCapability::CAPABILITY => array( 78 79 'caption' => pht('Default edit policy for newly created sources.'), 79 80 'template' => NuanceSourcePHIDType::TYPECONST, 81 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 80 82 ), 81 83 NuanceSourceManageCapability::CAPABILITY => array(), 82 84 );
+2
src/applications/passphrase/application/PhabricatorPassphraseApplication.php
··· 71 71 PassphraseDefaultViewCapability::CAPABILITY => array( 72 72 'caption' => pht('Default view policy for newly created credentials.'), 73 73 'template' => PassphraseCredentialPHIDType::TYPECONST, 74 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 74 75 'default' => $policy_key, 75 76 ), 76 77 PassphraseDefaultEditCapability::CAPABILITY => array( 77 78 'caption' => pht('Default edit policy for newly created credentials.'), 78 79 'template' => PassphraseCredentialPHIDType::TYPECONST, 80 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 79 81 'default' => $policy_key, 80 82 ), 81 83 );
+2
src/applications/paste/application/PhabricatorPasteApplication.php
··· 65 65 PasteDefaultViewCapability::CAPABILITY => array( 66 66 'caption' => pht('Default view policy for newly created pastes.'), 67 67 'template' => PhabricatorPastePastePHIDType::TYPECONST, 68 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 68 69 ), 69 70 PasteDefaultEditCapability::CAPABILITY => array( 70 71 'caption' => pht('Default edit policy for newly created pastes.'), 71 72 'template' => PhabricatorPastePastePHIDType::TYPECONST, 73 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 72 74 ), 73 75 ); 74 76 }
+2
src/applications/pholio/application/PhabricatorPholioApplication.php
··· 73 73 return array( 74 74 PholioDefaultViewCapability::CAPABILITY => array( 75 75 'template' => PholioMockPHIDType::TYPECONST, 76 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 76 77 ), 77 78 PholioDefaultEditCapability::CAPABILITY => array( 78 79 'template' => PholioMockPHIDType::TYPECONST, 80 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 79 81 ), 80 82 ); 81 83 }
-4
src/applications/policy/controller/PhabricatorPolicyEditController.php
··· 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $this->getViewer(); 8 8 9 - // TODO: This doesn't do anything yet, but sets up template policies; see 10 - // T6860. 11 - $is_template = false; 12 9 13 10 $object_phid = $request->getURIData('objectPHID'); 14 11 if ($object_phid) { ··· 23 20 $object_type = $request->getURIData('objectType'); 24 21 if (!$object_type) { 25 22 $object_type = $request->getURIData('templateType'); 26 - $is_template = true; 27 23 } 28 24 29 25 $phid_types = PhabricatorPHIDType::getAllInstalledTypes($viewer);
+51 -14
src/applications/policy/controller/PhabricatorPolicyExplainController.php
··· 3 3 final class PhabricatorPolicyExplainController 4 4 extends PhabricatorPolicyController { 5 5 6 - private $phid; 7 - private $capability; 8 - 9 6 public function shouldAllowPublic() { 10 7 return true; 11 8 } 12 9 13 - public function willProcessRequest(array $data) { 14 - $this->phid = $data['phid']; 15 - $this->capability = $data['capability']; 16 - } 10 + public function handleRequest(AphrontRequest $request) { 11 + $viewer = $this->getViewer(); 17 12 18 - public function processRequest() { 19 - $request = $this->getRequest(); 20 - $viewer = $request->getUser(); 21 - 22 - $phid = $this->phid; 23 - $capability = $this->capability; 13 + $phid = $request->getURIData('phid'); 14 + $capability = $request->getURIData('capability'); 24 15 25 16 $object = id(new PhabricatorObjectQuery()) 26 17 ->setViewer($viewer) ··· 84 75 $handle->getTypeName(), 85 76 $handle->getObjectName()); 86 77 87 - return $dialog 78 + $dialog 88 79 ->setTitle(pht('Policy Details: %s', $object_name)) 89 80 ->appendParagraph($intro) 90 81 ->appendChild($auto_info) 91 82 ->addCancelButton($object_uri, pht('Done')); 83 + 84 + $this->appendStrengthInformation($dialog, $object, $policy, $capability); 85 + 86 + return $dialog; 92 87 } 93 88 94 89 private function appendSpaceInformation( ··· 178 173 pht( 179 174 'After a user passes space policy checks, they must still pass '. 180 175 'object policy checks.')); 176 + } 177 + 178 + private function appendStrengthInformation( 179 + AphrontDialogView $dialog, 180 + PhabricatorPolicyInterface $object, 181 + PhabricatorPolicy $policy, 182 + $capability) { 183 + $viewer = $this->getViewer(); 184 + 185 + $default_policy = PhabricatorPolicyQuery::getDefaultPolicyForObject( 186 + $viewer, 187 + $object, 188 + $capability); 189 + if (!$default_policy) { 190 + return; 191 + } 192 + 193 + if ($default_policy->getPHID() == $policy->getPHID()) { 194 + return; 195 + } 196 + 197 + if ($default_policy->isStrongerThan($policy)) { 198 + $info = pht( 199 + 'This object has a less restrictive policy ("%s") than the default '. 200 + 'policy for similar objects (which is "%s").', 201 + $policy->getShortName(), 202 + $default_policy->getShortName()); 203 + } else if ($policy->isStrongerThan($default_policy)) { 204 + $info = pht( 205 + 'This object has a more restrictive policy ("%s") than the default '. 206 + 'policy for similar objects (which is "%s").', 207 + $policy->getShortName(), 208 + $default_policy->getShortName()); 209 + } else { 210 + $info = pht( 211 + 'This object has a different policy ("%s") than the default policy '. 212 + 'for similar objects (which is "%s").', 213 + $policy->getShortName(), 214 + $default_policy->getShortName()); 215 + } 216 + 217 + $dialog->appendParagraph($info); 181 218 } 182 219 183 220 }
+41
src/applications/policy/query/PhabricatorPolicyQuery.php
··· 342 342 return $results; 343 343 } 344 344 345 + public static function getDefaultPolicyForObject( 346 + PhabricatorUser $viewer, 347 + PhabricatorPolicyInterface $object, 348 + $capability) { 349 + 350 + $phid = $object->getPHID(); 351 + if (!$phid) { 352 + return null; 353 + } 354 + 355 + $type = phid_get_type($phid); 356 + 357 + $map = self::getDefaultObjectTypePolicyMap(); 358 + 359 + if (empty($map[$type][$capability])) { 360 + return null; 361 + } 362 + 363 + $policy_phid = $map[$type][$capability]; 364 + 365 + return id(new PhabricatorPolicyQuery()) 366 + ->setViewer($viewer) 367 + ->withPHIDs(array($policy_phid)) 368 + ->executeOne(); 369 + } 370 + 371 + private static function getDefaultObjectTypePolicyMap() { 372 + static $map; 373 + 374 + if ($map === null) { 375 + $map = array(); 376 + 377 + $apps = PhabricatorApplication::getAllApplications(); 378 + foreach ($apps as $app) { 379 + $map += $app->getDefaultObjectTypePolicyMap(); 380 + } 381 + } 382 + 383 + return $map; 384 + } 385 + 345 386 346 387 }
+3
src/applications/project/application/PhabricatorProjectApplication.php
··· 121 121 ProjectDefaultViewCapability::CAPABILITY => array( 122 122 'caption' => pht('Default view policy for newly created projects.'), 123 123 'template' => PhabricatorProjectProjectPHIDType::TYPECONST, 124 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 124 125 ), 125 126 ProjectDefaultEditCapability::CAPABILITY => array( 126 127 'caption' => pht('Default edit policy for newly created projects.'), 127 128 'template' => PhabricatorProjectProjectPHIDType::TYPECONST, 129 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 128 130 ), 129 131 ProjectDefaultJoinCapability::CAPABILITY => array( 130 132 'caption' => pht('Default join policy for newly created projects.'), 131 133 'template' => PhabricatorProjectProjectPHIDType::TYPECONST, 134 + 'capability' => PhabricatorPolicyCapability::CAN_JOIN, 132 135 ), 133 136 ); 134 137 }
+1
src/applications/slowvote/application/PhabricatorSlowvoteApplication.php
··· 65 65 PhabricatorSlowvoteDefaultViewCapability::CAPABILITY => array( 66 66 'caption' => pht('Default view policy for new polls.'), 67 67 'template' => PhabricatorSlowvotePollPHIDType::TYPECONST, 68 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 68 69 ), 69 70 ); 70 71 }
+2
src/applications/spaces/application/PhabricatorSpacesApplication.php
··· 74 74 PhabricatorSpacesCapabilityDefaultView::CAPABILITY => array( 75 75 'caption' => pht('Default view policy for newly created spaces.'), 76 76 'template' => PhabricatorSpacesNamespacePHIDType::TYPECONST, 77 + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, 77 78 ), 78 79 PhabricatorSpacesCapabilityDefaultEdit::CAPABILITY => array( 79 80 'caption' => pht('Default edit policy for newly created spaces.'), 80 81 'default' => PhabricatorPolicies::POLICY_ADMIN, 81 82 'template' => PhabricatorSpacesNamespacePHIDType::TYPECONST, 83 + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, 82 84 ), 83 85 ); 84 86 }
+40 -1
src/view/phui/PHUIHeaderView.php
··· 292 292 // NOTE: We'll do this even if the viewer has access to only one space, and 293 293 // show them information about the existence of spaces if they click 294 294 // through. 295 + $use_space_policy = false; 295 296 if ($object instanceof PhabricatorSpacesInterface) { 296 297 $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID( 297 298 $object); ··· 306 307 if ($space_policy) { 307 308 if ($space_policy->isStrongerThan($policy)) { 308 309 $policy = $space_policy; 310 + $use_space_policy = true; 309 311 } 310 312 } 311 313 } 312 314 } 313 315 316 + $container_classes = array(); 317 + $container_classes[] = 'policy-header-callout'; 314 318 $phid = $object->getPHID(); 315 319 320 + // If we're going to show the object policy, try to determine if the object 321 + // policy differs from the default policy. If it does, we'll call it out 322 + // as changed. 323 + if (!$use_space_policy) { 324 + $default_policy = PhabricatorPolicyQuery::getDefaultPolicyForObject( 325 + $viewer, 326 + $object, 327 + $view_capability); 328 + if ($default_policy) { 329 + if ($default_policy->getPHID() != $policy->getPHID()) { 330 + $container_classes[] = 'policy-adjusted'; 331 + if ($default_policy->isStrongerThan($policy)) { 332 + // The policy has strictly been weakened. For example, the 333 + // default might be "All Users" and the current policy is "Public". 334 + $container_classes[] = 'policy-adjusted-weaker'; 335 + } else if ($policy->isStrongerThan($default_policy)) { 336 + // The policy has strictly been strengthened, and is now more 337 + // restrictive than the default. For example, "All Users" has 338 + // been replaced with "No One". 339 + $container_classes[] = 'policy-adjusted-stronger'; 340 + } else { 341 + // The policy has been adjusted but not strictly strengthened 342 + // or weakened. For example, "Members of X" has been replaced with 343 + // "Members of Y". 344 + $container_classes[] = 'policy-adjusted-different'; 345 + } 346 + } 347 + } 348 + } 349 + 316 350 $icon = id(new PHUIIconView()) 317 351 ->setIconFont($policy->getIcon().' bluegrey'); 318 352 ··· 325 359 ), 326 360 $policy->getShortName()); 327 361 328 - return array($icon, $link); 362 + return phutil_tag( 363 + 'span', 364 + array( 365 + 'class' => implode(' ', $container_classes), 366 + ), 367 + array($icon, $link)); 329 368 } 330 369 331 370 }
+35
webroot/rsrc/css/phui/phui-header-view.css
··· 116 116 color: {$darkbluetext}; 117 117 } 118 118 119 + .policy-header-callout.policy-adjusted { 120 + padding: 0 4px; 121 + border-radius: 3px; 122 + } 123 + 124 + .policy-header-callout.policy-adjusted-weaker { 125 + background: {$lightgreen}; 126 + border: 1px solid {$green}; 127 + } 128 + 129 + .policy-header-callout.policy-adjusted-weaker .policy-link, 130 + .policy-header-callout.policy-adjusted-weaker .phui-icon-view { 131 + color: {$green}; 132 + } 133 + 134 + .policy-header-callout.policy-adjusted-stronger { 135 + background: {$lightred}; 136 + border: 1px solid {$red}; 137 + } 138 + 139 + .policy-header-callout.policy-adjusted-stronger .policy-link, 140 + .policy-header-callout.policy-adjusted-stronger .phui-icon-view { 141 + color: {$red}; 142 + } 143 + 144 + .policy-header-callout.policy-adjusted-different { 145 + background: {$lightorange}; 146 + border: 1px solid {$orange}; 147 + } 148 + 149 + .policy-header-callout.policy-adjusted-different .policy-link, 150 + .policy-header-callout.policy-adjusted-different .phui-icon-view { 151 + color: {$orange}; 152 + } 153 + 119 154 .phui-header-subheader .phui-header-status-dark { 120 155 color: {$indigo}; 121 156 text-shadow: 0 1px #fff;