mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-20 20:40:56 +01:00
Add "PassphraseKey" classes for code which needs to actually use credentials
Summary: Ref T4122. These classes provide typed, checked access to credentials, so you can say "give me this password, and throw if anything is funky". Test Plan: Used in next revision. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T4122 Differential Revision: https://secure.phabricator.com/D7625
This commit is contained in:
parent
572567b85d
commit
61b26255bb
8 changed files with 143 additions and 5 deletions
|
@ -947,6 +947,7 @@ phutil_register_library_map(array(
|
|||
'PackageDeleteMail' => 'applications/owners/mail/PackageDeleteMail.php',
|
||||
'PackageMail' => 'applications/owners/mail/PackageMail.php',
|
||||
'PackageModifyMail' => 'applications/owners/mail/PackageModifyMail.php',
|
||||
'PassphraseAbstractKey' => 'applications/passphrase/keys/PassphraseAbstractKey.php',
|
||||
'PassphraseController' => 'applications/passphrase/controller/PassphraseController.php',
|
||||
'PassphraseCredential' => 'applications/passphrase/storage/PassphraseCredential.php',
|
||||
'PassphraseCredentialControl' => 'applications/passphrase/view/PassphraseCredentialControl.php',
|
||||
|
@ -968,6 +969,8 @@ phutil_register_library_map(array(
|
|||
'PassphraseCredentialViewController' => 'applications/passphrase/controller/PassphraseCredentialViewController.php',
|
||||
'PassphraseDAO' => 'applications/passphrase/storage/PassphraseDAO.php',
|
||||
'PassphrasePHIDTypeCredential' => 'applications/passphrase/phid/PassphrasePHIDTypeCredential.php',
|
||||
'PassphrasePasswordKey' => 'applications/passphrase/keys/PassphrasePasswordKey.php',
|
||||
'PassphraseSSHKey' => 'applications/passphrase/keys/PassphraseSSHKey.php',
|
||||
'PassphraseSecret' => 'applications/passphrase/storage/PassphraseSecret.php',
|
||||
'PasteCapabilityDefaultView' => 'applications/paste/capability/PasteCapabilityDefaultView.php',
|
||||
'PasteCreateMailReceiver' => 'applications/paste/mail/PasteCreateMailReceiver.php',
|
||||
|
@ -3330,6 +3333,7 @@ phutil_register_library_map(array(
|
|||
'PackageDeleteMail' => 'PackageMail',
|
||||
'PackageMail' => 'PhabricatorMail',
|
||||
'PackageModifyMail' => 'PackageMail',
|
||||
'PassphraseAbstractKey' => 'Phobject',
|
||||
'PassphraseController' => 'PhabricatorController',
|
||||
'PassphraseCredential' =>
|
||||
array(
|
||||
|
@ -3359,6 +3363,8 @@ phutil_register_library_map(array(
|
|||
'PassphraseCredentialViewController' => 'PassphraseController',
|
||||
'PassphraseDAO' => 'PhabricatorLiskDAO',
|
||||
'PassphrasePHIDTypeCredential' => 'PhabricatorPHIDType',
|
||||
'PassphrasePasswordKey' => 'PassphraseAbstractKey',
|
||||
'PassphraseSSHKey' => 'PassphraseAbstractKey',
|
||||
'PassphraseSecret' => 'PassphraseDAO',
|
||||
'PasteCapabilityDefaultView' => 'PhabricatorPolicyCapability',
|
||||
'PasteCreateMailReceiver' => 'PhabricatorMailReceiver',
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
final class PassphraseCredentialTypePassword
|
||||
extends PassphraseCredentialType {
|
||||
|
||||
const CREDENTIAL_TYPE = 'password';
|
||||
const PROVIDES_TYPE = 'provides/password';
|
||||
|
||||
public function getCredentialType() {
|
||||
return 'password';
|
||||
return self::CREDENTIAL_TYPE;
|
||||
}
|
||||
|
||||
public function getProvidesType() {
|
||||
return 'provides/password';
|
||||
return self::PROVIDES_TYPE;
|
||||
}
|
||||
|
||||
public function getCredentialTypeName() {
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
abstract class PassphraseCredentialTypeSSHPrivateKey
|
||||
extends PassphraseCredentialType {
|
||||
|
||||
const PROVIDES_TYPE = 'provides/ssh-key-file';
|
||||
|
||||
final public function getProvidesType() {
|
||||
return 'provides/ssh-key-file';
|
||||
return self::PROVIDES_TYPE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
final class PassphraseCredentialTypeSSHPrivateKeyFile
|
||||
extends PassphraseCredentialTypeSSHPrivateKey {
|
||||
|
||||
const CREDENTIAL_TYPE = 'ssh-key-file';
|
||||
|
||||
public function getCredentialType() {
|
||||
return 'ssh-key-file';
|
||||
return self::CREDENTIAL_TYPE;
|
||||
}
|
||||
|
||||
public function getCredentialTypeName() {
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
final class PassphraseCredentialTypeSSHPrivateKeyText
|
||||
extends PassphraseCredentialTypeSSHPrivateKey {
|
||||
|
||||
const CREDENTIAL_TYPE = 'ssh-key-text';
|
||||
|
||||
public function getCredentialType() {
|
||||
return 'ssh-key-text';
|
||||
return self::CREDENTIAL_TYPE;
|
||||
}
|
||||
|
||||
public function getCredentialTypeName() {
|
||||
|
|
66
src/applications/passphrase/keys/PassphraseAbstractKey.php
Normal file
66
src/applications/passphrase/keys/PassphraseAbstractKey.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
abstract class PassphraseAbstractKey extends Phobject {
|
||||
|
||||
private $credential;
|
||||
|
||||
protected function requireCredential() {
|
||||
if (!$this->credential) {
|
||||
throw new Exception(pht("Credential is required!"));
|
||||
}
|
||||
return $this->credential;
|
||||
}
|
||||
|
||||
private function loadCredential(
|
||||
$phid,
|
||||
PhabricatorUser $viewer) {
|
||||
|
||||
$credential = id(new PassphraseCredentialQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($phid))
|
||||
->needSecrets(true)
|
||||
->executeOne();
|
||||
|
||||
if (!$credential) {
|
||||
throw new Exception(pht('Failed to load credential "%s"!', $phid));
|
||||
}
|
||||
|
||||
return $credential;
|
||||
}
|
||||
|
||||
private function validateCredential(
|
||||
PassphraseCredential $credential,
|
||||
$provides_type) {
|
||||
|
||||
$type = $credential->getCredentialType();
|
||||
if ($type->getProvides() !== $provides_type) {
|
||||
throw new Exception(
|
||||
pht(
|
||||
'Credential "%s" must provide "%s", but provides "%s"!',
|
||||
'K'.$credential->getID(),
|
||||
$provides_type,
|
||||
$type->getProvides()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function loadAndValidateFromPHID(
|
||||
$phid,
|
||||
PhabricatorUser $viewer,
|
||||
$type) {
|
||||
|
||||
$credential = $this->loadCredential($phid, $viewer);
|
||||
|
||||
$this->validateCredential($credential, $type);
|
||||
|
||||
$this->credential = $credential;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUsernameEnvelope() {
|
||||
$credential = $this->requireCredential();
|
||||
return new PhutilOpaqueEnvelope($credential->getUsername());
|
||||
}
|
||||
|
||||
}
|
17
src/applications/passphrase/keys/PassphrasePasswordKey.php
Normal file
17
src/applications/passphrase/keys/PassphrasePasswordKey.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
final class PassphrasePasswordKey extends PassphraseAbstractKey {
|
||||
|
||||
public static function loadFromPHID($phid, PhabricatorUser $viewer) {
|
||||
$key = new PassphraseSSHKey();
|
||||
return $key->loadAndValidateFromPHID(
|
||||
$phid,
|
||||
$viewer,
|
||||
PassphraseCredentialTypePassword::PROVIDES_TYPE);
|
||||
}
|
||||
|
||||
public function getPasswordEnvelope() {
|
||||
return $this->requireCredential()->getSecret();
|
||||
}
|
||||
|
||||
}
|
40
src/applications/passphrase/keys/PassphraseSSHKey.php
Normal file
40
src/applications/passphrase/keys/PassphraseSSHKey.php
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
final class PassphraseSSHKey extends PassphraseAbstractKey {
|
||||
|
||||
private $keyFile;
|
||||
|
||||
public static function loadFromPHID($phid, PhabricatorUser $viewer) {
|
||||
$key = new PassphraseSSHKey();
|
||||
return $key->loadAndValidateFromPHID(
|
||||
$phid,
|
||||
$viewer,
|
||||
PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE);
|
||||
}
|
||||
|
||||
public function getKeyfileEnvelope() {
|
||||
$credential = $this->requireCredential();
|
||||
|
||||
$text_type = PassphraseCredentialTypeSSHPrivateKeyText::CREDENTIAL_TYPE;
|
||||
if ($credential->getCredentialType() == $text_type) {
|
||||
// If the credential stores key text, write it out to a temporary file
|
||||
// so we can pass it to `ssh`.
|
||||
if (!$this->keyFile) {
|
||||
$temporary_file = new TempFile('passphrase-ssh-key');
|
||||
|
||||
Filesystem::changePermissions($temporary_file, 0600);
|
||||
|
||||
Filesystem::writeFile(
|
||||
$temporary_file,
|
||||
$credential->getSecret()->openEnvelope());
|
||||
|
||||
$this->keyFile = $temporary_file;
|
||||
}
|
||||
|
||||
return new PhutilOpaqueEnvelope((string)$this->keyFile);
|
||||
}
|
||||
|
||||
return $credential->getSecret();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue