Skip to content

Commit

Permalink
Merge pull request #33 from fotografde/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Mark S. committed Jan 22, 2015
2 parents e837cd8 + 184e850 commit 6aa9ee1
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 28 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ matrix:
- DB=mysql CAKE_VERSION=master COVERALLS=1

before_script:
- composer selfupdate
- git clone -b master https://github.com/FriendsOfCake/travis.git --depth 1 ../travis
- ../travis/before_script.sh
- cd ../cakephp/app
- ln -s ~/.composer/vendor/phpseclib ../vendors/phpseclib
- echo "Configure::write('Security.salt', 'AycG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');" >> Config/bootstrap.php
- echo "Configure::write('Security.cipherSeed', '16659201697453542496749683615');" >> Config/bootstrap.php
- cd ..
Expand Down
5 changes: 3 additions & 2 deletions Controller/FtpAppController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ class FtpAppController extends AppController {
*/
public function __construct($request = null, $response = null) {
parent::__construct($request, $response);
if (Configure::read('Cakeftp.enabled') !== true) {
throw new InternalErrorException(__d('cakeftp', 'CakeFTP client/console are disabled by default for security. To enable put Configure::write(\'Cakeftp.enabled\', true); in your Config/bootstrap.php or AppController.php.'));
// The latter is deprecated
if (!Configure::read('Ftp.enabled') && !Configure::read('Cakeftp.enabled')) {
throw new InternalErrorException(__d('cakeftp', 'CakePHP FTP client/console are disabled by default for security. To enable put Configure::write(\'Ftp.enabled\', true); in your Config/bootstrap.php or config file.'));
}
}
}
46 changes: 31 additions & 15 deletions Model/Datasource/FtpSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function init($config = array()) {
if (!empty($config['type'])) {
$config['type'] = strtolower($config['type']);
}
$this->config = array_merge($this->config, (array)$config);
$this->config = $config + $this->config;
if ($this->config['cache'] === true) {
Cache::config('cakeftp', array('engine' => 'File', 'prefix' => 'cakeftp_'));
$this->config['cache'] = 'cakeftp';
Expand Down Expand Up @@ -213,7 +213,7 @@ public function create(Model $model, $fields = null, $values = null) {
}
$data['direction'] = (!empty($data['direction'])) ? strtolower($data['direction']) : 'up';
$model->id = dirname($data['remote']);
if ($this->config['type'] == "ftp") {
if ($this->config['type'] === "ftp") {
if (!$this->_ftp('ftp_chdir', array($this->config['connection'], $model->id))) {
throw new Exception(__d('cakeftp', 'Could not change directory'));
}
Expand All @@ -235,7 +235,7 @@ public function create(Model $model, $fields = null, $values = null) {
$this->_ftp('unlink', array($data['local']));
throw new Exception(__d('cakeftp', 'Failed to download'));
}
} elseif ($this->config['type'] == "ssh") {
} elseif ($this->config['type'] === "ssh") {
$this->config['connection']->chdir($model->id);
switch ($data['direction']) {
case 'up':
Expand Down Expand Up @@ -291,11 +291,11 @@ public function delete(Model $model, $file = null) {
if (!$this->connect()) {
throw new Exception(__d('cakeftp', 'Failed to connect'));
}
if ($this->config['type'] == "ftp") {
if ($this->config['type'] === "ftp") {
if ($this->_ftp('ftp_delete', array($this->config['connection'], $file))) {
return true;
}
} elseif ($this->config['type'] == "ssh") {
} elseif ($this->config['type'] === "ssh") {
if ($this->config['connection']->delete($file)) {
return true;
}
Expand All @@ -313,13 +313,13 @@ public function delete(Model $model, $file = null) {
* @throws Exception
*/
public function query($query = null, $data = null) {
if (strtolower($query) == 'connect') {
if (strtolower($query) === 'connect') {
return $this->connect(current($data));
}
if (strtolower($query) == 'connection') {
if (strtolower($query) === 'connection') {
return $this->config;
}
if (strtolower($query) == 'console') {
if (strtolower($query) === 'console') {
return $this->console(current($data));
}
throw new Exception(__d('cakeftp', 'That method is not supported.'));
Expand Down Expand Up @@ -392,14 +392,17 @@ public function connect($config = array()) {
return true;

case 'ssh':
if (strpos(get_include_path(), 'phpseclib') === false) {
set_include_path(App::pluginPath('Ftp') . DS . 'Vendor' . DS . 'phpseclib' . DS . 'phpseclib' . DS . PATH_SEPARATOR . get_include_path());
if (!App::import('Vendor', 'Ftp.Net_SFTP', array('file' => 'phpseclib' . DS . 'phpseclib' . DS . 'Net' . DS . 'SFTP.php'))) {
throw new Exception(__d('cakeftp', 'Please upload the contents of the phpseclib (https://github.com/phpseclib/phpseclib) to the app/Plugin/Ftp/Vendor/phpseclib/ folder'));
// Deprecated way of not using composer, but a ROOT/vendors/phpseclib/ one (downloaded version).
if (!class_exists('Net_SFTP') && strpos(get_include_path(), 'phpseclib') === false) {
if (!App::import('Vendor', 'Net_SFTP', array('file' => 'phpseclib' . DS . 'phpseclib' . DS . 'Net' . DS . 'SFTP.php'))) {
throw new Exception(__d('cakeftp', 'Please upload the contents of the phpseclib (https://github.com/phpseclib/phpseclib) to the ROOT/vendors/phpseclib/ folder'));
}
}
if (!class_exists('Net_SFTP')) {
throw new Exception(__d('cakeftp', 'Please make sure phpseclib (https://github.com/phpseclib/phpseclib) is a loaded composer dependency.'));
}
$port = !empty($this->config['port']) ? $this->config['port'] : 22;
$this->config['connection'] = new Net_SFTP($this->config['host'], $port);
$this->config['connection'] = $this->_getFtp($this->config['host'], $port);
if (!$this->config['connection']->login($this->config['username'], $this->config['password'])) {
unset($this->config['connection']);
throw new Exception(__d('cakeftp', 'Login failed'));
Expand All @@ -410,6 +413,19 @@ public function connect($config = array()) {
return false;
}

/**
* FtpSource::_getFtp()
*
* Allows mocking of the ssh ftp class.
*
* @param string $host
* @param int $port
* @return Net_SFTP Instance
*/
protected function _getFtp($host, $port = 22) {
return new Net_SFTP();
}

/**
* console
* @param string $cmd
Expand Down Expand Up @@ -439,7 +455,7 @@ public function console($cmd = null) {
*/
public function quit() {
if (isset($this->config['connection']) && $this->config['connection']) {
if ($this->config['type'] == "ftp") {
if ($this->config['type'] === "ftp") {
$this->_ftp('ftp_close', array($this->config['connection']));
}
$this->config['connection'] = null;
Expand Down Expand Up @@ -499,7 +515,7 @@ protected function _parsels($ls = null, $path = '') {
if (empty($line)) {
continue;
}
if (substr($line, -1) == ':') {
if (substr($line, -1) === ':') {
$thisPath = substr($line, strlen($path), -1);
continue;
}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![License](https://poser.pugx.org/fotografde/cakephp-ftp/license.svg)](https://packagist.org/packages/fotografde/cakephp-ftp)
[![Total Downloads](https://poser.pugx.org/fotografde/cakephp-ftp/d/total.svg)](https://packagist.org/packages/fotografde/cakephp-ftp)

Requires: CakePHP 2.0+ (tested with CakePHP 2.5+), PHP 5.2+ (tested with PHP5.3+)
Requires: CakePHP 2.0+ (tested with CakePHP 2.5+), PHP 5.3+, phpseclib for ssh

## Features

Expand Down
63 changes: 53 additions & 10 deletions Test/Case/Model/Datasource/FtpSourceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
App::uses('DataSource', 'Model/Datasource');
App::uses('FtpSource', 'Ftp.Model/Datasource');

/*
if (!class_exists('Net_SFTP') && strpos(get_include_path(), 'phpseclib') === false) {
if (!App::import('Vendor', 'Net_SFTP', array('file' => 'phpseclib' . DS . 'phpseclib' . DS . 'Net' . DS . 'SFTP.php'))) {
throw new Exception(__d('cakeftp', 'Please upload the contents of the phpseclib (https://github.com/phpseclib/phpseclib) to the APP/Vendor/phpseclib/ folder'));
}
}
if (!class_exists('Net_SFTP')) {
throw new Exception(__d('cakeftp', 'Please make sure phpseclib (https://github.com/phpseclib/phpseclib) is a loaded composer dependency.'));
}
*/

/**
* Ftp Source Test
*
Expand Down Expand Up @@ -69,10 +80,10 @@ public function tearDown() {
}

/**
* testInit
* testInit and uppercase type
*/
public function testInit() {
$this->FtpSource = new FtpSource(array($this->defaultConfig));
$this->FtpSource = new FtpSource($this->defaultConfig);
$data = array('type' => 'FTP', 'cache' => true);
$this->assertTrue($this->FtpSource->init($data));
$this->assertEqual($this->FtpSource->config['type'], 'ftp');
Expand All @@ -91,7 +102,7 @@ public function testConnect() {
// FTP FAILED CONNECT
$this->FtpSource = $this->getMock('FtpSource', array('_ftp'), array($this->defaultConfig));
$callback = create_function('$method,$params', <<<END
if (\$method == "ftp_connect") {
if (\$method === "ftp_connect") {
return false;
}
return true;
Expand All @@ -109,7 +120,7 @@ public function testConnect() {
// FTP FAILED LOGIN
$this->FtpSource = $this->getMock('FtpSource', array('_ftp'), array($this->defaultConfig));
$callback = create_function('$method,$params', <<<END
if (\$method == "ftp_login") {
if (\$method === "ftp_login") {
return false;
}
return true;
Expand All @@ -135,17 +146,49 @@ public function testConnect() {
// TODO: ADD SFTP
}

/**
* testConnectSsh
*/
public function testConnectSsh() {
$this->skipIf(true, 'FIXME: Non-composered vendor of phpseclib not found in travis, locally it\'s fine.');

$config = array('type' => 'ssh') + $this->defaultConfig;
$this->FtpSource = $this->getMock('FtpSource', array('_getFtp'), array($config));
$data = array('cache' => true);
$this->assertTrue($this->FtpSource->init($data));
$this->assertEqual($this->FtpSource->config['type'], 'ssh');
$this->assertEqual($this->FtpSource->config['cache'], 'cakeftp');

$this->assertTrue($this->FtpSource->init(array(
'host' => 'https://localhost',
)));
$this->assertEquals('localhost', $this->FtpSource->config['host']);

$Ftp = $this->getMock('Net_SFTP', array(), array('https://localhost', 21));
$this->FtpSource->expects($this->once())
->method('_getFtp')
->with('localhost', 21)
->will($this->returnValue($Ftp));
$Ftp->expects($this->once())
->method('login')
->with('testuser', 1234)
->will($this->returnValue(true));

$result = $this->FtpSource->connect();
$this->assertTrue($result);
}

/**
* testRead
*/
public function testRead() {
$Model = new FtpSourceTestModel();
$this->FtpSource = $this->getMock('FtpSource', array('_ftp'), array($this->defaultConfig));
$callback = create_function('$method,$params', <<<END
if (\$method == 'ftp_pwd') {
if (\$method === 'ftp_pwd') {
return '/path/to/remote/folder/';
}
if (\$method == 'ftp_rawlist') {
if (\$method === 'ftp_rawlist') {
return array(
"drwxr-x--- 3 kyle group 4096 Jul 12 12:16 public_ftp",
"drwxr-x--- 15 kyle group 4096 Nov 3 21:31 public_html",
Expand Down Expand Up @@ -192,10 +235,10 @@ public function testCreate() {
$Model = new FtpSourceTestModel();
$this->FtpSource = $this->getMock('FtpSource', array('_ftp'), array($this->defaultConfig));
$callback = create_function('$method,$params', <<<END
if (\$method == 'ftp_put') {
if (\$method === 'ftp_put') {
return false;
}
if (\$method == 'ftp_get') {
if (\$method === 'ftp_get') {
return false;
}
return true;
Expand Down Expand Up @@ -235,10 +278,10 @@ public function testDelete() {
$Model = new FtpSourceTestModel();
$this->FtpSource = $this->getMock('FtpSource', array('_ftp'), array($this->defaultConfig));
$callback = create_function('$method,$params', <<<END
if (\$method == 'ftp_delete') {
if (\$method === 'ftp_delete') {
return true;
}
if (\$method == 'ftp_connect' || \$method == 'ftp_login') {
if (\$method === 'ftp_connect' || \$method === 'ftp_login') {
return true;
}
return false;
Expand Down

0 comments on commit 6aa9ee1

Please sign in to comment.