mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-15 11:22:40 +01:00
d2df3064bc
Summary: Fixes T6741. This allows Almanac services to be locked from the CLI. Locked services (and their bindings, interfaces and devices) can not be edited. This serves two similar use cases: - For normal installs, you can protect cluster configuration from an attacker who compromises an account (or generally harden services which are intended to be difficult to edit). - For Phacility, we can lock externally-managed instance cluster configuration without having to pull any spooky tricks. Test Plan: - Locked and unlocked services. - Verified locking a service locks connected properties, bindings, binding properties, interfaces, devices, and device properties. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T6741 Differential Revision: https://secure.phabricator.com/D11006
201 lines
5 KiB
PHP
201 lines
5 KiB
PHP
<?php
|
|
|
|
abstract class AlmanacController
|
|
extends PhabricatorController {
|
|
|
|
protected function buildAlmanacPropertiesTable(
|
|
AlmanacPropertyInterface $object) {
|
|
|
|
$viewer = $this->getViewer();
|
|
$properties = $object->getAlmanacProperties();
|
|
|
|
$this->requireResource('almanac-css');
|
|
|
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
$viewer,
|
|
$object,
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
$field_list = PhabricatorCustomField::getObjectFields(
|
|
$object,
|
|
PhabricatorCustomField::ROLE_DEFAULT);
|
|
|
|
// Before reading values from the object, read defaults.
|
|
$defaults = mpull(
|
|
$field_list->getFields(),
|
|
'getValueForStorage',
|
|
'getFieldKey');
|
|
|
|
$field_list
|
|
->setViewer($viewer)
|
|
->readFieldsFromStorage($object);
|
|
|
|
Javelin::initBehavior('phabricator-tooltips', array());
|
|
|
|
$icon_builtin = id(new PHUIIconView())
|
|
->setIconFont('fa-circle')
|
|
->addSigil('has-tooltip')
|
|
->setMetadata(
|
|
array(
|
|
'tip' => pht('Builtin Property'),
|
|
'align' => 'E',
|
|
));
|
|
|
|
$icon_custom = id(new PHUIIconView())
|
|
->setIconFont('fa-circle-o grey')
|
|
->addSigil('has-tooltip')
|
|
->setMetadata(
|
|
array(
|
|
'tip' => pht('Custom Property'),
|
|
'align' => 'E',
|
|
));
|
|
|
|
$builtins = $object->getAlmanacPropertyFieldSpecifications();
|
|
|
|
// Sort fields so builtin fields appear first, then fields are ordered
|
|
// alphabetically.
|
|
$fields = $field_list->getFields();
|
|
$fields = msort($fields, 'getFieldKey');
|
|
|
|
$head = array();
|
|
$tail = array();
|
|
foreach ($fields as $field) {
|
|
$key = $field->getFieldKey();
|
|
if (isset($builtins[$key])) {
|
|
$head[$key] = $field;
|
|
} else {
|
|
$tail[$key] = $field;
|
|
}
|
|
}
|
|
|
|
$fields = $head + $tail;
|
|
|
|
$rows = array();
|
|
foreach ($fields as $key => $field) {
|
|
$value = $field->getValueForStorage();
|
|
|
|
$is_builtin = isset($builtins[$key]);
|
|
|
|
$delete_uri = $this->getApplicationURI('property/delete/');
|
|
$delete_uri = id(new PhutilURI($delete_uri))
|
|
->setQueryParams(
|
|
array(
|
|
'objectPHID' => $object->getPHID(),
|
|
'key' => $key,
|
|
));
|
|
|
|
$edit_uri = $this->getApplicationURI('property/edit/');
|
|
$edit_uri = id(new PhutilURI($edit_uri))
|
|
->setQueryParams(
|
|
array(
|
|
'objectPHID' => $object->getPHID(),
|
|
'key' => $key,
|
|
));
|
|
|
|
$delete = javelin_tag(
|
|
'a',
|
|
array(
|
|
'class' => ($can_edit
|
|
? 'button grey small'
|
|
: 'button grey small disabled'),
|
|
'sigil' => 'workflow',
|
|
'href' => $delete_uri,
|
|
),
|
|
$is_builtin ? pht('Reset') : pht('Delete'));
|
|
|
|
$default = idx($defaults, $key);
|
|
$is_default = ($default !== null && $default === $value);
|
|
|
|
$display_value = PhabricatorConfigJSON::prettyPrintJSON($value);
|
|
if ($is_default) {
|
|
$display_value = phutil_tag(
|
|
'span',
|
|
array(
|
|
'class' => 'almanac-default-property-value',
|
|
),
|
|
$display_value);
|
|
}
|
|
|
|
$display_key = $key;
|
|
if ($can_edit) {
|
|
$display_key = javelin_tag(
|
|
'a',
|
|
array(
|
|
'href' => $edit_uri,
|
|
'sigil' => 'workflow',
|
|
),
|
|
$display_key);
|
|
}
|
|
|
|
$rows[] = array(
|
|
($is_builtin ? $icon_builtin : $icon_custom),
|
|
$display_key,
|
|
$display_value,
|
|
$delete,
|
|
);
|
|
}
|
|
|
|
$table = id(new AphrontTableView($rows))
|
|
->setNoDataString(pht('No properties.'))
|
|
->setHeaders(
|
|
array(
|
|
null,
|
|
pht('Name'),
|
|
pht('Value'),
|
|
null,
|
|
))
|
|
->setColumnClasses(
|
|
array(
|
|
null,
|
|
null,
|
|
'wide',
|
|
'action',
|
|
));
|
|
|
|
$phid = $object->getPHID();
|
|
$add_uri = $this->getApplicationURI("property/edit/?objectPHID={$phid}");
|
|
|
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
$viewer,
|
|
$object,
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
$add_button = id(new PHUIButtonView())
|
|
->setTag('a')
|
|
->setHref($add_uri)
|
|
->setWorkflow(true)
|
|
->setDisabled(!$can_edit)
|
|
->setText(pht('Add Property'))
|
|
->setIcon(
|
|
id(new PHUIIconView())
|
|
->setIconFont('fa-plus'));
|
|
|
|
$header = id(new PHUIHeaderView())
|
|
->setHeader(pht('Properties'))
|
|
->addActionLink($add_button);
|
|
|
|
return id(new PHUIObjectBoxView())
|
|
->setHeader($header)
|
|
->appendChild($table);
|
|
}
|
|
|
|
protected function addLockMessage(PHUIObjectBoxView $box, $message) {
|
|
$doc_link = phutil_tag(
|
|
'a',
|
|
array(
|
|
'href' => PhabricatorEnv::getDoclink('Almanac User Guide'),
|
|
'target' => '_blank',
|
|
),
|
|
pht('Learn More'));
|
|
|
|
$error_view = id(new AphrontErrorView())
|
|
->setSeverity(AphrontErrorView::SEVERITY_WARNING)
|
|
->setErrors(
|
|
array(
|
|
array($message, ' ', $doc_link),
|
|
));
|
|
|
|
$box->setErrorView($error_view);
|
|
}
|
|
|
|
}
|