1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-01 19:22:42 +01:00

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
This commit is contained in:
epriestley 2019-09-12 08:20:04 -07:00
parent 506f93b4a3
commit 9a36e6931c
8 changed files with 176 additions and 124 deletions

View file

@ -9,7 +9,7 @@ return array(
'names' => array( 'names' => array(
'conpherence.pkg.css' => '3c8a0668', 'conpherence.pkg.css' => '3c8a0668',
'conpherence.pkg.js' => '020aebcf', 'conpherence.pkg.js' => '020aebcf',
'core.pkg.css' => '5a4a5010', 'core.pkg.css' => 'c69171e6',
'core.pkg.js' => '73a06a9f', 'core.pkg.js' => '73a06a9f',
'differential.pkg.css' => '8d8360fb', 'differential.pkg.css' => '8d8360fb',
'differential.pkg.js' => '0b037a4f', 'differential.pkg.js' => '0b037a4f',
@ -155,7 +155,7 @@ return array(
'rsrc/css/phui/phui-form-view.css' => '01b796c0', 'rsrc/css/phui/phui-form-view.css' => '01b796c0',
'rsrc/css/phui/phui-form.css' => '159e2d9c', 'rsrc/css/phui/phui-form.css' => '159e2d9c',
'rsrc/css/phui/phui-head-thing.css' => 'd7f293df', 'rsrc/css/phui/phui-head-thing.css' => 'd7f293df',
'rsrc/css/phui/phui-header-view.css' => '285c9139', 'rsrc/css/phui/phui-header-view.css' => 'b500eeea',
'rsrc/css/phui/phui-hovercard.css' => '6ca90fa0', 'rsrc/css/phui/phui-hovercard.css' => '6ca90fa0',
'rsrc/css/phui/phui-icon-set-selector.css' => '7aa5f3ec', 'rsrc/css/phui/phui-icon-set-selector.css' => '7aa5f3ec',
'rsrc/css/phui/phui-icon.css' => '4cbc684a', 'rsrc/css/phui/phui-icon.css' => '4cbc684a',
@ -168,6 +168,7 @@ return array(
'rsrc/css/phui/phui-object-box.css' => 'f434b6be', 'rsrc/css/phui/phui-object-box.css' => 'f434b6be',
'rsrc/css/phui/phui-pager.css' => 'd022c7ad', 'rsrc/css/phui/phui-pager.css' => 'd022c7ad',
'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8', 'rsrc/css/phui/phui-pinboard-view.css' => '1f08f5d8',
'rsrc/css/phui/phui-policy-section-view.css' => '139fdc64',
'rsrc/css/phui/phui-property-list-view.css' => 'cad62236', 'rsrc/css/phui/phui-property-list-view.css' => 'cad62236',
'rsrc/css/phui/phui-remarkup-preview.css' => '91767007', 'rsrc/css/phui/phui-remarkup-preview.css' => '91767007',
'rsrc/css/phui/phui-segment-bar-view.css' => '5166b370', 'rsrc/css/phui/phui-segment-bar-view.css' => '5166b370',
@ -842,7 +843,7 @@ return array(
'phui-form-css' => '159e2d9c', 'phui-form-css' => '159e2d9c',
'phui-form-view-css' => '01b796c0', 'phui-form-view-css' => '01b796c0',
'phui-head-thing-view-css' => 'd7f293df', 'phui-head-thing-view-css' => 'd7f293df',
'phui-header-view-css' => '285c9139', 'phui-header-view-css' => 'b500eeea',
'phui-hovercard' => '074f0783', 'phui-hovercard' => '074f0783',
'phui-hovercard-view-css' => '6ca90fa0', 'phui-hovercard-view-css' => '6ca90fa0',
'phui-icon-set-selector-css' => '7aa5f3ec', 'phui-icon-set-selector-css' => '7aa5f3ec',
@ -863,6 +864,7 @@ return array(
'phui-oi-simple-ui-css' => '6a30fa46', 'phui-oi-simple-ui-css' => '6a30fa46',
'phui-pager-css' => 'd022c7ad', 'phui-pager-css' => 'd022c7ad',
'phui-pinboard-view-css' => '1f08f5d8', 'phui-pinboard-view-css' => '1f08f5d8',
'phui-policy-section-view-css' => '139fdc64',
'phui-property-list-view-css' => 'cad62236', 'phui-property-list-view-css' => 'cad62236',
'phui-remarkup-preview-css' => '91767007', 'phui-remarkup-preview-css' => '91767007',
'phui-segment-bar-view-css' => '5166b370', 'phui-segment-bar-view-css' => '5166b370',

View file

@ -4198,6 +4198,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyRef' => 'applications/policy/view/PhabricatorPolicyRef.php', 'PhabricatorPolicyRef' => 'applications/policy/view/PhabricatorPolicyRef.php',
'PhabricatorPolicyRequestExceptionHandler' => 'aphront/handler/PhabricatorPolicyRequestExceptionHandler.php', 'PhabricatorPolicyRequestExceptionHandler' => 'aphront/handler/PhabricatorPolicyRequestExceptionHandler.php',
'PhabricatorPolicyRule' => 'applications/policy/rule/PhabricatorPolicyRule.php', 'PhabricatorPolicyRule' => 'applications/policy/rule/PhabricatorPolicyRule.php',
'PhabricatorPolicyRulesView' => 'applications/policy/view/PhabricatorPolicyRulesView.php',
'PhabricatorPolicySearchEngineExtension' => 'applications/policy/engineextension/PhabricatorPolicySearchEngineExtension.php', 'PhabricatorPolicySearchEngineExtension' => 'applications/policy/engineextension/PhabricatorPolicySearchEngineExtension.php',
'PhabricatorPolicyStrengthConstants' => 'applications/policy/constants/PhabricatorPolicyStrengthConstants.php', 'PhabricatorPolicyStrengthConstants' => 'applications/policy/constants/PhabricatorPolicyStrengthConstants.php',
'PhabricatorPolicyTestCase' => 'applications/policy/__tests__/PhabricatorPolicyTestCase.php', 'PhabricatorPolicyTestCase' => 'applications/policy/__tests__/PhabricatorPolicyTestCase.php',
@ -10679,6 +10680,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyRef' => 'Phobject', 'PhabricatorPolicyRef' => 'Phobject',
'PhabricatorPolicyRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler', 'PhabricatorPolicyRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
'PhabricatorPolicyRule' => 'Phobject', 'PhabricatorPolicyRule' => 'Phobject',
'PhabricatorPolicyRulesView' => 'AphrontView',
'PhabricatorPolicySearchEngineExtension' => 'PhabricatorSearchEngineExtension', 'PhabricatorPolicySearchEngineExtension' => 'PhabricatorSearchEngineExtension',
'PhabricatorPolicyStrengthConstants' => 'PhabricatorPolicyConstants', 'PhabricatorPolicyStrengthConstants' => 'PhabricatorPolicyConstants',
'PhabricatorPolicyTestCase' => 'PhabricatorTestCase', 'PhabricatorPolicyTestCase' => 'PhabricatorTestCase',

View file

@ -318,7 +318,7 @@ final class PhabricatorPolicyExplainController
->setViewer($viewer) ->setViewer($viewer)
->setIcon($handle->getIcon().' bluegrey') ->setIcon($handle->getIcon().' bluegrey')
->setHeader(pht('Object Policy')) ->setHeader(pht('Object Policy'))
->appendList( ->appendParagraph(
array( array(
array( array(
phutil_tag('strong', array(), pht('%s:', $capability_name)), phutil_tag('strong', array(), pht('%s:', $capability_name)),
@ -337,6 +337,13 @@ final class PhabricatorPolicyExplainController
$policy->getPHID()), $policy->getPHID()),
)); ));
if ($policy->isCustomPolicy()) {
$rules_view = id(new PhabricatorPolicyRulesView())
->setViewer($viewer)
->setPolicy($policy);
$object_section->appendRulesView($rules_view);
}
$strength = $this->getStrengthInformation($object, $policy, $capability); $strength = $this->getStrengthInformation($object, $policy, $capability);
if ($strength) { if ($strength) {
$object_section->appendHint($strength); $object_section->appendHint($strength);

View file

@ -93,6 +93,16 @@ final class PHUIPolicySectionView
return $this->appendChild(phutil_tag('p', array(), $content)); return $this->appendChild(phutil_tag('p', array(), $content));
} }
public function appendRulesView(PhabricatorPolicyRulesView $rules_view) {
return $this->appendChild(
phutil_tag(
'div',
array(
'class' => 'phui-policy-section-view-rules',
),
$rules_view));
}
protected function getTagAttributes() { protected function getTagAttributes() {
return array( return array(
'class' => 'phui-policy-section-view', 'class' => 'phui-policy-section-view',
@ -100,7 +110,7 @@ final class PHUIPolicySectionView
} }
protected function getTagContent() { protected function getTagContent() {
require_celerity_resource('phui-header-view-css'); require_celerity_resource('phui-policy-section-view-css');
$icon_view = null; $icon_view = null;
$icon = $this->getIcon(); $icon = $this->getIcon();

View file

@ -0,0 +1,84 @@
<?php
final class PhabricatorPolicyRulesView
extends AphrontView {
private $policy;
public function setPolicy(PhabricatorPolicy $policy) {
$this->policy = $policy;
return $this;
}
public function getPolicy() {
return $this->policy;
}
public function render() {
$policy = $this->getPolicy();
require_celerity_resource('policy-transaction-detail-css');
$rule_objects = array();
foreach ($policy->getCustomRuleClasses() as $class) {
$rule_objects[$class] = newv($class, array());
}
$policy = clone $policy;
$policy->attachRuleObjects($rule_objects);
$details = array();
$details[] = phutil_tag(
'p',
array(
'class' => 'policy-transaction-detail-intro',
),
pht('These rules are processed in order:'));
foreach ($policy->getRules() as $index => $rule) {
$rule_object = $rule_objects[$rule['rule']];
if ($rule['action'] == 'allow') {
$icon = 'fa-check-circle green';
} else {
$icon = 'fa-minus-circle red';
}
$icon = id(new PHUIIconView())
->setIcon($icon)
->setText(
ucfirst($rule['action']).' '.$rule_object->getRuleDescription());
$handle_phids = $rule_object->getRequiredHandlePHIDsForSummary(
$rule['value']);
if ($handle_phids) {
$value = $this->getViewer()
->renderHandleList($handle_phids)
->setAsInline(true);
} else {
$value = $rule['value'];
}
$details[] = phutil_tag('div',
array(
'class' => 'policy-transaction-detail-row',
),
array(
$icon,
$value,
));
}
$details[] = phutil_tag(
'p',
array(
'class' => 'policy-transaction-detail-end',
),
pht(
'If no rules match, %s all other users.',
phutil_tag('b',
array(),
$policy->getDefaultAction())));
return $details;
}
}

View file

@ -58,89 +58,16 @@ final class PhabricatorApplicationTransactionValueController
return new Aphront404Response(); return new Aphront404Response();
} }
$rule_objects = array(); $rules_view = id(new PhabricatorPolicyRulesView())
foreach ($policy->getCustomRuleClasses() as $class) { ->setViewer($viewer)
$rule_objects[$class] = newv($class, array()); ->setPolicy($policy);
}
$policy->attachRuleObjects($rule_objects);
$this->requireResource('policy-transaction-detail-css');
$cancel_uri = $this->guessCancelURI($viewer, $xaction); $cancel_uri = $this->guessCancelURI($viewer, $xaction);
return $this->newDialog() return $this->newDialog()
->setTitle($policy->getFullName()) ->setTitle($policy->getFullName())
->setWidth(AphrontDialogView::WIDTH_FORM) ->setWidth(AphrontDialogView::WIDTH_FORM)
->appendChild($this->renderPolicyDetails($policy, $rule_objects)) ->appendChild($rules_view)
->addCancelButton($cancel_uri, pht('Close')); ->addCancelButton($cancel_uri, pht('Close'));
} }
private function extractPHIDs(
PhabricatorPolicy $policy,
array $rule_objects) {
$phids = array();
foreach ($policy->getRules() as $rule) {
$rule_object = $rule_objects[$rule['rule']];
$phids[] =
$rule_object->getRequiredHandlePHIDsForSummary($rule['value']);
}
return array_filter(array_mergev($phids));
}
private function renderPolicyDetails(
PhabricatorPolicy $policy,
array $rule_objects) {
$details = array();
$details[] = phutil_tag(
'p',
array(
'class' => 'policy-transaction-detail-intro',
),
pht('These rules are processed in order:'));
foreach ($policy->getRules() as $index => $rule) {
$rule_object = $rule_objects[$rule['rule']];
if ($rule['action'] == 'allow') {
$icon = 'fa-check-circle green';
} else {
$icon = 'fa-minus-circle red';
}
$icon = id(new PHUIIconView())
->setIcon($icon)
->setText(
ucfirst($rule['action']).' '.$rule_object->getRuleDescription());
$handle_phids = $rule_object->getRequiredHandlePHIDsForSummary(
$rule['value']);
if ($handle_phids) {
$value = $this->getViewer()
->renderHandleList($handle_phids)
->setAsInline(true);
} else {
$value = $rule['value'];
}
$details[] = phutil_tag('div',
array(
'class' => 'policy-transaction-detail-row',
),
array(
$icon,
$value,
));
}
$details[] = phutil_tag(
'p',
array(
'class' => 'policy-transaction-detail-end',
),
pht(
'If no rules match, %s all other users.',
phutil_tag('b',
array(),
$policy->getDefaultAction())));
return $details;
}
} }

View file

@ -354,45 +354,3 @@ body .phui-header-shell.phui-bleed-header
.phui-header-view .phui-tag-indigo a { .phui-header-view .phui-tag-indigo a {
color: {$sh-indigotext}; color: {$sh-indigotext};
} }
.phui-policy-section-view {
margin-bottom: 24px;
}
.phui-policy-section-view-header {
background: {$bluebackground};
border-bottom: 1px solid {$lightblueborder};
padding: 4px 8px;
color: {$darkbluetext};
margin-bottom: 8px;
}
.phui-policy-section-view-header-text {
font-weight: bold;
}
.phui-policy-section-view-header .phui-icon-view {
margin-right: 8px;
}
.phui-policy-section-view-link {
float: right;
}
.phui-policy-section-view-link .phui-icon-view {
color: {$bluetext};
}
.phui-policy-section-view-hint {
color: {$greytext};
background: {$lightbluebackground};
padding: 8px;
}
.phui-policy-section-view-body {
padding: 0 12px;
}
.phui-policy-section-view-inactive-rule {
color: {$greytext};
}

View file

@ -0,0 +1,62 @@
/**
* @provides phui-policy-section-view-css
*/
.phui-policy-section-view {
margin-bottom: 24px;
}
.phui-policy-section-view-header {
background: {$bluebackground};
border-bottom: 1px solid {$lightblueborder};
padding: 4px 8px;
color: {$darkbluetext};
margin-bottom: 8px;
}
.phui-policy-section-view-header-text {
font-weight: bold;
}
.phui-policy-section-view-header .phui-icon-view {
margin-right: 8px;
}
.phui-policy-section-view-link {
float: right;
}
.phui-policy-section-view-link .phui-icon-view {
color: {$bluetext};
}
.phui-policy-section-view-hint {
color: {$greytext};
background: {$lightbluebackground};
padding: 8px;
}
.phui-policy-section-view-body {
padding: 0 12px;
}
.phui-policy-section-view-inactive-rule {
color: {$greytext};
}
.phui-policy-section-view-rules {
margin: 8px 0;
padding: 8px;
background: {$lightbluebackground};
border: 1px solid {$lightblueborder};
}
.phui-policy-section-view .phui-policy-section-view-body ul {
margin: 8px 0;
padding: 0 16px 0 24px;
list-style: disc;
}
.phui-policy-section-view .phui-policy-section-view-body p + p {
margin-top: 8px;
}