From 3d0e10586c2a51060508dcc6b359e585ef60bb2c Mon Sep 17 00:00:00 2001 From: Zachary Quintana Date: Tue, 10 Nov 2020 10:14:58 -0700 Subject: [PATCH 1/7] Add standards and start scripts section. --- .gitignore | 1 + composer.json | 12 +++++- composer.lock | 110 ------------------------------------------------- phpcs.xml.dist | 4 ++ 4 files changed, 16 insertions(+), 111 deletions(-) delete mode 100644 composer.lock create mode 100644 phpcs.xml.dist diff --git a/.gitignore b/.gitignore index 48b8bf9..d1502b0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ vendor/ +composer.lock diff --git a/composer.json b/composer.json index 03d673f..b990223 100644 --- a/composer.json +++ b/composer.json @@ -11,11 +11,21 @@ ], "require": { "php": "^7.0", - "phpseclib/phpseclib": "^2.0" + "phpseclib/phpseclib": "^2.0", + "zingle-com/php-coding-standard": "^0.0.1" }, "autoload": { "psr-4": { "Zingle\\": "src/Zingle" } + }, + "scripts": { + "test": "./vendor/bin/phpunit", + "test-no-coverage": "@test --no-coverage", + "check-standards": "./vendor/bin/phpcs -p", + "test-all": [ + "@check-standards", + "@test" + ] } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index a6c3c52..0000000 --- a/composer.lock +++ /dev/null @@ -1,110 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "content-hash": "98d09f6b60c631acf9099cd0b2f98d5b", - "packages": [ - { - "name": "phpseclib/phpseclib", - "version": "2.0.12", - "source": { - "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/8814dc7841db159daed0b32c2b08fb7e03c6afe7", - "reference": "8814dc7841db159daed0b32c2b08fb7e03c6afe7", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phing/phing": "~2.7", - "phpunit/phpunit": "^4.8.35|^5.7|^6.0", - "sami/sami": "~2.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "suggest": { - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." - }, - "type": "library", - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib\\": "phpseclib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" - } - ], - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "homepage": "http://phpseclib.sourceforge.net", - "keywords": [ - "BigInteger", - "aes", - "asn.1", - "asn1", - "blowfish", - "crypto", - "cryptography", - "encryption", - "rsa", - "security", - "sftp", - "signature", - "signing", - "ssh", - "twofish", - "x.509", - "x509" - ], - "time": "2018-11-04T05:45:48+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [] -} diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..82921f5 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,4 @@ + + + + From 686c31d7e0b3c4c23c1d9906693117b97ea5f91d Mon Sep 17 00:00:00 2001 From: Zachary Quintana Date: Tue, 10 Nov 2020 10:42:49 -0700 Subject: [PATCH 2/7] Add phpunit and first test. --- .gitignore | 1 + composer.json | 8 +- phpcs.xml.dist | 2 + phpunit.xml.dist | 24 ++++++ src/Agent.php | 63 ++++++++++++++ .../Infrastructure => }/Connection.php | 84 +++++++++++++------ src/Result.php | 69 +++++++++++++++ src/Zingle/Infrastructure/Agent.php | 42 ---------- src/Zingle/Infrastructure/Result.php | 47 ----------- tests/ConnectionTest.php | 42 ++++++++++ 10 files changed, 263 insertions(+), 119 deletions(-) create mode 100644 phpunit.xml.dist create mode 100644 src/Agent.php rename src/{Zingle/Infrastructure => }/Connection.php (52%) create mode 100644 src/Result.php delete mode 100644 src/Zingle/Infrastructure/Agent.php delete mode 100644 src/Zingle/Infrastructure/Result.php create mode 100644 tests/ConnectionTest.php diff --git a/.gitignore b/.gitignore index d1502b0..3d7e132 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ vendor/ composer.lock +.phpunit.result.cache diff --git a/composer.json b/composer.json index b990223..4703e37 100644 --- a/composer.json +++ b/composer.json @@ -10,13 +10,15 @@ } ], "require": { - "php": "^7.0", + "php": "^7.1", "phpseclib/phpseclib": "^2.0", - "zingle-com/php-coding-standard": "^0.0.1" + "zingle-com/php-coding-standard": "^0.0.1", + "phpunit/phpunit": "^9.4" }, "autoload": { "psr-4": { - "Zingle\\": "src/Zingle" + "Zingle\\Infrastructure\\": "src/", + "Zingle\\Infrastructure\\Test\\": "tests/" } }, "scripts": { diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 82921f5..48621e0 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -1,4 +1,6 @@ + + ./src diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..9cb7ee8 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,24 @@ + + + + + + src + + + + + + + + + + + + + + tests + + + + diff --git a/src/Agent.php b/src/Agent.php new file mode 100644 index 0000000..e191986 --- /dev/null +++ b/src/Agent.php @@ -0,0 +1,63 @@ +user = $user; + $this->setKey($keyData); + } + + /** + * Return the agent user name. + * + * @return string + */ + public function getUser(): string + { + return $this->user; + } + + /** + * Return the agent RSA key. + * + * @return RSA + */ + public function getKey(): RSA + { + return $this->key; + } + + /** + * @param string $keyData + */ + private function setKey(string $keyData): void + { + $this->key = new RSA(); + $this->key->loadKey($keyData); + } +} diff --git a/src/Zingle/Infrastructure/Connection.php b/src/Connection.php similarity index 52% rename from src/Zingle/Infrastructure/Connection.php rename to src/Connection.php index 3b19114..ddbbb38 100644 --- a/src/Zingle/Infrastructure/Connection.php +++ b/src/Connection.php @@ -1,6 +1,7 @@ host = $host; + public function __construct(string $host, Agent $agent) + { + $this->host = $host; $this->agent = $agent; } /** * Open the connection. */ - public function open(): void { + public function open(): void + { if ($this->ssh) { throw new LogicException("connection already open"); } @@ -46,12 +60,25 @@ public function open(): void { } } + /** + * @param SSH2 $ssh + * + * @return $this + */ + public function useSsh(SSH2 $ssh): self + { + $this->ssh = $ssh; + + return $this; + } + /** * Close the connection. */ - public function close(): void { + public function close(): void + { if (!$this->ssh) { - throw new LogicException("connection not open"); + return; // it's already closed } $this->ssh->disconnect(); @@ -59,46 +86,49 @@ public function close(): void { } /** - * Return true if the connection is open. + * @return bool true if the connection is open. */ - public function isOpen(): bool { - return (bool)$this->ssh; + public function isOpen(): bool + { + return isset($this->ssh); } /** * Execute command. + * + * @param string $cmd + * + * @return Result */ - public function execute(string $cmd): Result { + public function execute(string $cmd): Result + { try { - $close = false; - if (!$this->isOpen()) { $this->open(); - $close = true; } $output = $this->ssh->exec($cmd); - $exit = $this->ssh->getExitStatus(); + $exit = $this->ssh->getExitStatus(); return new Result($cmd, $exit, $output); } finally { - if ($close) { - $this->close(); - } + $this->close(); } } /** - * Return the user agent for the connection. + * @return Agent the user agent for the connection. */ - public function getAgent(): Agent { + public function getAgent(): Agent + { return $this->agent; } /** - * Return the host used by this connection. + * @return string the host used by this connection. */ - public function getHost(): string { + public function getHost(): string + { return $this->host; } } diff --git a/src/Result.php b/src/Result.php new file mode 100644 index 0000000..4d7333d --- /dev/null +++ b/src/Result.php @@ -0,0 +1,69 @@ +cmd = $cmd; + $this->exit = $exit; + $this->output = $output; + } + + /** + * Return command which generated this result. + * + * @return string + */ + public function getCommand(): string + { + return $this->cmd; + } + + /** + * Return the command exit status. + * + * @return int + */ + public function getExit(): int + { + return $this->exit; + } + + /** + * Return the command output. + * + * @return string + */ + public function getOutput(): string + { + return $this->output; + } +} diff --git a/src/Zingle/Infrastructure/Agent.php b/src/Zingle/Infrastructure/Agent.php deleted file mode 100644 index c0d98a7..0000000 --- a/src/Zingle/Infrastructure/Agent.php +++ /dev/null @@ -1,42 +0,0 @@ -loadKey($keyData); - - $this->user = $user; - $this->key = $key; - } - - /** - * Return the agent user name. - */ - public function getUser(): string { - return $this->user; - } - - /** - * Return the agent RSA key. - */ - public function getKey(): RSA { - return $this->key; - } -} diff --git a/src/Zingle/Infrastructure/Result.php b/src/Zingle/Infrastructure/Result.php deleted file mode 100644 index a1fa221..0000000 --- a/src/Zingle/Infrastructure/Result.php +++ /dev/null @@ -1,47 +0,0 @@ -cmd = $cmd; - $this->exit = $exit; - $this->output = $output; - } - - /** - * Return command which generated this result. - */ - public function getCommand(): string { - return $this->cmd; - } - - /** - * Return the command exit status. - */ - public function getExit(): int { - return $this->exit; - } - - /** - * Return the command output. - */ - public function getOutput(): string { - return $this->output; - } -} diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php new file mode 100644 index 0000000..a10f20f --- /dev/null +++ b/tests/ConnectionTest.php @@ -0,0 +1,42 @@ +createMock(Agent::class); + $connection = new Connection('localhost', $agent); + $ssh = $this->createMock(SSH2::class); + $ssh + ->expects($this->once()) + ->method('exec') + ->with($cmd) + ->willReturn($mockOutput = sprintf('output-%s', rand())) + ; + $ssh + ->expects($this->once()) + ->method('getExitStatus') + ->willReturn($exitStatus = 1) + ; + $connection->useSsh($ssh); + $result = $connection->execute($cmd); + + $this->assertEquals($cmd, $result->getCommand()); + $this->assertEquals($exitStatus, $result->getExit()); + $this->assertEquals($mockOutput, $result->getOutput()); + } +} From c64862165582397cc5f1c689eb28ecbaccdfc27d Mon Sep 17 00:00:00 2001 From: Zachary Quintana Date: Tue, 10 Nov 2020 11:16:10 -0700 Subject: [PATCH 3/7] Add coveralls and clean up composer. --- .coveralls.yml | 2 ++ composer.json | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .coveralls.yml diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 0000000..da396f1 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,2 @@ +service_name: travis-pro +repo_token: aHR2Vq500iS9DEQu5bwcAR2rotYnEqMq2 diff --git a/composer.json b/composer.json index 4703e37..261c132 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,10 @@ ], "require": { "php": "^7.1", - "phpseclib/phpseclib": "^2.0", + "phpseclib/phpseclib": "^2.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.4", "zingle-com/php-coding-standard": "^0.0.1", "phpunit/phpunit": "^9.4" }, From a8ecd0c0fbeb6bca635ab33aab1cd6caafd56d23 Mon Sep 17 00:00:00 2001 From: Zachary Quintana Date: Tue, 10 Nov 2020 11:17:15 -0700 Subject: [PATCH 4/7] Add travis config. --- .travis.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..604a500 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: php +php: + - "7.2" + +cache: + directories: + - vendor + +install: + - composer install + +script: + - composer run-script test-all + +after_success: + - travis_retry php vendor/bin/php-coveralls -v From 08d29f7a9ee367a28f7a015187e970652b00e83d Mon Sep 17 00:00:00 2001 From: Zachary Quintana Date: Tue, 10 Nov 2020 11:28:02 -0700 Subject: [PATCH 5/7] Update phpunit dependency. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 261c132..ad2ad14 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "require-dev": { "php-coveralls/php-coveralls": "^2.4", "zingle-com/php-coding-standard": "^0.0.1", - "phpunit/phpunit": "^9.4" + "phpunit/phpunit": "^8.5" }, "autoload": { "psr-4": { From 4e81824e5f21b1c04012a4f7540074c10fcbaf07 Mon Sep 17 00:00:00 2001 From: Zachary Quintana Date: Tue, 10 Nov 2020 12:56:11 -0700 Subject: [PATCH 6/7] Revert phpunit. --- phpunit.xml.dist | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9cb7ee8..b6c4db5 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,18 +1,13 @@ - - - - src - - - - - - - + - + @@ -20,5 +15,14 @@ tests - + + + + src + + + + + + From 71a08c7a41a8e5ad71a3c4d7b465e38e5dc47333 Mon Sep 17 00:00:00 2001 From: Zachary Quintana Date: Tue, 10 Nov 2020 12:59:52 -0700 Subject: [PATCH 7/7] Update coveralls config. --- .coveralls.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.coveralls.yml b/.coveralls.yml index da396f1..ac8bd47 100644 --- a/.coveralls.yml +++ b/.coveralls.yml @@ -1,2 +1,4 @@ service_name: travis-pro repo_token: aHR2Vq500iS9DEQu5bwcAR2rotYnEqMq2 +coverage_clover: tmp/clover.xml +json_path: tmp/coveralls.json