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

Give policy name rendering explicit "text name", "capability link", and "transaction link" pathways

Summary:
Ref T13411. This cleans up policy name rendering. We ultimately render into three contexts:

- Plain text contexts, like `bin/policy show`.
- Transaction contexts, where we're showing a policy change. In these cases, we link some policies (like project policies and custom policies) but the links go directly to the relevant object or a minimal explanation of the change. We don't link policies like "All Users".
- Capability contexts, where we're describing a capability, like "Can Push" or cases in Applicaitons. In these cases, we link all policies to the full policy explanation flow.

Test Plan:
- Used `bin/policy show` to examine the policy of an object with a project policy, no longer saw HTML.
- Viewed the transaction logs of Applications (ModularTransactions) and Tasks (not ModularTransactions) with policy edits, including project and custom policies.
- Clicked "Custom Policy" in both logs, got consistent dialogs.
- Viewed application detail pages, saw all capabities linked to explanatory capability dialogs. The value of having this dialog is that the user can get a full explanation of special rules even if the policy is something mundane like "All Users".

Maniphest Tasks: T13411

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

+146 -50
+2
src/__phutil_library_map__.php
··· 4195 4195 'PhabricatorPolicyManagementWorkflow' => 'applications/policy/management/PhabricatorPolicyManagementWorkflow.php', 4196 4196 'PhabricatorPolicyPHIDTypePolicy' => 'applications/policy/phid/PhabricatorPolicyPHIDTypePolicy.php', 4197 4197 'PhabricatorPolicyQuery' => 'applications/policy/query/PhabricatorPolicyQuery.php', 4198 + 'PhabricatorPolicyRef' => 'applications/policy/view/PhabricatorPolicyRef.php', 4198 4199 'PhabricatorPolicyRequestExceptionHandler' => 'aphront/handler/PhabricatorPolicyRequestExceptionHandler.php', 4199 4200 'PhabricatorPolicyRule' => 'applications/policy/rule/PhabricatorPolicyRule.php', 4200 4201 'PhabricatorPolicySearchEngineExtension' => 'applications/policy/engineextension/PhabricatorPolicySearchEngineExtension.php', ··· 10675 10676 'PhabricatorPolicyManagementWorkflow' => 'PhabricatorManagementWorkflow', 10676 10677 'PhabricatorPolicyPHIDTypePolicy' => 'PhabricatorPHIDType', 10677 10678 'PhabricatorPolicyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 10679 + 'PhabricatorPolicyRef' => 'Phobject', 10678 10680 'PhabricatorPolicyRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler', 10679 10681 'PhabricatorPolicyRule' => 'Phobject', 10680 10682 'PhabricatorPolicySearchEngineExtension' => 'PhabricatorSearchEngineExtension',
+3 -1
src/applications/policy/management/PhabricatorPolicyManagementShowWorkflow.php
··· 60 60 61 61 $console->writeOut("__%s__\n\n", pht('CAPABILITIES')); 62 62 foreach ($policies as $capability => $policy) { 63 + $ref = $policy->newRef($viewer); 64 + 63 65 $console->writeOut(" **%s**\n", $capability); 64 - $console->writeOut(" %s\n", $policy->renderDescription()); 66 + $console->writeOut(" %s\n", $ref->getPolicyDisplayName()); 65 67 $console->writeOut(" %s\n", 66 68 PhabricatorPolicy::getPolicyExplanation($viewer, $policy->getPHID())); 67 69 $console->writeOut("\n");
+2 -1
src/applications/policy/query/PhabricatorPolicyQuery.php
··· 48 48 $policies = self::loadPolicies($viewer, $object); 49 49 50 50 foreach ($policies as $capability => $policy) { 51 - $policies[$capability] = $policy->renderDescription(); 51 + $policies[$capability] = $policy->newRef($viewer) 52 + ->newCapabilityLink($object, $capability); 52 53 } 53 54 54 55 return $policies;
+15 -25
src/applications/policy/storage/PhabricatorPolicy.php
··· 276 276 } 277 277 } 278 278 279 - public function renderDescription() { 280 - if ($this->getHref()) { 281 - $desc = javelin_tag( 282 - 'a', 283 - array( 284 - 'href' => $this->getHref(), 285 - 'class' => 'policy-link', 286 - 'sigil' => $this->getWorkflow() ? 'workflow' : null, 287 - ), 288 - $this->getName()); 289 - } else { 290 - $desc = $this->getName(); 291 - } 279 + public function newRef(PhabricatorUser $viewer) { 280 + return id(new PhabricatorPolicyRef()) 281 + ->setViewer($viewer) 282 + ->setPolicy($this); 283 + } 292 284 293 - switch ($this->getType()) { 294 - case PhabricatorPolicyType::TYPE_PROJECT: 295 - return pht('%s (Project)', $desc); 296 - case PhabricatorPolicyType::TYPE_CUSTOM: 297 - return $desc; 298 - case PhabricatorPolicyType::TYPE_MASKED: 299 - return pht( 300 - '%s (You do not have permission to view policy details.)', 301 - $desc); 302 - default: 303 - return $desc; 304 - } 285 + public function isProjectPolicy() { 286 + return ($this->getType() === PhabricatorPolicyType::TYPE_PROJECT); 287 + } 288 + 289 + public function isCustomPolicy() { 290 + return ($this->getType() === PhabricatorPolicyType::TYPE_CUSTOM); 291 + } 292 + 293 + public function isMaskedPolicy() { 294 + return ($this->getType() === PhabricatorPolicyType::TYPE_MASKED); 305 295 } 306 296 307 297 /**
+99
src/applications/policy/view/PhabricatorPolicyRef.php
··· 1 + <?php 2 + 3 + final class PhabricatorPolicyRef 4 + extends Phobject { 5 + 6 + private $viewer; 7 + private $policy; 8 + 9 + public function setViewer(PhabricatorUser $viewer) { 10 + $this->viewer = $viewer; 11 + return $this; 12 + } 13 + 14 + public function getViewer() { 15 + return $this->viewer; 16 + } 17 + 18 + public function setPolicy(PhabricatorPolicy $policy) { 19 + $this->policy = $policy; 20 + return $this; 21 + } 22 + 23 + public function getPolicy() { 24 + return $this->policy; 25 + } 26 + 27 + public function getPolicyDisplayName() { 28 + $policy = $this->getPolicy(); 29 + return $policy->getFullName(); 30 + } 31 + 32 + public function newTransactionLink( 33 + $mode, 34 + PhabricatorApplicationTransaction $xaction) { 35 + 36 + $policy = $this->getPolicy(); 37 + 38 + if ($policy->isCustomPolicy()) { 39 + $uri = urisprintf( 40 + '/transactions/%s/%s/', 41 + $mode, 42 + $xaction->getPHID()); 43 + $workflow = true; 44 + } else { 45 + $uri = $policy->getHref(); 46 + $workflow = false; 47 + } 48 + 49 + return $this->newLink($uri, $workflow); 50 + } 51 + 52 + public function newCapabilityLink($object, $capability) { 53 + $policy = $this->getPolicy(); 54 + 55 + $uri = urisprintf( 56 + '/policy/explain/%s/%s/', 57 + $object->getPHID(), 58 + $capability); 59 + 60 + return $this->newLink($uri, true); 61 + } 62 + 63 + private function newLink($uri, $workflow) { 64 + $policy = $this->getPolicy(); 65 + $name = $policy->getName(); 66 + 67 + if ($uri !== null) { 68 + $name = javelin_tag( 69 + 'a', 70 + array( 71 + 'href' => $uri, 72 + 'sigil' => ($workflow ? 'workflow' : null), 73 + ), 74 + $name); 75 + } 76 + 77 + $hint = $this->getPolicyTypeHint(); 78 + if ($hint !== null) { 79 + $name = pht('%s (%s)', $name, $hint); 80 + } 81 + 82 + return $name; 83 + } 84 + 85 + private function getPolicyTypeHint() { 86 + $policy = $this->getPolicy(); 87 + 88 + if ($policy->isProjectPolicy()) { 89 + return pht('Project'); 90 + } 91 + 92 + if ($policy->isMaskedPolicy()) { 93 + return pht('You do not have permission to view policy details.'); 94 + } 95 + 96 + return null; 97 + } 98 + 99 + }
+6 -10
src/applications/transactions/storage/PhabricatorApplicationTransaction.php
··· 445 445 $policy = PhabricatorPolicy::newFromPolicyAndHandle( 446 446 $phid, 447 447 $this->getHandleIfExists($phid)); 448 + 449 + $ref = $policy->newRef($this->getViewer()); 450 + 448 451 if ($this->renderingTarget == self::TARGET_HTML) { 449 - switch ($policy->getType()) { 450 - case PhabricatorPolicyType::TYPE_CUSTOM: 451 - $policy->setHref('/transactions/'.$state.'/'.$this->getPHID().'/'); 452 - $policy->setWorkflow(true); 453 - break; 454 - default: 455 - break; 456 - } 457 - $output = $policy->renderDescription(); 452 + $output = $ref->newTransactionLink($state, $this); 458 453 } else { 459 - $output = hsprintf('%s', $policy->getFullName()); 454 + $output = $ref->getPolicyDisplayName(); 460 455 } 456 + 461 457 return $output; 462 458 } 463 459
+7 -8
src/applications/transactions/storage/PhabricatorModularTransactionType.php
··· 215 215 $phid, 216 216 $handles[$phid]); 217 217 218 + $ref = $policy->newRef($viewer); 219 + 218 220 if ($this->isTextMode()) { 219 - return $this->renderValue($policy->getFullName()); 221 + $name = $ref->getPolicyDisplayName(); 222 + } else { 223 + $storage = $this->getStorage(); 224 + $name = $ref->newTransactionLink($mode, $storage); 220 225 } 221 226 222 - $storage = $this->getStorage(); 223 - if ($policy->getType() == PhabricatorPolicyType::TYPE_CUSTOM) { 224 - $policy->setHref('/transactions/'.$mode.'/'.$storage->getPHID().'/'); 225 - $policy->setWorkflow(true); 226 - } 227 - 228 - return $this->renderValue($policy->renderDescription()); 227 + return $this->renderValue($name); 229 228 } 230 229 231 230 final protected function renderHandleList(array $phids) {
+12 -5
src/docs/user/userguide/unlocking.diviner
··· 63 63 Unlocking Objects 64 64 ================= 65 65 66 - If you aren't sure who owns an object, or no user account has access to an 67 - object, you can directly change object policies from the CLI: 66 + If you aren't sure who owns an object, you can inspect the policies from the 67 + CLI: 68 + 69 + ``` 70 + $ ./bin/policy show <object> 71 + ``` 72 + 73 + To identify the object you want to examine, you can specify an object 74 + name (like `T123`) or a PHID as the `<object>` parameter. 75 + 76 + If examining the policy isn't helpful, or no user account has access to an 77 + object, you can then directly change object policies from the CLI: 68 78 69 79 ``` 70 80 $ ./bin/policy unlock <object> [--view ...] [--edit ...] [--owner ...] 71 81 ``` 72 - 73 - To identify the object you want to unlock, you can specify an object name (like 74 - `T123`) or a PHID as the `<object>` parameter. 75 82 76 83 Use the `--view` and `--edit` flags (and, for some objects, the `--owner` 77 84 flag) to specify new policies for the object.