@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

Inline custom policy rules inside policy capability explanation dialogs

Summary: Ref T13411. When users click a link to explain a capability (like the policy header on many objects, or the link next to specific capabilities in "Applications", "Diffusion", etc), inline the full ruleset for the custom policy into the dialog if the object has a custom policy.

Test Plan: {F6856365}

Maniphest Tasks: T13411

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

+176 -124
+5 -3
resources/celerity/map.php
··· 9 9 'names' => array( 10 10 'conpherence.pkg.css' => '3c8a0668', 11 11 'conpherence.pkg.js' => '020aebcf', 12 - 'core.pkg.css' => '5a4a5010', 12 + 'core.pkg.css' => 'c69171e6', 13 13 'core.pkg.js' => '73a06a9f', 14 14 'differential.pkg.css' => '8d8360fb', 15 15 'differential.pkg.js' => '0b037a4f', ··· 155 155 'rsrc/css/phui/phui-form-view.css' => '01b796c0', 156 156 'rsrc/css/phui/phui-form.css' => '159e2d9c', 157 157 'rsrc/css/phui/phui-head-thing.css' => 'd7f293df', 158 - 'rsrc/css/phui/phui-header-view.css' => '285c9139', 158 + 'rsrc/css/phui/phui-header-view.css' => 'b500eeea', 159 159 'rsrc/css/phui/phui-hovercard.css' => '6ca90fa0', 160 160 'rsrc/css/phui/phui-icon-set-selector.css' => '7aa5f3ec', 161 161 'rsrc/css/phui/phui-icon.css' => '4cbc684a', ··· 168 168 'rsrc/css/phui/phui-object-box.css' => 'f434b6be', 169 169 'rsrc/css/phui/phui-pager.css' => 'd022c7ad', 170 170 'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8', 171 + 'rsrc/css/phui/phui-policy-section-view.css' => '139fdc64', 171 172 'rsrc/css/phui/phui-property-list-view.css' => 'cad62236', 172 173 'rsrc/css/phui/phui-remarkup-preview.css' => '91767007', 173 174 'rsrc/css/phui/phui-segment-bar-view.css' => '5166b370', ··· 842 843 'phui-form-css' => '159e2d9c', 843 844 'phui-form-view-css' => '01b796c0', 844 845 'phui-head-thing-view-css' => 'd7f293df', 845 - 'phui-header-view-css' => '285c9139', 846 + 'phui-header-view-css' => 'b500eeea', 846 847 'phui-hovercard' => '074f0783', 847 848 'phui-hovercard-view-css' => '6ca90fa0', 848 849 'phui-icon-set-selector-css' => '7aa5f3ec', ··· 863 864 'phui-oi-simple-ui-css' => '6a30fa46', 864 865 'phui-pager-css' => 'd022c7ad', 865 866 'phui-pinboard-view-css' => '1f08f5d8', 867 + 'phui-policy-section-view-css' => '139fdc64', 866 868 'phui-property-list-view-css' => 'cad62236', 867 869 'phui-remarkup-preview-css' => '91767007', 868 870 'phui-segment-bar-view-css' => '5166b370',
+2
src/__phutil_library_map__.php
··· 4198 4198 'PhabricatorPolicyRef' => 'applications/policy/view/PhabricatorPolicyRef.php', 4199 4199 'PhabricatorPolicyRequestExceptionHandler' => 'aphront/handler/PhabricatorPolicyRequestExceptionHandler.php', 4200 4200 'PhabricatorPolicyRule' => 'applications/policy/rule/PhabricatorPolicyRule.php', 4201 + 'PhabricatorPolicyRulesView' => 'applications/policy/view/PhabricatorPolicyRulesView.php', 4201 4202 'PhabricatorPolicySearchEngineExtension' => 'applications/policy/engineextension/PhabricatorPolicySearchEngineExtension.php', 4202 4203 'PhabricatorPolicyStrengthConstants' => 'applications/policy/constants/PhabricatorPolicyStrengthConstants.php', 4203 4204 'PhabricatorPolicyTestCase' => 'applications/policy/__tests__/PhabricatorPolicyTestCase.php', ··· 10679 10680 'PhabricatorPolicyRef' => 'Phobject', 10680 10681 'PhabricatorPolicyRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler', 10681 10682 'PhabricatorPolicyRule' => 'Phobject', 10683 + 'PhabricatorPolicyRulesView' => 'AphrontView', 10682 10684 'PhabricatorPolicySearchEngineExtension' => 'PhabricatorSearchEngineExtension', 10683 10685 'PhabricatorPolicyStrengthConstants' => 'PhabricatorPolicyConstants', 10684 10686 'PhabricatorPolicyTestCase' => 'PhabricatorTestCase',
+8 -1
src/applications/policy/controller/PhabricatorPolicyExplainController.php
··· 318 318 ->setViewer($viewer) 319 319 ->setIcon($handle->getIcon().' bluegrey') 320 320 ->setHeader(pht('Object Policy')) 321 - ->appendList( 321 + ->appendParagraph( 322 322 array( 323 323 array( 324 324 phutil_tag('strong', array(), pht('%s:', $capability_name)), ··· 336 336 $viewer, 337 337 $policy->getPHID()), 338 338 )); 339 + 340 + if ($policy->isCustomPolicy()) { 341 + $rules_view = id(new PhabricatorPolicyRulesView()) 342 + ->setViewer($viewer) 343 + ->setPolicy($policy); 344 + $object_section->appendRulesView($rules_view); 345 + } 339 346 340 347 $strength = $this->getStrengthInformation($object, $policy, $capability); 341 348 if ($strength) {
+11 -1
src/applications/policy/view/PHUIPolicySectionView.php
··· 93 93 return $this->appendChild(phutil_tag('p', array(), $content)); 94 94 } 95 95 96 + public function appendRulesView(PhabricatorPolicyRulesView $rules_view) { 97 + return $this->appendChild( 98 + phutil_tag( 99 + 'div', 100 + array( 101 + 'class' => 'phui-policy-section-view-rules', 102 + ), 103 + $rules_view)); 104 + } 105 + 96 106 protected function getTagAttributes() { 97 107 return array( 98 108 'class' => 'phui-policy-section-view', ··· 100 110 } 101 111 102 112 protected function getTagContent() { 103 - require_celerity_resource('phui-header-view-css'); 113 + require_celerity_resource('phui-policy-section-view-css'); 104 114 105 115 $icon_view = null; 106 116 $icon = $this->getIcon();
+84
src/applications/policy/view/PhabricatorPolicyRulesView.php
··· 1 + <?php 2 + 3 + final class PhabricatorPolicyRulesView 4 + extends AphrontView { 5 + 6 + private $policy; 7 + 8 + public function setPolicy(PhabricatorPolicy $policy) { 9 + $this->policy = $policy; 10 + return $this; 11 + } 12 + 13 + public function getPolicy() { 14 + return $this->policy; 15 + } 16 + 17 + public function render() { 18 + $policy = $this->getPolicy(); 19 + 20 + require_celerity_resource('policy-transaction-detail-css'); 21 + 22 + $rule_objects = array(); 23 + foreach ($policy->getCustomRuleClasses() as $class) { 24 + $rule_objects[$class] = newv($class, array()); 25 + } 26 + 27 + $policy = clone $policy; 28 + $policy->attachRuleObjects($rule_objects); 29 + 30 + $details = array(); 31 + $details[] = phutil_tag( 32 + 'p', 33 + array( 34 + 'class' => 'policy-transaction-detail-intro', 35 + ), 36 + pht('These rules are processed in order:')); 37 + 38 + foreach ($policy->getRules() as $index => $rule) { 39 + $rule_object = $rule_objects[$rule['rule']]; 40 + if ($rule['action'] == 'allow') { 41 + $icon = 'fa-check-circle green'; 42 + } else { 43 + $icon = 'fa-minus-circle red'; 44 + } 45 + $icon = id(new PHUIIconView()) 46 + ->setIcon($icon) 47 + ->setText( 48 + ucfirst($rule['action']).' '.$rule_object->getRuleDescription()); 49 + 50 + $handle_phids = $rule_object->getRequiredHandlePHIDsForSummary( 51 + $rule['value']); 52 + if ($handle_phids) { 53 + $value = $this->getViewer() 54 + ->renderHandleList($handle_phids) 55 + ->setAsInline(true); 56 + } else { 57 + $value = $rule['value']; 58 + } 59 + 60 + $details[] = phutil_tag('div', 61 + array( 62 + 'class' => 'policy-transaction-detail-row', 63 + ), 64 + array( 65 + $icon, 66 + $value, 67 + )); 68 + } 69 + 70 + $details[] = phutil_tag( 71 + 'p', 72 + array( 73 + 'class' => 'policy-transaction-detail-end', 74 + ), 75 + pht( 76 + 'If no rules match, %s all other users.', 77 + phutil_tag('b', 78 + array(), 79 + $policy->getDefaultAction()))); 80 + 81 + return $details; 82 + } 83 + 84 + }
+4 -77
src/applications/transactions/controller/PhabricatorApplicationTransactionValueController.php
··· 58 58 return new Aphront404Response(); 59 59 } 60 60 61 - $rule_objects = array(); 62 - foreach ($policy->getCustomRuleClasses() as $class) { 63 - $rule_objects[$class] = newv($class, array()); 64 - } 65 - $policy->attachRuleObjects($rule_objects); 61 + $rules_view = id(new PhabricatorPolicyRulesView()) 62 + ->setViewer($viewer) 63 + ->setPolicy($policy); 66 64 67 - $this->requireResource('policy-transaction-detail-css'); 68 65 $cancel_uri = $this->guessCancelURI($viewer, $xaction); 69 66 70 67 return $this->newDialog() 71 68 ->setTitle($policy->getFullName()) 72 69 ->setWidth(AphrontDialogView::WIDTH_FORM) 73 - ->appendChild($this->renderPolicyDetails($policy, $rule_objects)) 70 + ->appendChild($rules_view) 74 71 ->addCancelButton($cancel_uri, pht('Close')); 75 72 } 76 - 77 - private function extractPHIDs( 78 - PhabricatorPolicy $policy, 79 - array $rule_objects) { 80 - 81 - $phids = array(); 82 - foreach ($policy->getRules() as $rule) { 83 - $rule_object = $rule_objects[$rule['rule']]; 84 - $phids[] = 85 - $rule_object->getRequiredHandlePHIDsForSummary($rule['value']); 86 - } 87 - return array_filter(array_mergev($phids)); 88 - } 89 - 90 - private function renderPolicyDetails( 91 - PhabricatorPolicy $policy, 92 - array $rule_objects) { 93 - $details = array(); 94 - $details[] = phutil_tag( 95 - 'p', 96 - array( 97 - 'class' => 'policy-transaction-detail-intro', 98 - ), 99 - pht('These rules are processed in order:')); 100 - 101 - foreach ($policy->getRules() as $index => $rule) { 102 - $rule_object = $rule_objects[$rule['rule']]; 103 - if ($rule['action'] == 'allow') { 104 - $icon = 'fa-check-circle green'; 105 - } else { 106 - $icon = 'fa-minus-circle red'; 107 - } 108 - $icon = id(new PHUIIconView()) 109 - ->setIcon($icon) 110 - ->setText( 111 - ucfirst($rule['action']).' '.$rule_object->getRuleDescription()); 112 - 113 - $handle_phids = $rule_object->getRequiredHandlePHIDsForSummary( 114 - $rule['value']); 115 - if ($handle_phids) { 116 - $value = $this->getViewer() 117 - ->renderHandleList($handle_phids) 118 - ->setAsInline(true); 119 - } else { 120 - $value = $rule['value']; 121 - } 122 - 123 - $details[] = phutil_tag('div', 124 - array( 125 - 'class' => 'policy-transaction-detail-row', 126 - ), 127 - array( 128 - $icon, 129 - $value, 130 - )); 131 - } 132 - 133 - $details[] = phutil_tag( 134 - 'p', 135 - array( 136 - 'class' => 'policy-transaction-detail-end', 137 - ), 138 - pht( 139 - 'If no rules match, %s all other users.', 140 - phutil_tag('b', 141 - array(), 142 - $policy->getDefaultAction()))); 143 - return $details; 144 - } 145 - 146 73 }
-42
webroot/rsrc/css/phui/phui-header-view.css
··· 354 354 .phui-header-view .phui-tag-indigo a { 355 355 color: {$sh-indigotext}; 356 356 } 357 - 358 - .phui-policy-section-view { 359 - margin-bottom: 24px; 360 - } 361 - 362 - .phui-policy-section-view-header { 363 - background: {$bluebackground}; 364 - border-bottom: 1px solid {$lightblueborder}; 365 - padding: 4px 8px; 366 - color: {$darkbluetext}; 367 - margin-bottom: 8px; 368 - } 369 - 370 - .phui-policy-section-view-header-text { 371 - font-weight: bold; 372 - } 373 - 374 - .phui-policy-section-view-header .phui-icon-view { 375 - margin-right: 8px; 376 - } 377 - 378 - .phui-policy-section-view-link { 379 - float: right; 380 - } 381 - 382 - .phui-policy-section-view-link .phui-icon-view { 383 - color: {$bluetext}; 384 - } 385 - 386 - .phui-policy-section-view-hint { 387 - color: {$greytext}; 388 - background: {$lightbluebackground}; 389 - padding: 8px; 390 - } 391 - 392 - .phui-policy-section-view-body { 393 - padding: 0 12px; 394 - } 395 - 396 - .phui-policy-section-view-inactive-rule { 397 - color: {$greytext}; 398 - }
+62
webroot/rsrc/css/phui/phui-policy-section-view.css
··· 1 + /** 2 + * @provides phui-policy-section-view-css 3 + */ 4 + 5 + .phui-policy-section-view { 6 + margin-bottom: 24px; 7 + } 8 + 9 + .phui-policy-section-view-header { 10 + background: {$bluebackground}; 11 + border-bottom: 1px solid {$lightblueborder}; 12 + padding: 4px 8px; 13 + color: {$darkbluetext}; 14 + margin-bottom: 8px; 15 + } 16 + 17 + .phui-policy-section-view-header-text { 18 + font-weight: bold; 19 + } 20 + 21 + .phui-policy-section-view-header .phui-icon-view { 22 + margin-right: 8px; 23 + } 24 + 25 + .phui-policy-section-view-link { 26 + float: right; 27 + } 28 + 29 + .phui-policy-section-view-link .phui-icon-view { 30 + color: {$bluetext}; 31 + } 32 + 33 + .phui-policy-section-view-hint { 34 + color: {$greytext}; 35 + background: {$lightbluebackground}; 36 + padding: 8px; 37 + } 38 + 39 + .phui-policy-section-view-body { 40 + padding: 0 12px; 41 + } 42 + 43 + .phui-policy-section-view-inactive-rule { 44 + color: {$greytext}; 45 + } 46 + 47 + .phui-policy-section-view-rules { 48 + margin: 8px 0; 49 + padding: 8px; 50 + background: {$lightbluebackground}; 51 + border: 1px solid {$lightblueborder}; 52 + } 53 + 54 + .phui-policy-section-view .phui-policy-section-view-body ul { 55 + margin: 8px 0; 56 + padding: 0 16px 0 24px; 57 + list-style: disc; 58 + } 59 + 60 + .phui-policy-section-view .phui-policy-section-view-body p + p { 61 + margin-top: 8px; 62 + }