1
0
Fork 0
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:
epriestley 2013-11-22 15:23:10 -08:00
parent 572567b85d
commit 61b26255bb
8 changed files with 143 additions and 5 deletions

View file

@ -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',

View file

@ -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() {

View file

@ -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;
}
}

View file

@ -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() {

View file

@ -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() {

View 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());
}
}

View 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();
}
}

View 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();
}
}