1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
<?php
class FileTranferTest extends DrupalWebTestCase {
protected $hostname = 'localhost';
protected $username = 'drupal';
protected $password = 'password';
protected $port = '42';
public static function getInfo() {
return array(
'name' => 'FileTransfer unit tests',
'description' => 'Test that the jail is respected and that protocols using recursive file move operations work.',
'group' => 'System'
);
}
function setUp() {
parent::setUp();
$this->testConnection = TestFileTransfer::factory(DRUPAL_ROOT, array('hostname' => $this->hostname, 'username' => $this->username, 'password' => $this->password, 'port' => $this->port));
}
function _getFakeModuleFiles() {
$files = array(
'fake.module',
'fake.info',
'theme' => array(
'fake.tpl.php'
),
'inc' => array(
'fake.inc'
)
);
return $files;
}
function _buildFakeModule() {
$location = 'temporary://fake';
if (is_dir($location)) {
$ret = 0;
$output = array();
exec('rm -Rf ' . escapeshellarg($location), $output, $ret);
if ($ret != 0) {
throw new Exception('Error removing fake module directory.');
}
}
$files = $this->_getFakeModuleFiles();
$this->_writeDirectory($location, $files);
return $location;
}
function _writeDirectory($base, $files = array()) {
mkdir($base);
foreach ($files as $key => $file) {
if (is_array($file)) {
$this->_writeDirectory($base . DIRECTORY_SEPARATOR . $key, $file);
}
else {
//just write the filename into the file
file_put_contents($base . DIRECTORY_SEPARATOR . $file, $file);
}
}
}
function testJail() {
$source = $this->_buildFakeModule();
// This convoluted piece of code is here because our testing framework does
// not support expecting exceptions.
$gotit = FALSE;
try {
$this->testConnection->copyDirectory($source, '/tmp');
}
catch (FileTransferException $e) {
$gotit = TRUE;
}
$this->assertTrue($gotit, 'Was not able to copy a directory outside of the jailed area.');
$gotit = TRUE;
try {
$this->testConnection->copyDirectory($source, DRUPAL_ROOT . '/'. variable_get('file_public_path', conf_path() . '/files'));
}
catch (FileTransferException $e) {
$gotit = FALSE;
}
$this->assertTrue($gotit, 'Was able to copy a directory inside of the jailed area');
}
}
/**
* Mock FileTransfer object for test case.
*/
class TestFileTransfer extends FileTransfer {
protected $host = NULL;
protected $username = NULL;
protected $password = NULL;
protected $port = NULL;
/**
* This is for testing the CopyRecursive logic.
*/
public $shouldIsDirectoryReturnTrue = FALSE;
function __construct($jail, $username, $password, $hostname = 'localhost', $port = 9999) {
parent::__construct($jail, $username, $password, $hostname, $port);
}
static function factory($jail, $settings) {
return new TestFileTransfer($jail, $settings['username'], $settings['password'], $settings['hostname'], $settings['port']);
}
function connect() {
$parts = explode(':', $this->hostname);
$port = (count($parts) == 2) ? $parts[1] : $this->port;
$this->connection = new MockTestConnection();
$this->connection->connectionString = 'test://' . urlencode($this->username) . ':' . urlencode($this->password) . "@$this->host:$this->port/";
}
function copyFileJailed($source, $destination) {
$this->connection->run("copyFile $source $destination");
}
protected function removeDirectoryJailed($directory) {
$this->connection->run("rmdir $directory");
}
function createDirectoryJailed($directory) {
$this->connection->run("mkdir $directory");
}
function removeFileJailed($destination) {
if (!ftp_delete($this->connection, $item)) {
throw new FileTransferException('Unable to remove to file @file.', NULL, array('@file' => $item));
}
}
function isDirectory($path) {
return $this->shouldIsDirectoryReturnTrue;
}
function isFile($path) {
return FALSE;
}
function chmodJailed($path, $mode, $recursive) {
return;
}
}
/**
* Mock connection object for test case.
*/
class MockTestConnection {
var $commandsRun = array();
var $connectionString;
function run($cmd) {
$this->commandsRun[] = $cmd;
}
function flushCommands() {
$out = $this->commandsRun;
$this->commandsRun = array();
return $out;
}
}
|