|
|
|
|
@ -6,6 +6,7 @@
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
use yii\helpers\FileHelper;
|
|
|
|
|
use yii\helpers\VarDumper;
|
|
|
|
|
use yiiunit\TestCase;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -937,4 +938,309 @@ class FileHelperTest extends TestCase
|
|
|
|
|
sort($foundFiles);
|
|
|
|
|
$this->assertEquals($expectedFiles, $foundFiles);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testChangeOwnership()
|
|
|
|
|
{
|
|
|
|
|
if (DIRECTORY_SEPARATOR !== '/') {
|
|
|
|
|
$this->markTestSkipped('FileHelper::changeOwnership() fails silently on Windows, nothing to test.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!extension_loaded('posix')) {
|
|
|
|
|
$this->markTestSkipped('posix extension is required.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$dirName = 'change_ownership_test_dir';
|
|
|
|
|
$fileName = 'file_1.txt';
|
|
|
|
|
$testFile = $this->testFilePath . DIRECTORY_SEPARATOR . $dirName . DIRECTORY_SEPARATOR . $fileName;
|
|
|
|
|
|
|
|
|
|
$currentUserId = posix_getuid();
|
|
|
|
|
$currentUserName = posix_getpwuid($currentUserId)['name'];
|
|
|
|
|
$currentGroupId = posix_getgid();
|
|
|
|
|
$currentGroupName = posix_getgrgid($currentGroupId)['name'];
|
|
|
|
|
|
|
|
|
|
/////////////
|
|
|
|
|
/// Setup ///
|
|
|
|
|
/////////////
|
|
|
|
|
|
|
|
|
|
$this->createFileStructure([
|
|
|
|
|
$dirName => [
|
|
|
|
|
$fileName => 'test 1',
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Ensure the test file is created as the current user/group and has a specific file mode
|
|
|
|
|
$this->assertFileExists($testFile);
|
|
|
|
|
$fileMode = 0770;
|
|
|
|
|
@chmod($testFile, $fileMode);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($currentUserId, fileowner($testFile), 'Expected created test file owner to be current user.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected created test file group to be current group.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be changed.');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////
|
|
|
|
|
/// File Mode ///
|
|
|
|
|
/////////////////
|
|
|
|
|
|
|
|
|
|
// Test file mode
|
|
|
|
|
$fileMode = 0777;
|
|
|
|
|
FileHelper::changeOwnership($testFile, null, $fileMode);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($currentUserId, fileowner($testFile), 'Expected file owner to be unchanged.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be changed.');
|
|
|
|
|
|
|
|
|
|
if ($currentUserId !== 0) {
|
|
|
|
|
$this->markTestInComplete(__METHOD__ . ' could only run partially, chown() can only to be tested as root user. Current user: ' . $currentUserName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////
|
|
|
|
|
/// User Ownership ///
|
|
|
|
|
//////////////////////
|
|
|
|
|
|
|
|
|
|
// Test user ownership as integer
|
|
|
|
|
$ownership = 10001;
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($ownership, fileowner($testFile), 'Expected file owner to be changed.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user ownership as numeric string (should be treated as integer)
|
|
|
|
|
$ownership = '10002';
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals((int)$ownership, fileowner($testFile), 'Expected created test file owner to be changed.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user ownership as string
|
|
|
|
|
$ownership = $currentUserName;
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($ownership, posix_getpwuid(fileowner($testFile))['name'], 'Expected created test file owner to be changed.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user ownership as numeric string with trailing colon (should be treated as integer)
|
|
|
|
|
$ownership = '10003:';
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals((int)$ownership, fileowner($testFile), 'Expected created test file owner to be changed.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user ownership as string with trailing colon
|
|
|
|
|
$ownership = $currentUserName . ':';
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals(substr($ownership, 0, -1), posix_getpwuid(fileowner($testFile))['name'], 'Expected created test file owner to be changed.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user ownership as indexed array (integer value)
|
|
|
|
|
$ownership = [10004];
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($ownership[0], fileowner($testFile), 'Expected created test file owner to be changed.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user ownership as indexed array (numeric string value)
|
|
|
|
|
$ownership = ['10005'];
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals((int)$ownership[0], fileowner($testFile), 'Expected created test file owner to be changed.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user ownership as associative array (string value)
|
|
|
|
|
$ownership = ['user' => $currentUserName];
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($ownership['user'], posix_getpwuid(fileowner($testFile))['name'], 'Expected created test file owner to be changed.');
|
|
|
|
|
$this->assertEquals($currentGroupId, filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
///////////////////////
|
|
|
|
|
/// Group Ownership ///
|
|
|
|
|
///////////////////////
|
|
|
|
|
|
|
|
|
|
// Test group ownership as numeric string
|
|
|
|
|
$ownership = ':10006';
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($currentUserId, fileowner($testFile), 'Expected file owner to be unchanged.');
|
|
|
|
|
$this->assertEquals((int)substr($ownership, 1), filegroup($testFile), 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test group ownership as string
|
|
|
|
|
$ownership = ':' . $currentGroupName;
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($currentUserId, fileowner($testFile), 'Expected file owner to be unchanged.');
|
|
|
|
|
$this->assertEquals(substr($ownership, 1), posix_getgrgid(filegroup($testFile))['name'], 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test group ownership as associative array (integer value)
|
|
|
|
|
$ownership = ['group' => 10007];
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($currentUserId, fileowner($testFile), 'Expected file owner to be unchanged.');
|
|
|
|
|
$this->assertEquals($ownership['group'], filegroup($testFile), 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test group ownership as associative array (numeric string value)
|
|
|
|
|
$ownership = ['group' => '10008'];
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($currentUserId, fileowner($testFile), 'Expected file owner to be unchanged.');
|
|
|
|
|
$this->assertEquals((int)$ownership['group'], filegroup($testFile), 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test group ownership as associative array (string value)
|
|
|
|
|
$ownership = ['group' => $currentGroupName];
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($currentUserId, fileowner($testFile), 'Expected file owner to be unchanged.');
|
|
|
|
|
$this->assertEquals($ownership['group'], posix_getgrgid(filegroup($testFile))['name'], 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////
|
|
|
|
|
/// User- and Group Ownership ///
|
|
|
|
|
/////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Test user and group ownership as numeric string
|
|
|
|
|
$ownership = '10009:10010';
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals((int)explode(':', $ownership)[0], fileowner($testFile), 'Expected file owner to be changed.');
|
|
|
|
|
$this->assertEquals((int)explode(':', $ownership)[1], filegroup($testFile), 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user and group ownership as string
|
|
|
|
|
$ownership = $currentUserName . ':' . $currentGroupName;
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals(explode(':', $ownership)[0], posix_getpwuid(fileowner($testFile))['name'], 'Expected file owner to be changed.');
|
|
|
|
|
$this->assertEquals(explode(':', $ownership)[1], posix_getgrgid(filegroup($testFile))['name'], 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user and group ownership as indexed array (integer values)
|
|
|
|
|
$ownership = [10011, 10012];
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($ownership[0], fileowner($testFile), 'Expected file owner to be changed.');
|
|
|
|
|
$this->assertEquals($ownership[1], filegroup($testFile), 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user and group ownership as indexed array (numeric string values)
|
|
|
|
|
$ownership = ['10013', '10014'];
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals((int)$ownership[0], fileowner($testFile), 'Expected file owner to be changed.');
|
|
|
|
|
$this->assertEquals((int)$ownership[1], filegroup($testFile), 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user and group ownership as indexed array (string values)
|
|
|
|
|
$ownership = [$currentUserName, $currentGroupName];
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($ownership[0], posix_getpwuid(fileowner($testFile))['name'], 'Expected file owner to be changed.');
|
|
|
|
|
$this->assertEquals($ownership[1], posix_getgrgid(filegroup($testFile))['name'], 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user and group ownership as associative array (integer values)
|
|
|
|
|
$ownership = ['group' => 10015, 'user' => 10016]; // user/group reversed on purpose
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($ownership['user'], fileowner($testFile), 'Expected file owner to be changed.');
|
|
|
|
|
$this->assertEquals($ownership['group'], filegroup($testFile), 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user and group ownership as associative array (numeric string values)
|
|
|
|
|
$ownership = ['group' => '10017', 'user' => '10018']; // user/group reversed on purpose
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals((int)$ownership['user'], fileowner($testFile), 'Expected file owner to be changed.');
|
|
|
|
|
$this->assertEquals((int)$ownership['group'], filegroup($testFile), 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
// Test user and group ownership as associative array (string values)
|
|
|
|
|
$ownership = ['group' => $currentGroupName, 'user' => $currentUserName]; // user/group reversed on purpose
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals($ownership['user'], posix_getpwuid(fileowner($testFile))['name'], 'Expected file owner to be changed.');
|
|
|
|
|
$this->assertEquals($ownership['group'], posix_getgrgid(filegroup($testFile))['name'], 'Expected created test file group to be changed.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected file mode to be unchanged.');
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////
|
|
|
|
|
/// Mode, User- and Group Ownership ///
|
|
|
|
|
///////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
// Test user ownership as integer with file mode
|
|
|
|
|
$ownership = '10019:10020';
|
|
|
|
|
$fileMode = 0774;
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership, $fileMode);
|
|
|
|
|
clearstatcache(true, $testFile);
|
|
|
|
|
$this->assertEquals(explode(':', $ownership)[0], fileowner($testFile), 'Expected created test file owner to be changed.');
|
|
|
|
|
$this->assertEquals(explode(':', $ownership)[1], filegroup($testFile), 'Expected file group to be unchanged.');
|
|
|
|
|
$this->assertEquals('0'.decoct($fileMode), substr(decoct(fileperms($testFile)), -4), 'Expected created test file mode to be changed.');
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testChangeOwnershipNonExistingUser()
|
|
|
|
|
{
|
|
|
|
|
$dirName = 'change_ownership_non_existing_user';
|
|
|
|
|
$fileName = 'file_1.txt';
|
|
|
|
|
$testFile = $this->testFilePath . DIRECTORY_SEPARATOR . $dirName . DIRECTORY_SEPARATOR . $fileName;
|
|
|
|
|
|
|
|
|
|
$this->createFileStructure([
|
|
|
|
|
$dirName => [
|
|
|
|
|
$fileName => 'test 1',
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Test user ownership as integer with file mode (Due to the nature of chown we can't use PHPUnit's `expectException`)
|
|
|
|
|
$ownership = 'non_existing_user';
|
|
|
|
|
try {
|
|
|
|
|
FileHelper::changeOwnership($testFile, $ownership);
|
|
|
|
|
throw new \Exception('FileHelper::changeOwnership() should have thrown error for non existing user.');
|
|
|
|
|
} catch(\Exception $e) {
|
|
|
|
|
$this->assertEquals('chown(): Unable to find uid for non_existing_user', $e->getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @dataProvider changeOwnershipInvalidArgumentsProvider
|
|
|
|
|
* @param bool $useFile
|
|
|
|
|
* @param mixed $ownership
|
|
|
|
|
* @param mixed $mode
|
|
|
|
|
*/
|
|
|
|
|
public function testChangeOwnershipInvalidArguments($useFile, $ownership, $mode)
|
|
|
|
|
{
|
|
|
|
|
$dirName = 'change_ownership_invalid_arguments';
|
|
|
|
|
$fileName = 'file_1.txt';
|
|
|
|
|
$file = $this->testFilePath . DIRECTORY_SEPARATOR . $dirName . DIRECTORY_SEPARATOR . $fileName;
|
|
|
|
|
|
|
|
|
|
$this->createFileStructure([
|
|
|
|
|
$dirName => [
|
|
|
|
|
$fileName => 'test 1',
|
|
|
|
|
],
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
$this->expectException('yii\base\InvalidArgumentException');
|
|
|
|
|
FileHelper::changeOwnership($useFile ? $file : null, $ownership, $mode);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function changeOwnershipInvalidArgumentsProvider()
|
|
|
|
|
{
|
|
|
|
|
return [
|
|
|
|
|
[false, '123:123', null],
|
|
|
|
|
[true, new stdClass(), null],
|
|
|
|
|
[true, ['user' => new stdClass()], null],
|
|
|
|
|
[true, ['group' => new stdClass()], null],
|
|
|
|
|
[true, null, 'test'],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|