@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+143 -5
+6
src/__phutil_library_map__.php
··· 947 947 'PackageDeleteMail' => 'applications/owners/mail/PackageDeleteMail.php', 948 948 'PackageMail' => 'applications/owners/mail/PackageMail.php', 949 949 'PackageModifyMail' => 'applications/owners/mail/PackageModifyMail.php', 950 + 'PassphraseAbstractKey' => 'applications/passphrase/keys/PassphraseAbstractKey.php', 950 951 'PassphraseController' => 'applications/passphrase/controller/PassphraseController.php', 951 952 'PassphraseCredential' => 'applications/passphrase/storage/PassphraseCredential.php', 952 953 'PassphraseCredentialControl' => 'applications/passphrase/view/PassphraseCredentialControl.php', ··· 968 969 'PassphraseCredentialViewController' => 'applications/passphrase/controller/PassphraseCredentialViewController.php', 969 970 'PassphraseDAO' => 'applications/passphrase/storage/PassphraseDAO.php', 970 971 'PassphrasePHIDTypeCredential' => 'applications/passphrase/phid/PassphrasePHIDTypeCredential.php', 972 + 'PassphrasePasswordKey' => 'applications/passphrase/keys/PassphrasePasswordKey.php', 973 + 'PassphraseSSHKey' => 'applications/passphrase/keys/PassphraseSSHKey.php', 971 974 'PassphraseSecret' => 'applications/passphrase/storage/PassphraseSecret.php', 972 975 'PasteCapabilityDefaultView' => 'applications/paste/capability/PasteCapabilityDefaultView.php', 973 976 'PasteCreateMailReceiver' => 'applications/paste/mail/PasteCreateMailReceiver.php', ··· 3330 3333 'PackageDeleteMail' => 'PackageMail', 3331 3334 'PackageMail' => 'PhabricatorMail', 3332 3335 'PackageModifyMail' => 'PackageMail', 3336 + 'PassphraseAbstractKey' => 'Phobject', 3333 3337 'PassphraseController' => 'PhabricatorController', 3334 3338 'PassphraseCredential' => 3335 3339 array( ··· 3359 3363 'PassphraseCredentialViewController' => 'PassphraseController', 3360 3364 'PassphraseDAO' => 'PhabricatorLiskDAO', 3361 3365 'PassphrasePHIDTypeCredential' => 'PhabricatorPHIDType', 3366 + 'PassphrasePasswordKey' => 'PassphraseAbstractKey', 3367 + 'PassphraseSSHKey' => 'PassphraseAbstractKey', 3362 3368 'PassphraseSecret' => 'PassphraseDAO', 3363 3369 'PasteCapabilityDefaultView' => 'PhabricatorPolicyCapability', 3364 3370 'PasteCreateMailReceiver' => 'PhabricatorMailReceiver',
+5 -2
src/applications/passphrase/credentialtype/PassphraseCredentialTypePassword.php
··· 3 3 final class PassphraseCredentialTypePassword 4 4 extends PassphraseCredentialType { 5 5 6 + const CREDENTIAL_TYPE = 'password'; 7 + const PROVIDES_TYPE = 'provides/password'; 8 + 6 9 public function getCredentialType() { 7 - return 'password'; 10 + return self::CREDENTIAL_TYPE; 8 11 } 9 12 10 13 public function getProvidesType() { 11 - return 'provides/password'; 14 + return self::PROVIDES_TYPE; 12 15 } 13 16 14 17 public function getCredentialTypeName() {
+3 -1
src/applications/passphrase/credentialtype/PassphraseCredentialTypeSSHPrivateKey.php
··· 3 3 abstract class PassphraseCredentialTypeSSHPrivateKey 4 4 extends PassphraseCredentialType { 5 5 6 + const PROVIDES_TYPE = 'provides/ssh-key-file'; 7 + 6 8 final public function getProvidesType() { 7 - return 'provides/ssh-key-file'; 9 + return self::PROVIDES_TYPE; 8 10 } 9 11 10 12 }
+3 -1
src/applications/passphrase/credentialtype/PassphraseCredentialTypeSSHPrivateKeyFile.php
··· 3 3 final class PassphraseCredentialTypeSSHPrivateKeyFile 4 4 extends PassphraseCredentialTypeSSHPrivateKey { 5 5 6 + const CREDENTIAL_TYPE = 'ssh-key-file'; 7 + 6 8 public function getCredentialType() { 7 - return 'ssh-key-file'; 9 + return self::CREDENTIAL_TYPE; 8 10 } 9 11 10 12 public function getCredentialTypeName() {
+3 -1
src/applications/passphrase/credentialtype/PassphraseCredentialTypeSSHPrivateKeyText.php
··· 3 3 final class PassphraseCredentialTypeSSHPrivateKeyText 4 4 extends PassphraseCredentialTypeSSHPrivateKey { 5 5 6 + const CREDENTIAL_TYPE = 'ssh-key-text'; 7 + 6 8 public function getCredentialType() { 7 - return 'ssh-key-text'; 9 + return self::CREDENTIAL_TYPE; 8 10 } 9 11 10 12 public function getCredentialTypeName() {
+66
src/applications/passphrase/keys/PassphraseAbstractKey.php
··· 1 + <?php 2 + 3 + abstract class PassphraseAbstractKey extends Phobject { 4 + 5 + private $credential; 6 + 7 + protected function requireCredential() { 8 + if (!$this->credential) { 9 + throw new Exception(pht("Credential is required!")); 10 + } 11 + return $this->credential; 12 + } 13 + 14 + private function loadCredential( 15 + $phid, 16 + PhabricatorUser $viewer) { 17 + 18 + $credential = id(new PassphraseCredentialQuery()) 19 + ->setViewer($viewer) 20 + ->withPHIDs(array($phid)) 21 + ->needSecrets(true) 22 + ->executeOne(); 23 + 24 + if (!$credential) { 25 + throw new Exception(pht('Failed to load credential "%s"!', $phid)); 26 + } 27 + 28 + return $credential; 29 + } 30 + 31 + private function validateCredential( 32 + PassphraseCredential $credential, 33 + $provides_type) { 34 + 35 + $type = $credential->getCredentialType(); 36 + if ($type->getProvides() !== $provides_type) { 37 + throw new Exception( 38 + pht( 39 + 'Credential "%s" must provide "%s", but provides "%s"!', 40 + 'K'.$credential->getID(), 41 + $provides_type, 42 + $type->getProvides())); 43 + } 44 + 45 + } 46 + 47 + protected function loadAndValidateFromPHID( 48 + $phid, 49 + PhabricatorUser $viewer, 50 + $type) { 51 + 52 + $credential = $this->loadCredential($phid, $viewer); 53 + 54 + $this->validateCredential($credential, $type); 55 + 56 + $this->credential = $credential; 57 + 58 + return $this; 59 + } 60 + 61 + public function getUsernameEnvelope() { 62 + $credential = $this->requireCredential(); 63 + return new PhutilOpaqueEnvelope($credential->getUsername()); 64 + } 65 + 66 + }
+17
src/applications/passphrase/keys/PassphrasePasswordKey.php
··· 1 + <?php 2 + 3 + final class PassphrasePasswordKey extends PassphraseAbstractKey { 4 + 5 + public static function loadFromPHID($phid, PhabricatorUser $viewer) { 6 + $key = new PassphraseSSHKey(); 7 + return $key->loadAndValidateFromPHID( 8 + $phid, 9 + $viewer, 10 + PassphraseCredentialTypePassword::PROVIDES_TYPE); 11 + } 12 + 13 + public function getPasswordEnvelope() { 14 + return $this->requireCredential()->getSecret(); 15 + } 16 + 17 + }
+40
src/applications/passphrase/keys/PassphraseSSHKey.php
··· 1 + <?php 2 + 3 + final class PassphraseSSHKey extends PassphraseAbstractKey { 4 + 5 + private $keyFile; 6 + 7 + public static function loadFromPHID($phid, PhabricatorUser $viewer) { 8 + $key = new PassphraseSSHKey(); 9 + return $key->loadAndValidateFromPHID( 10 + $phid, 11 + $viewer, 12 + PassphraseCredentialTypeSSHPrivateKey::PROVIDES_TYPE); 13 + } 14 + 15 + public function getKeyfileEnvelope() { 16 + $credential = $this->requireCredential(); 17 + 18 + $text_type = PassphraseCredentialTypeSSHPrivateKeyText::CREDENTIAL_TYPE; 19 + if ($credential->getCredentialType() == $text_type) { 20 + // If the credential stores key text, write it out to a temporary file 21 + // so we can pass it to `ssh`. 22 + if (!$this->keyFile) { 23 + $temporary_file = new TempFile('passphrase-ssh-key'); 24 + 25 + Filesystem::changePermissions($temporary_file, 0600); 26 + 27 + Filesystem::writeFile( 28 + $temporary_file, 29 + $credential->getSecret()->openEnvelope()); 30 + 31 + $this->keyFile = $temporary_file; 32 + } 33 + 34 + return new PhutilOpaqueEnvelope((string)$this->keyFile); 35 + } 36 + 37 + return $credential->getSecret(); 38 + } 39 + 40 + }