2014-10-17 14:02:14 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class AlmanacDeviceViewController
|
|
|
|
extends AlmanacDeviceController {
|
|
|
|
|
|
|
|
public function shouldAllowPublic() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function handleRequest(AphrontRequest $request) {
|
|
|
|
$viewer = $request->getViewer();
|
|
|
|
|
|
|
|
$name = $request->getURIData('name');
|
|
|
|
|
|
|
|
$device = id(new AlmanacDeviceQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withNames(array($name))
|
2016-02-22 21:53:40 +01:00
|
|
|
->needProperties(true)
|
2014-10-17 14:02:14 +02:00
|
|
|
->executeOne();
|
|
|
|
if (!$device) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
|
|
|
$title = pht('Device %s', $device->getName());
|
|
|
|
|
2016-03-02 17:45:53 +01:00
|
|
|
$properties = $this->buildPropertyList($device);
|
|
|
|
$actions = $this->buildActionList($device);
|
2014-10-17 14:02:14 +02:00
|
|
|
|
|
|
|
$header = id(new PHUIHeaderView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setHeader($device->getName())
|
2016-03-02 17:45:53 +01:00
|
|
|
->setPolicyObject($device)
|
|
|
|
->setHeaderIcon('fa-server');
|
2014-10-17 14:02:14 +02:00
|
|
|
|
2016-03-02 17:45:53 +01:00
|
|
|
$issue = null;
|
2016-02-24 01:23:40 +01:00
|
|
|
if ($device->isClusterDevice()) {
|
2016-03-02 17:45:53 +01:00
|
|
|
$issue = $this->addClusterMessage(
|
2016-02-24 01:23:40 +01:00
|
|
|
pht('This device is bound to a cluster service.'),
|
2014-12-18 23:31:36 +01:00
|
|
|
pht(
|
2016-02-24 01:23:40 +01:00
|
|
|
'This device is bound to a cluster service. You do not have '.
|
|
|
|
'permission to manage cluster services, so the device can not '.
|
|
|
|
'be edited.'));
|
2014-12-18 23:31:36 +01:00
|
|
|
}
|
|
|
|
|
2014-10-17 14:04:24 +02:00
|
|
|
$interfaces = $this->buildInterfaceList($device);
|
|
|
|
|
2014-10-17 14:02:14 +02:00
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
|
|
|
$crumbs->addTextCrumb($device->getName());
|
2016-03-02 17:45:53 +01:00
|
|
|
$crumbs->setBorder(true);
|
2014-10-17 14:02:14 +02:00
|
|
|
|
Transactions - deploy buildTransactionTimeline against a few more applications
Summary:
Ref T4712. Thus far, it seems that most "non-standard" things can be done pretty easily in the controller. Aside from deploying, this diff had to fix a few bugs / missing implementations of stuff.
(Notably, PhabricatorAuthProviderConfig, HeraldRule, PhabricatorSlowvotePoll, and AlmanacNetwork needed to implement PhabricatorApplicationTransactionInterface, PhabricatorAuthAuthProviderPHIDType had to be added, and a rendering bug in transactions of type PhabricatorOAuth2AuthProvider had to be fixed.)
Test Plan: Almanac - looked at binding, device, network, and service view controllers and verified timeline displayed properly. Herald - looked at a rule and verified timeline. Slowvote - looked at a vote and verified timeline. Auth - looked at an auth provider (Facebook) and verified proper display of transactions within timeline.
Reviewers: epriestley
Reviewed By: epriestley
Subscribers: Korvin, epriestley
Maniphest Tasks: T4712
Differential Revision: https://secure.phabricator.com/D10921
2014-12-02 23:33:59 +01:00
|
|
|
$timeline = $this->buildTransactionTimeline(
|
|
|
|
$device,
|
|
|
|
new AlmanacDeviceTransactionQuery());
|
|
|
|
$timeline->setShouldTerminate(true);
|
2014-10-17 14:02:14 +02:00
|
|
|
|
2016-03-02 17:45:53 +01:00
|
|
|
$view = id(new PHUITwoColumnView())
|
|
|
|
->setHeader($header)
|
|
|
|
->setMainColumn(array(
|
|
|
|
$issue,
|
2015-11-28 23:46:19 +01:00
|
|
|
$interfaces,
|
|
|
|
$this->buildAlmanacPropertiesTable($device),
|
|
|
|
$this->buildSSHKeysTable($device),
|
|
|
|
$this->buildServicesTable($device),
|
|
|
|
$timeline,
|
2016-03-02 17:45:53 +01:00
|
|
|
))
|
|
|
|
->setPropertyList($properties)
|
|
|
|
->setActionList($actions);
|
|
|
|
|
|
|
|
return $this->newPage()
|
|
|
|
->setTitle($title)
|
|
|
|
->setCrumbs($crumbs)
|
|
|
|
->appendChild(
|
|
|
|
array(
|
|
|
|
$view,
|
|
|
|
));
|
2014-10-17 14:02:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private function buildPropertyList(AlmanacDevice $device) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
|
|
|
|
$properties = id(new PHUIPropertyListView())
|
2014-11-06 00:30:00 +01:00
|
|
|
->setUser($viewer)
|
|
|
|
->setObject($device);
|
2014-10-17 14:02:14 +02:00
|
|
|
|
|
|
|
return $properties;
|
|
|
|
}
|
|
|
|
|
|
|
|
private function buildActionList(AlmanacDevice $device) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$id = $device->getID();
|
|
|
|
|
|
|
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
|
|
$viewer,
|
|
|
|
$device,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
|
|
|
$actions = id(new PhabricatorActionListView())
|
|
|
|
->setUser($viewer);
|
|
|
|
|
|
|
|
$actions->addAction(
|
|
|
|
id(new PhabricatorActionView())
|
|
|
|
->setIcon('fa-pencil')
|
|
|
|
->setName(pht('Edit Device'))
|
|
|
|
->setHref($this->getApplicationURI("device/edit/{$id}/"))
|
|
|
|
->setWorkflow(!$can_edit)
|
|
|
|
->setDisabled(!$can_edit));
|
|
|
|
|
|
|
|
return $actions;
|
|
|
|
}
|
|
|
|
|
2014-10-17 14:04:24 +02:00
|
|
|
private function buildInterfaceList(AlmanacDevice $device) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$id = $device->getID();
|
|
|
|
|
|
|
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
|
|
$viewer,
|
|
|
|
$device,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
|
|
|
$interfaces = id(new AlmanacInterfaceQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withDevicePHIDs(array($device->getPHID()))
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$table = id(new AlmanacInterfaceTableView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setInterfaces($interfaces)
|
2014-12-18 23:31:36 +01:00
|
|
|
->setCanEdit($can_edit);
|
2014-10-17 14:04:24 +02:00
|
|
|
|
|
|
|
$header = id(new PHUIHeaderView())
|
2016-03-02 17:45:53 +01:00
|
|
|
->setHeader(pht('DEVICE INTERFACES'))
|
2014-10-17 14:04:24 +02:00
|
|
|
->addActionLink(
|
|
|
|
id(new PHUIButtonView())
|
|
|
|
->setTag('a')
|
|
|
|
->setHref($this->getApplicationURI("interface/edit/?deviceID={$id}"))
|
|
|
|
->setWorkflow(!$can_edit)
|
|
|
|
->setDisabled(!$can_edit)
|
|
|
|
->setText(pht('Add Interface'))
|
2016-01-28 05:38:01 +01:00
|
|
|
->setIcon('fa-plus'));
|
2014-10-17 14:04:24 +02:00
|
|
|
|
|
|
|
return id(new PHUIObjectBoxView())
|
|
|
|
->setHeader($header)
|
2016-03-02 17:45:53 +01:00
|
|
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
[Redesign] Add Table, Collapse support to ObjectBox
Summary: Converts most all tables to be directly set via `setTable` to an ObjectBox. I think this path is more flexible design wise, as we can change the box based on children, and not just CSS. We also already do this with PropertyList, Forms, ObjectList, and Header. `setCollapsed` is added to ObjectBox to all children objects to bleed to the edges (like diffs).
Test Plan: I did a grep of `appendChild($table)` as well as searches for `PHUIObjectBoxView`, also with manual opening of hundreds of files. I'm sure I missed 5-8 places. If you just appendChild($table) nothing breaks, it just looks a little funny.
Reviewers: epriestley, btrahan
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D12955
2015-05-20 21:43:34 +02:00
|
|
|
->setTable($table);
|
2014-10-17 14:04:24 +02:00
|
|
|
}
|
|
|
|
|
2014-11-11 17:20:08 +01:00
|
|
|
private function buildSSHKeysTable(AlmanacDevice $device) {
|
|
|
|
$viewer = $this->getViewer();
|
|
|
|
$id = $device->getID();
|
|
|
|
$device_phid = $device->getPHID();
|
|
|
|
|
|
|
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
|
|
|
$viewer,
|
|
|
|
$device,
|
|
|
|
PhabricatorPolicyCapability::CAN_EDIT);
|
|
|
|
|
|
|
|
$keys = id(new PhabricatorAuthSSHKeyQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withObjectPHIDs(array($device_phid))
|
|
|
|
->execute();
|
|
|
|
|
|
|
|
$table = id(new PhabricatorAuthSSHKeyTableView())
|
|
|
|
->setUser($viewer)
|
|
|
|
->setKeys($keys)
|
|
|
|
->setCanEdit($can_edit)
|
2014-11-21 02:33:30 +01:00
|
|
|
->setShowID(true)
|
|
|
|
->setShowTrusted(true)
|
2014-11-11 17:20:08 +01:00
|
|
|
->setNoDataString(pht('This device has no associated SSH public keys.'));
|
|
|
|
|
|
|
|
try {
|
|
|
|
PhabricatorSSHKeyGenerator::assertCanGenerateKeypair();
|
|
|
|
$can_generate = true;
|
|
|
|
} catch (Exception $ex) {
|
|
|
|
$can_generate = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$generate_uri = '/auth/sshkey/generate/?objectPHID='.$device_phid;
|
|
|
|
$upload_uri = '/auth/sshkey/upload/?objectPHID='.$device_phid;
|
|
|
|
|
|
|
|
$header = id(new PHUIHeaderView())
|
2016-03-02 17:45:53 +01:00
|
|
|
->setHeader(pht('SSH PUBLIC KEYS'))
|
2014-11-11 17:20:08 +01:00
|
|
|
->addActionLink(
|
|
|
|
id(new PHUIButtonView())
|
|
|
|
->setTag('a')
|
|
|
|
->setHref($generate_uri)
|
|
|
|
->setWorkflow(true)
|
|
|
|
->setDisabled(!$can_edit || !$can_generate)
|
|
|
|
->setText(pht('Generate Keypair'))
|
|
|
|
->setIcon(
|
|
|
|
id(new PHUIIconView())
|
2016-01-28 05:38:01 +01:00
|
|
|
->setIcon('fa-lock')))
|
2014-11-11 17:20:08 +01:00
|
|
|
->addActionLink(
|
|
|
|
id(new PHUIButtonView())
|
|
|
|
->setTag('a')
|
|
|
|
->setHref($upload_uri)
|
|
|
|
->setWorkflow(true)
|
|
|
|
->setDisabled(!$can_edit)
|
|
|
|
->setText(pht('Upload Public Key'))
|
|
|
|
->setIcon(
|
|
|
|
id(new PHUIIconView())
|
2016-01-28 05:38:01 +01:00
|
|
|
->setIcon('fa-upload')));
|
2014-11-11 17:20:08 +01:00
|
|
|
|
|
|
|
return id(new PHUIObjectBoxView())
|
|
|
|
->setHeader($header)
|
2016-03-02 17:45:53 +01:00
|
|
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
[Redesign] Add Table, Collapse support to ObjectBox
Summary: Converts most all tables to be directly set via `setTable` to an ObjectBox. I think this path is more flexible design wise, as we can change the box based on children, and not just CSS. We also already do this with PropertyList, Forms, ObjectList, and Header. `setCollapsed` is added to ObjectBox to all children objects to bleed to the edges (like diffs).
Test Plan: I did a grep of `appendChild($table)` as well as searches for `PHUIObjectBoxView`, also with manual opening of hundreds of files. I'm sure I missed 5-8 places. If you just appendChild($table) nothing breaks, it just looks a little funny.
Reviewers: epriestley, btrahan
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D12955
2015-05-20 21:43:34 +02:00
|
|
|
->setTable($table);
|
2014-11-11 17:20:08 +01:00
|
|
|
}
|
|
|
|
|
2014-12-18 23:31:36 +01:00
|
|
|
private function buildServicesTable(AlmanacDevice $device) {
|
2015-04-10 01:15:02 +02:00
|
|
|
$viewer = $this->getViewer();
|
2014-12-18 23:31:36 +01:00
|
|
|
|
|
|
|
// NOTE: We're loading all services so we can show hidden, locked services.
|
|
|
|
// In general, we let you know about all the things the device is bound to,
|
|
|
|
// even if you don't have permission to see their details. This is similar
|
|
|
|
// to exposing the existence of edges in other applications, with the
|
|
|
|
// addition of always letting you see that locks exist.
|
|
|
|
|
|
|
|
$services = id(new AlmanacServiceQuery())
|
|
|
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
|
|
|
->withDevicePHIDs(array($device->getPHID()))
|
|
|
|
->execute();
|
|
|
|
|
2015-04-10 01:15:02 +02:00
|
|
|
$handles = $viewer->loadHandles(mpull($services, 'getPHID'));
|
2014-12-18 23:31:36 +01:00
|
|
|
|
2016-02-24 01:23:40 +01:00
|
|
|
$icon_cluster = id(new PHUIIconView())
|
|
|
|
->setIcon('fa-sitemap');
|
2014-12-18 23:31:36 +01:00
|
|
|
|
|
|
|
$rows = array();
|
|
|
|
foreach ($services as $service) {
|
|
|
|
$rows[] = array(
|
2016-02-24 01:23:40 +01:00
|
|
|
($service->isClusterService()
|
|
|
|
? $icon_cluster
|
2014-12-18 23:31:36 +01:00
|
|
|
: null),
|
2015-04-10 01:15:02 +02:00
|
|
|
$handles->renderHandle($service->getPHID()),
|
2014-12-18 23:31:36 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$table = id(new AphrontTableView($rows))
|
|
|
|
->setNoDataString(pht('No services are bound to this device.'))
|
|
|
|
->setHeaders(
|
|
|
|
array(
|
|
|
|
null,
|
|
|
|
pht('Service'),
|
|
|
|
))
|
|
|
|
->setColumnClasses(
|
|
|
|
array(
|
|
|
|
null,
|
|
|
|
'wide pri',
|
|
|
|
));
|
|
|
|
|
|
|
|
return id(new PHUIObjectBoxView())
|
2016-03-02 17:45:53 +01:00
|
|
|
->setHeaderText(pht('BOUND SERVICES'))
|
|
|
|
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
[Redesign] Add Table, Collapse support to ObjectBox
Summary: Converts most all tables to be directly set via `setTable` to an ObjectBox. I think this path is more flexible design wise, as we can change the box based on children, and not just CSS. We also already do this with PropertyList, Forms, ObjectList, and Header. `setCollapsed` is added to ObjectBox to all children objects to bleed to the edges (like diffs).
Test Plan: I did a grep of `appendChild($table)` as well as searches for `PHUIObjectBoxView`, also with manual opening of hundreds of files. I'm sure I missed 5-8 places. If you just appendChild($table) nothing breaks, it just looks a little funny.
Reviewers: epriestley, btrahan
Subscribers: Korvin, epriestley
Differential Revision: https://secure.phabricator.com/D12955
2015-05-20 21:43:34 +02:00
|
|
|
->setTable($table);
|
2014-12-18 23:31:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-10-17 14:02:14 +02:00
|
|
|
}
|