Skip to content

Commit

Permalink
MIG-71: Add Ssh with passphrase support
Browse files Browse the repository at this point in the history
  • Loading branch information
momoss committed Oct 13, 2017
1 parent 0f9ae26 commit b81084f
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 13 deletions.
6 changes: 0 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ list:
@echo " $(YELLOW)fix-style$(RESTORE) > run the PHP-CS-FIXER"
@echo " $(YELLOW)test$(RESTORE) > run All tests"
@echo " $(YELLOW)phpspec-run$(RESTORE) > run All PHPSpec tests"
@echo " $(YELLOW)phpspec$(RESTORE) > run PHPSpec"
@echo " $(YELLOW)phpunit$(RESTORE) > run All PHPUnit"
@echo " $(YELLOW)launch$(RESTORE) > Launch the tool"
@echo " $(YELLOW)dump-state-machine$(RESTORE) > Dump the State Machine"
Expand All @@ -25,7 +24,6 @@ list:
@echo " $(YELLOW)composer$(RESTORE) > run composer"
@echo " $(YELLOW)install$(RESTORE) > install vendors"
@echo " $(YELLOW)update$(RESTORE) > update vendors"
@echo " $(YELLOW)run$(RESTORE) > run the tool"
@echo " $(YELLOW)clean$(RESTORE) > removes the vendors"

.PHONY: commit
Expand Down Expand Up @@ -55,10 +53,6 @@ phpspec-run:
phpunit:
./vendor/bin/phpunit ${ARGS} --exclude-group 'docker-compose'

.PHONY: phpspec
phpspec:
./vendor/bin/phpspec ${ARGS}

.PHONY: composer
composer:
composer ${ARGS}
Expand Down
2 changes: 2 additions & 0 deletions src/Domain/PrinterAndAsker.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public function askChoiceQuestion(string $question, array $choicesAvailable): st

public function askSimpleQuestion(string $question, string $default = '', ?callable $validator = null): string;

public function askHiddenSimpleQuestion(string $question, ?callable $validator = null): string;

public function title(string $message): void;

public function section(string $message): void;
Expand Down
4 changes: 4 additions & 0 deletions src/Infrastructure/Cli/SshConsole.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ public function execute(Command $command, Pim $pim): CommandResult

$ssh = new SSH2($connection->getHost(), $connection->getPort());
$rsa = new RSA();
if (null !== $connection->getPassword()) {
$rsa->setPassword($connection->getPassword());
}

$rsa->load($connection->getSshKey()->getKey());

if (!$ssh->isConnected()) {
Expand Down
2 changes: 2 additions & 0 deletions src/Infrastructure/Common/messages.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ from_ready_to_source_pim_configured:
ssh_user_question: "What is the SSH user you want to connect with to the source PIM? "
ssh_key_path_question: "What is the absolute path of the private SSH key able to connect to the source PIM? "
ssh_key_path_error: "Your SSH key path should be an absolute one."
ssh_key_protected: "Is your ssh key protected by a passphrase ? "
ssh_key_passphrase: "Enter passphrase for %s "
project_path_question: "What is the absolute path of the source PIM on the server? "
project_path_error: "Your source PIM path should be an absolute one."
on_local_configuration:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

namespace Akeneo\PimMigration\Infrastructure\MigrationStep;

use Akeneo\PimMigration\Domain\MigrationStep\s010_SourcePimConfiguration\SourcePimConfigurationException;
use Akeneo\PimMigration\Domain\MigrationStep\s010_SourcePimConfiguration\SourcePimConfigurator;
use Akeneo\PimMigration\Domain\Pim\PimServerInformation;
use Akeneo\PimMigration\Domain\MigrationStep\s010_SourcePimConfiguration\SourcePimConfigurationException;
use Akeneo\PimMigration\Infrastructure\TransporteoStateMachine;
use Akeneo\PimMigration\Infrastructure\Pim\Localhost;
use Akeneo\PimMigration\Infrastructure\Pim\SshConnection;
use Akeneo\PimMigration\Infrastructure\SshKey;
use Akeneo\PimMigration\Infrastructure\TransporteoStateMachine;
use Psr\Log\LoggerInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Translation\Translator;
Expand All @@ -28,6 +28,9 @@ class S010FromReadyToSourcePimConfigured extends AbstractStateMachineSubscriber
private const LOCAL_SOURCE_PIM = 'locally';
private const REMOTE_SOURCE_PIM = 'on a remote server';

private const YES = 'yes';
private const NO = 'no';

/** @var SourcePimConfigurator */
private $pimConfigurator;

Expand Down Expand Up @@ -175,7 +178,21 @@ function ($answer) use ($transPrefix) {
}
);

$stateMachine->setSourcePimConnection(new SshConnection($host, $port, $user, new SshKey($sshPath)));
$hasPassword = $this->printerAndAsker->askChoiceQuestion(
$this->translator->trans($transPrefix . 'ssh_key_protected'),
[self::YES => self::YES, self::NO => self::NO]
);

$password = null;
if (self::YES === $hasPassword) {
$password = $this
->printerAndAsker
->askHiddenSimpleQuestion(
sprintf($this->translator->trans($transPrefix . 'ssh_key_passphrase'), $sshPath)
);
}

$stateMachine->setSourcePimConnection(new SshConnection($host, $port, $user, new SshKey($sshPath), $password));

$pimProjectPath = $this
->printerAndAsker
Expand Down
14 changes: 12 additions & 2 deletions src/Infrastructure/Pim/SshConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ class SshConnection implements PimConnection
/** @var SshKey */
private $sshKey;

public function __construct(string $host, int $port, string $username, SshKey $sshKey)
/** @var ?string */
private $password;

public function __construct(string $host, int $port, string $username, SshKey $sshKey, ?string $password = null)
{
$this->host = $host;
$this->port = $port;
$this->username = $username;
$this->sshKey = $sshKey;
$this->password = $password;
}

public static function fromString(string $serverInformation, SshKey $sshKey)
Expand All @@ -43,7 +47,8 @@ public static function fromString(string $serverInformation, SshKey $sshKey)
$parsedServerInformation['host'],
$parsedServerInformation['port'],
$parsedServerInformation['user'],
$sshKey
$sshKey,
$parsedServerInformation['password']
);
}

Expand All @@ -66,4 +71,9 @@ public function getSshKey(): SshKey
{
return $this->sshKey;
}

public function getPassword(): ?string
{
return $this->password;
}
}
4 changes: 4 additions & 0 deletions src/Infrastructure/SshFileFetcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ private function createSftpConnection(PimConnection $connection): SFTP
}

$key = new RSA();
if (null !== $connection->getPassword()) {
$key->setPassword($connection->getPassword());
}

$key->load($connection->getSshKey()->getKey());
$sftp = new SFTP($connection->getHost(), $connection->getPort());

Expand Down
16 changes: 16 additions & 0 deletions src/Infrastructure/UserInterface/Cli/ConsolePrinterAndAsker.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ public function askSimpleQuestion(string $question, string $default = '', ?calla
);
}

public function askHiddenSimpleQuestion(string $question, ?callable $validator = null): string
{
return $this->io->askHidden($question, function ($answer) use ($validator) {
if (empty(trim($answer))) {
throw new \RuntimeException('Please provide a value :)');
}

if (null !== $validator) {
$validator($answer);
}

return $answer;
}
);
}

public function title(string $message): void
{
$this->io->title($message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,18 @@ public function it_configures_a_source_pim_from_a_server(
$sshUserQuestion = 'What is the SSH user you want to connect with ? ';
$sshKeyPathQuestion = 'What is the absolute path of the private SSH key able to connect to the server? ';
$projectPathQuestion = 'What is the absolute path of the source PIM on the server? ';
$sshKeyProtected = 'Is your ssh key protected by a passphrase ? ';
$sshKeyPassphrase = 'Enter passphrase for %s ';

$transPrefix = 'from_ready_to_source_pim_configured.on_distant_configuration.';
$translations = [
$transPrefix . 'hostname_question' => $hostNameQuestion,
$transPrefix . 'ssh_port_question' => $portQuestion,
$transPrefix . 'ssh_user_question' => $sshUserQuestion,
$transPrefix . 'ssh_key_path_question' => $sshKeyPathQuestion,
$transPrefix . 'project_path_question' => $projectPathQuestion
$transPrefix . 'project_path_question' => $projectPathQuestion,
$transPrefix . 'ssh_key_protected' => $sshKeyProtected,
$transPrefix . 'ssh_key_passphrase' => $sshKeyPassphrase,
];

foreach ($translations as $translationKey => $translation) {
Expand All @@ -139,6 +143,7 @@ public function it_configures_a_source_pim_from_a_server(
$sshKeyPath = ResourcesFileLocator::getSshKeyPath();

$printerAndAsker->askSimpleQuestion($sshKeyPathQuestion, Argument::any(), Argument::any())->willReturn($sshKeyPath);
$printerAndAsker->askChoiceQuestion($sshKeyProtected, ['yes' => 'yes', 'no' => 'no'])->willReturn('no');

$sshKey = new SshKey($sshKeyPath);
$serverAccessInformation = new SshConnection('my-super-pim.akeneo.com', 22, 'akeneo', $sshKey);
Expand Down Expand Up @@ -211,14 +216,18 @@ public function it_throws_business_exception_from_technical(
$sshUserQuestion = 'What is the SSH user you want to connect with ? ';
$sshKeyPathQuestion = 'What is the absolute path of the private SSH key able to connect to the server? ';
$projectPathQuestion = 'What is the absolute path of the source PIM on the server? ';
$sshKeyProtected = 'Is your ssh key protected by a passphrase ? ';
$sshKeyPassphrase = 'Enter passphrase for %s ';

$transPrefix = 'from_ready_to_source_pim_configured.on_distant_configuration.';
$translations = [
$transPrefix . 'hostname_question' => $hostNameQuestion,
$transPrefix . 'ssh_port_question' => $portQuestion,
$transPrefix . 'ssh_user_question' => $sshUserQuestion,
$transPrefix . 'ssh_key_path_question' => $sshKeyPathQuestion,
$transPrefix . 'project_path_question' => $projectPathQuestion
$transPrefix . 'project_path_question' => $projectPathQuestion,
$transPrefix . 'ssh_key_protected' => $sshKeyProtected,
$transPrefix . 'ssh_key_passphrase' => $sshKeyPassphrase,
];

foreach ($translations as $translationKey => $translation) {
Expand All @@ -232,6 +241,7 @@ public function it_throws_business_exception_from_technical(
$sshKeyPath = ResourcesFileLocator::getSshKeyPath();

$printerAndAsker->askSimpleQuestion($sshKeyPathQuestion, Argument::any(), Argument::any())->willReturn($sshKeyPath);
$printerAndAsker->askChoiceQuestion($sshKeyProtected, ['yes' => 'yes', 'no' => 'no'])->willReturn('no');

$sshKey = new SshKey($sshKeyPath);
$serverAccessInformation = new SshConnection('my-super-pim.akeneo.com', 22, 'akeneo', $sshKey);
Expand Down

0 comments on commit b81084f

Please sign in to comment.