Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15418875
D10400.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
14 KB
Referenced Files
None
Subscribers
None
D10400.diff
View Options
diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,8 @@
/conf/local/local.json
/conf/local/ENVIRONMENT
/conf/local/VERSION
+/conf/local/HOSTKEY
+/conf/local/HOSTID
# Impact Font
/resources/font/impact.ttf
diff --git a/bin/almanac b/bin/almanac
new file mode 120000
--- /dev/null
+++ b/bin/almanac
@@ -0,0 +1 @@
+../scripts/almanac/manage_almanac.php
\ No newline at end of file
diff --git a/resources/sql/autopatches/20140902.almanacdevice.1.sql b/resources/sql/autopatches/20140902.almanacdevice.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20140902.almanacdevice.1.sql
@@ -0,0 +1,18 @@
+CREATE TABLE {$NAMESPACE}_almanac.almanac_device (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARBINARY(64) NOT NULL,
+ name VARCHAR(255) NOT NULL COLLATE {$COLLATE_TEXT},
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ UNIQUE KEY `key_phid` (phid)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
+
+CREATE TABLE {$NAMESPACE}_almanac.almanac_deviceproperty (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ devicePHID VARBINARY(64) NOT NULL,
+ `key` VARCHAR(128) NOT NULL COLLATE {$COLLATE_TEXT},
+ value LONGTEXT NOT NULL,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+ KEY `key_device` (devicePHID, `key`)
+) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
diff --git a/scripts/almanac/manage_almanac.php b/scripts/almanac/manage_almanac.php
new file mode 100755
--- /dev/null
+++ b/scripts/almanac/manage_almanac.php
@@ -0,0 +1,21 @@
+#!/usr/bin/env php
+<?php
+
+$root = dirname(dirname(dirname(__FILE__)));
+require_once $root.'/scripts/__init_script__.php';
+
+$args = new PhutilArgumentParser($argv);
+$args->setTagline('manage host directory');
+$args->setSynopsis(<<<EOSYNOPSIS
+**almanac** __commmand__ [__options__]
+ Manage Almanac stuff. NEW AND EXPERIMENTAL.
+
+EOSYNOPSIS
+);
+$args->parseStandardArguments();
+
+$workflows = id(new PhutilSymbolLoader())
+ ->setAncestorClass('AlmanacManagementWorkflow')
+ ->loadObjects();
+$workflows[] = new PhutilHelpArgumentWorkflow();
+$args->parseWorkflows($workflows);
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -9,6 +9,14 @@
phutil_register_library_map(array(
'__library_version__' => 2,
'class' => array(
+ 'AlmanacConduitUtil' => 'applications/almanac/util/AlmanacConduitUtil.php',
+ 'AlmanacDAO' => 'applications/almanac/storage/AlmanacDAO.php',
+ 'AlmanacDevice' => 'applications/almanac/storage/AlmanacDevice.php',
+ 'AlmanacDevicePHIDType' => 'applications/almanac/phid/AlmanacDevicePHIDType.php',
+ 'AlmanacDeviceProperty' => 'applications/almanac/storage/AlmanacDeviceProperty.php',
+ 'AlmanacDeviceQuery' => 'applications/almanac/query/AlmanacDeviceQuery.php',
+ 'AlmanacManagementRegisterWorkflow' => 'applications/almanac/management/AlmanacManagementRegisterWorkflow.php',
+ 'AlmanacManagementWorkflow' => 'applications/almanac/management/AlmanacManagementWorkflow.php',
'Aphront304Response' => 'aphront/response/Aphront304Response.php',
'Aphront400Response' => 'aphront/response/Aphront400Response.php',
'Aphront403Response' => 'aphront/response/Aphront403Response.php',
@@ -1126,6 +1134,7 @@
'PhabricatorActionListView' => 'view/layout/PhabricatorActionListView.php',
'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php',
'PhabricatorAllCapsTranslation' => 'infrastructure/internationalization/translation/PhabricatorAllCapsTranslation.php',
+ 'PhabricatorAlmanacApplication' => 'applications/almanac/application/PhabricatorAlmanacApplication.php',
'PhabricatorAmazonAuthProvider' => 'applications/auth/provider/PhabricatorAmazonAuthProvider.php',
'PhabricatorAnchorView' => 'view/layout/PhabricatorAnchorView.php',
'PhabricatorAphlictManagementBuildWorkflow' => 'applications/aphlict/management/PhabricatorAphlictManagementBuildWorkflow.php',
@@ -2847,6 +2856,17 @@
'require_celerity_resource' => 'infrastructure/celerity/api.php',
),
'xmap' => array(
+ 'AlmanacConduitUtil' => 'Phobject',
+ 'AlmanacDAO' => 'PhabricatorLiskDAO',
+ 'AlmanacDevice' => array(
+ 'AlmanacDAO',
+ 'PhabricatorPolicyInterface',
+ ),
+ 'AlmanacDevicePHIDType' => 'PhabricatorPHIDType',
+ 'AlmanacDeviceProperty' => 'AlmanacDAO',
+ 'AlmanacDeviceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'AlmanacManagementRegisterWorkflow' => 'AlmanacManagementWorkflow',
+ 'AlmanacManagementWorkflow' => 'PhabricatorManagementWorkflow',
'Aphront304Response' => 'AphrontResponse',
'Aphront400Response' => 'AphrontResponse',
'Aphront403Response' => 'AphrontHTMLResponse',
@@ -4031,6 +4051,7 @@
'PhabricatorActionListView' => 'AphrontView',
'PhabricatorActionView' => 'AphrontView',
'PhabricatorAllCapsTranslation' => 'PhabricatorTranslation',
+ 'PhabricatorAlmanacApplication' => 'PhabricatorApplication',
'PhabricatorAmazonAuthProvider' => 'PhabricatorOAuth2AuthProvider',
'PhabricatorAnchorView' => 'AphrontView',
'PhabricatorAphlictManagementBuildWorkflow' => 'PhabricatorAphlictManagementWorkflow',
diff --git a/src/applications/almanac/application/PhabricatorAlmanacApplication.php b/src/applications/almanac/application/PhabricatorAlmanacApplication.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/application/PhabricatorAlmanacApplication.php
@@ -0,0 +1,41 @@
+<?php
+
+final class PhabricatorAlmanacApplication extends PhabricatorApplication {
+
+ public function getBaseURI() {
+ return '/almanac/';
+ }
+
+ public function getName() {
+ return pht('Almanac');
+ }
+
+ public function getShortDescription() {
+ return pht('Service Directory');
+ }
+
+ public function getIconName() {
+ return 'almanac';
+ }
+
+ public function getTitleGlyph() {
+ return "\xE2\x98\x82";
+ }
+
+ public function getApplicationGroup() {
+ return self::GROUP_UTILITIES;
+ }
+
+ public function isPrototype() {
+ return true;
+ }
+
+ public function isLaunchable() {
+ return false;
+ }
+
+ public function getRoutes() {
+ return array();
+ }
+
+}
diff --git a/src/applications/almanac/management/AlmanacManagementRegisterWorkflow.php b/src/applications/almanac/management/AlmanacManagementRegisterWorkflow.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/management/AlmanacManagementRegisterWorkflow.php
@@ -0,0 +1,64 @@
+<?php
+
+final class AlmanacManagementRegisterWorkflow
+ extends AlmanacManagementWorkflow {
+
+ public function didConstruct() {
+ $this
+ ->setName('register')
+ ->setSynopsis(pht('Register this host for authorized Conduit access.'))
+ ->setArguments(array());
+ }
+
+ public function execute(PhutilArgumentParser $args) {
+ $console = PhutilConsole::getConsole();
+
+ if (Filesystem::pathExists(AlmanacConduitUtil::getHostPrivateKeyPath())) {
+ throw new Exception(
+ 'This host already has a private key for Conduit access.');
+ }
+
+ $pair = PhabricatorSSHKeyGenerator::generateKeypair();
+ list($public_key, $private_key) = $pair;
+
+ $host = id(new AlmanacDevice())
+ ->setName(php_uname('n'))
+ ->save();
+
+ id(new AlmanacDeviceProperty())
+ ->setDevicePHID($host->getPHID())
+ ->setKey('conduitPublicOpenSSHKey')
+ ->setValue($public_key)
+ ->save();
+
+ id(new AlmanacDeviceProperty())
+ ->setDevicePHID($host->getPHID())
+ ->setKey('conduitPublicOpenSSLKey')
+ ->setValue($this->convertToOpenSSLPublicKey($public_key))
+ ->save();
+
+ Filesystem::writeFile(
+ AlmanacConduitUtil::getHostPrivateKeyPath(),
+ $private_key);
+
+ Filesystem::writeFile(
+ AlmanacConduitUtil::getHostIDPath(),
+ $host->getID());
+
+ $console->writeOut("Registered as device %d.\n", $host->getID());
+ }
+
+ private function convertToOpenSSLPublicKey($openssh_public_key) {
+ $ssh_public_key_file = new TempFile();
+ Filesystem::writeFile($ssh_public_key_file, $openssh_public_key);
+
+ list($public_key, $stderr) = id(new ExecFuture(
+ 'ssh-keygen -e -f %s -m pkcs8',
+ $ssh_public_key_file))->resolvex();
+
+ unset($ssh_public_key_file);
+
+ return $public_key;
+ }
+
+}
diff --git a/src/applications/almanac/management/AlmanacManagementWorkflow.php b/src/applications/almanac/management/AlmanacManagementWorkflow.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/management/AlmanacManagementWorkflow.php
@@ -0,0 +1,4 @@
+<?php
+
+abstract class AlmanacManagementWorkflow
+ extends PhabricatorManagementWorkflow {}
diff --git a/src/applications/almanac/phid/AlmanacDevicePHIDType.php b/src/applications/almanac/phid/AlmanacDevicePHIDType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/phid/AlmanacDevicePHIDType.php
@@ -0,0 +1,39 @@
+<?php
+
+final class AlmanacDevicePHIDType extends PhabricatorPHIDType {
+
+ const TYPECONST = 'ADEV';
+
+ public function getTypeName() {
+ return pht('Almanac Device');
+ }
+
+ public function newObject() {
+ return new AlmanacDevice();
+ }
+
+ protected function buildQueryForObjects(
+ PhabricatorObjectQuery $query,
+ array $phids) {
+
+ return id(new AlmanacDeviceQuery())
+ ->withPHIDs($phids);
+ }
+
+ public function loadHandles(
+ PhabricatorHandleQuery $query,
+ array $handles,
+ array $objects) {
+
+ foreach ($handles as $phid => $handle) {
+ $device = $objects[$phid];
+
+ $id = $device->getID();
+ $name = $device->getName();
+
+ $handle->setObjectName(pht('Device %d', $id));
+ $handle->setName($name);
+ }
+ }
+
+}
diff --git a/src/applications/almanac/query/AlmanacDeviceQuery.php b/src/applications/almanac/query/AlmanacDeviceQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/query/AlmanacDeviceQuery.php
@@ -0,0 +1,60 @@
+<?php
+
+final class AlmanacDeviceQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $ids;
+ private $phids;
+
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
+ public function withPHIDs(array $phids) {
+ $this->phids = $phids;
+ return $this;
+ }
+
+ protected function loadPage() {
+ $table = new AlmanacDevice();
+ $conn_r = $table->establishConnection('r');
+
+ $data = queryfx_all(
+ $conn_r,
+ 'SELECT * FROM %T %Q %Q %Q',
+ $table->getTableName(),
+ $this->buildWhereClause($conn_r),
+ $this->buildOrderClause($conn_r),
+ $this->buildLimitClause($conn_r));
+
+ return $table->loadAllFromArray($data);
+ }
+
+ protected function buildWhereClause($conn_r) {
+ $where = array();
+
+ if ($this->ids !== null) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'id IN (%Ld)',
+ $this->ids);
+ }
+
+ if ($this->phids !== null) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'phid IN (%Ls)',
+ $this->phids);
+ }
+
+ $where[] = $this->buildPagingClause($conn_r);
+
+ return $this->formatWhereClause($where);
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorAlmanacApplication';
+ }
+
+}
diff --git a/src/applications/almanac/storage/AlmanacDAO.php b/src/applications/almanac/storage/AlmanacDAO.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/storage/AlmanacDAO.php
@@ -0,0 +1,9 @@
+<?php
+
+abstract class AlmanacDAO extends PhabricatorLiskDAO {
+
+ public function getApplicationName() {
+ return 'almanac';
+ }
+
+}
diff --git a/src/applications/almanac/storage/AlmanacDevice.php b/src/applications/almanac/storage/AlmanacDevice.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/storage/AlmanacDevice.php
@@ -0,0 +1,50 @@
+<?php
+
+final class AlmanacDevice
+ extends AlmanacDAO
+ implements PhabricatorPolicyInterface {
+
+ protected $name;
+
+ public function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ self::CONFIG_COLUMN_SCHEMA => array(
+ 'name' => 'text255',
+ ),
+ ) + parent::getConfiguration();
+ }
+
+ public function generatePHID() {
+ return PhabricatorPHID::generateNewPHID(AlmanacDevicePHIDType::TYPECONST);
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ );
+ }
+
+ public function getPolicy($capability) {
+ switch ($capability) {
+ case PhabricatorPolicyCapability::CAN_VIEW:
+ // Until we get a clearer idea on what's going to be stored in this
+ // table, don't allow anyone (other than the omnipotent user) to find
+ // these objects.
+ return PhabricatorPolicies::POLICY_NOONE;
+ }
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return null;
+ }
+
+}
diff --git a/src/applications/almanac/storage/AlmanacDeviceProperty.php b/src/applications/almanac/storage/AlmanacDeviceProperty.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/storage/AlmanacDeviceProperty.php
@@ -0,0 +1,25 @@
+<?php
+
+final class AlmanacDeviceProperty extends AlmanacDAO {
+
+ protected $devicePHID;
+ protected $key;
+ protected $value;
+
+ public function getConfiguration() {
+ return array(
+ self::CONFIG_SERIALIZATION => array(
+ 'value' => self::SERIALIZATION_JSON,
+ ),
+ self::CONFIG_COLUMN_SCHEMA => array(
+ 'key' => 'text128',
+ ),
+ self::CONFIG_KEY_SCHEMA => array(
+ 'key_device' => array(
+ 'columns' => array('devicePHID', 'key'),
+ ),
+ ),
+ ) + parent::getConfiguration();
+ }
+
+}
diff --git a/src/applications/almanac/util/AlmanacConduitUtil.php b/src/applications/almanac/util/AlmanacConduitUtil.php
new file mode 100644
--- /dev/null
+++ b/src/applications/almanac/util/AlmanacConduitUtil.php
@@ -0,0 +1,17 @@
+<?php
+
+final class AlmanacConduitUtil extends Phobject {
+
+ public static function getHostPrivateKeyPath() {
+ $root = dirname(phutil_get_library_root('phabricator'));
+ $path = $root.'/conf/local/HOSTKEY';
+ return $path;
+ }
+
+ public static function getHostIDPath() {
+ $root = dirname(phutil_get_library_root('phabricator'));
+ $path = $root.'/conf/local/HOSTID';
+ return $path;
+ }
+
+}
diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
--- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
+++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
@@ -120,6 +120,7 @@
'db.dashboard' => array(),
'db.system' => array(),
'db.fund' => array(),
+ 'db.almanac' => array(),
'0000.legacy.sql' => array(
'legacy' => 0,
),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 22, 2:00 AM (2 d, 18 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7693539
Default Alt Text
D10400.diff (14 KB)
Attached To
Mode
D10400: Implement storage of a host ID and a public key for authorizing Conduit between servers
Attached
Detach File
Event Timeline
Log In to Comment