From 4b7f5a728a6f44e08cd84c1d6333cf413b42361c Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Fri, 30 Aug 2013 16:52:33 +0200 Subject: [PATCH] improved control over and handling of file and dir permissions - rename FileHelper::mkdir for API consistency - changed default permission for directories to 775 instead of 777 - added some properties to classes that deal with files to allow control over directory permissions. --- extensions/mutex/yii/mutex/FileMutex.php | 24 +++++++++++++++++++++--- framework/yii/caching/FileCache.php | 23 ++++++++++++++++++++--- framework/yii/helpers/FileHelperBase.php | 14 +++++++------- framework/yii/log/FileTarget.php | 19 ++++++++++++++++++- framework/yii/web/AssetManager.php | 11 ++++++----- tests/unit/framework/helpers/FileHelperTest.php | 4 ++-- 6 files changed, 74 insertions(+), 21 deletions(-) diff --git a/extensions/mutex/yii/mutex/FileMutex.php b/extensions/mutex/yii/mutex/FileMutex.php index ab418ba..5ac9262 100644 --- a/extensions/mutex/yii/mutex/FileMutex.php +++ b/extensions/mutex/yii/mutex/FileMutex.php @@ -9,6 +9,7 @@ namespace yii\mutex; use Yii; use yii\base\InvalidConfigException; +use yii\helpers\FileHelper; /** * @author resurtm @@ -22,6 +23,19 @@ class FileMutex extends Mutex */ public $mutexPath = '@runtime/mutex'; /** + * @var integer the permission to be set for newly created mutex files. + * This value will be used by PHP chmod() function. No umask will be applied. + * If not set, the permission will be determined by the current environment. + */ + public $fileMode; + /** + * @var integer the permission to be set for newly created directories. + * This value will be used by PHP chmod() function. No umask will be applied. + * Defaults to 0775, meaning the directory is read-writable by owner and group, + * but read-only for other users. + */ + public $dirMode = 0775; + /** * @var resource[] stores all opened lock files. Keys are lock names and values are file handles. */ private $_files = array(); @@ -39,22 +53,26 @@ class FileMutex extends Mutex } $this->mutexPath = Yii::getAlias($this->mutexPath); if (!is_dir($this->mutexPath)) { - mkdir($this->mutexPath, 0777, true); + FileHelper::createDirectory($this->mutexPath, $this->dirMode, true); } } /** - * This method should be extended by concrete mutex implementations. Acquires lock by given name. + * Acquires lock by given name. * @param string $name of the lock to be acquired. * @param integer $timeout to wait for lock to become released. * @return boolean acquiring result. */ protected function acquireLock($name, $timeout = 0) { - $file = fopen($this->mutexPath . '/' . md5($name) . '.lock', 'w+'); + $fileName = $this->mutexPath . '/' . md5($name) . '.lock'; + $file = fopen($fileName, 'w+'); if ($file === false) { return false; } + if ($this->fileMode !== null) { + @chmod($fileName, $this->fileMode); + } $waitTime = 0; while (!flock($file, LOCK_EX | LOCK_NB)) { $waitTime++; diff --git a/framework/yii/caching/FileCache.php b/framework/yii/caching/FileCache.php index 437a7be..32cdf58 100644 --- a/framework/yii/caching/FileCache.php +++ b/framework/yii/caching/FileCache.php @@ -8,6 +8,7 @@ namespace yii\caching; use Yii; +use yii\helpers\FileHelper; /** * FileCache implements a cache component using files. @@ -45,6 +46,20 @@ class FileCache extends Cache * This number should be between 0 and 1000000. A value 0 means no GC will be performed at all. **/ public $gcProbability = 10; + /** + * @var integer the permission to be set for newly created cache files. + * This value will be used by PHP chmod() function. No umask will be applied. + * If not set, the permission will be determined by the current environment. + */ + public $fileMode; + /** + * @var integer the permission to be set for newly created directories. + * This value will be used by PHP chmod() function. No umask will be applied. + * Defaults to 0775, meaning the directory is read-writable by owner and group, + * but read-only for other users. + */ + public $dirMode = 0775; + /** * Initializes this component by ensuring the existence of the cache path. @@ -54,7 +69,7 @@ class FileCache extends Cache parent::init(); $this->cachePath = Yii::getAlias($this->cachePath); if (!is_dir($this->cachePath)) { - mkdir($this->cachePath, 0777, true); + FileHelper::createDirectory($this->cachePath, $this->dirMode, true); } } @@ -108,10 +123,12 @@ class FileCache extends Cache $cacheFile = $this->getCacheFile($key); if ($this->directoryLevel > 0) { - @mkdir(dirname($cacheFile), 0777, true); + @FileHelper::createDirectory(dirname($cacheFile), $this->dirMode, true); } if (@file_put_contents($cacheFile, $value, LOCK_EX) !== false) { - @chmod($cacheFile, 0777); + if ($this->fileMode !== null) { + @chmod($cacheFile, $this->fileMode); + } return @touch($cacheFile, $expire); } else { return false; diff --git a/framework/yii/helpers/FileHelperBase.php b/framework/yii/helpers/FileHelperBase.php index 6358ea1..0e480da 100644 --- a/framework/yii/helpers/FileHelperBase.php +++ b/framework/yii/helpers/FileHelperBase.php @@ -133,7 +133,7 @@ class FileHelperBase * @param string $dst the destination directory * @param array $options options for directory copy. Valid options are: * - * - dirMode: integer, the permission to be set for newly copied directories. Defaults to 0777. + * - dirMode: integer, the permission to be set for newly copied directories. Defaults to 0775. * - fileMode: integer, the permission to be set for newly copied files. Defaults to the current environment setting. * - filter: callback, a PHP callback that is called for each directory or file. * The signature of the callback should be: `function ($path)`, where `$path` refers the full path to be filtered. @@ -162,7 +162,7 @@ class FileHelperBase public static function copyDirectory($src, $dst, $options = array()) { if (!is_dir($dst)) { - static::mkdir($dst, isset($options['dirMode']) ? $options['dirMode'] : 0777, true); + static::createDirectory($dst, isset($options['dirMode']) ? $options['dirMode'] : 0775, true); } $handle = opendir($src); @@ -302,25 +302,25 @@ class FileHelperBase } /** - * Makes directory. + * Creates a new directory. * * This method is similar to the PHP `mkdir()` function except that * it uses `chmod()` to set the permission of the created directory * in order to avoid the impact of the `umask` setting. * - * @param string $path path to be created. - * @param integer $mode the permission to be set for created directory. + * @param string $path path of the directory to be created. + * @param integer $mode the permission to be set for the created directory. * @param boolean $recursive whether to create parent directories if they do not exist. * @return boolean whether the directory is created successfully */ - public static function mkdir($path, $mode = 0777, $recursive = true) + public static function createDirectory($path, $mode = 0775, $recursive = true) { if (is_dir($path)) { return true; } $parentDir = dirname($path); if ($recursive && !is_dir($parentDir)) { - static::mkdir($parentDir, $mode, true); + static::createDirectory($parentDir, $mode, true); } $result = mkdir($path, $mode); chmod($path, $mode); diff --git a/framework/yii/log/FileTarget.php b/framework/yii/log/FileTarget.php index 74a33be..970c71b 100644 --- a/framework/yii/log/FileTarget.php +++ b/framework/yii/log/FileTarget.php @@ -9,6 +9,7 @@ namespace yii\log; use Yii; use yii\base\InvalidConfigException; +use yii\helpers\FileHelper; /** * FileTarget records log messages in a file. @@ -37,6 +38,19 @@ class FileTarget extends Target * @var integer number of log files used for rotation. Defaults to 5. */ public $maxLogFiles = 5; + /** + * @var integer the permission to be set for newly created log files. + * This value will be used by PHP chmod() function. No umask will be applied. + * If not set, the permission will be determined by the current environment. + */ + public $fileMode; + /** + * @var integer the permission to be set for newly created directories. + * This value will be used by PHP chmod() function. No umask will be applied. + * Defaults to 0775, meaning the directory is read-writable by owner and group, + * but read-only for other users. + */ + public $dirMode = 0775; /** @@ -53,7 +67,7 @@ class FileTarget extends Target } $logPath = dirname($this->logFile); if (!is_dir($logPath)) { - @mkdir($logPath, 0777, true); + FileHelper::createDirectory($logPath, $this->dirMode, true); } if ($this->maxLogFiles < 1) { $this->maxLogFiles = 1; @@ -87,6 +101,9 @@ class FileTarget extends Target @flock($fp, LOCK_UN); @fclose($fp); } + if ($this->fileMode !== null) { + @chmod($this->logFile, $this->fileMode); + } } /** diff --git a/framework/yii/web/AssetManager.php b/framework/yii/web/AssetManager.php index 43e7cf9..c6f7fea 100644 --- a/framework/yii/web/AssetManager.php +++ b/framework/yii/web/AssetManager.php @@ -58,16 +58,17 @@ class AssetManager extends Component public $linkAssets = false; /** * @var integer the permission to be set for newly published asset files. - * This value will be used by PHP chmod() function. + * This value will be used by PHP chmod() function. No umask will be applied. * If not set, the permission will be determined by the current environment. */ public $fileMode; /** * @var integer the permission to be set for newly generated asset directories. - * This value will be used by PHP chmod() function. - * Defaults to 0777, meaning the directory can be read, written and executed by all users. + * This value will be used by PHP chmod() function. No umask will be applied. + * Defaults to 0775, meaning the directory is read-writable by owner and group, + * but read-only for other users. */ - public $dirMode = 0777; + public $dirMode = 0775; /** * Initializes the component. @@ -205,7 +206,7 @@ class AssetManager extends Component $dstFile = $dstDir . DIRECTORY_SEPARATOR . $fileName; if (!is_dir($dstDir)) { - mkdir($dstDir, $this->dirMode, true); + FileHelper::createDirectory($dstDir, $this->dirMode, true); } if ($this->linkAssets) { diff --git a/tests/unit/framework/helpers/FileHelperTest.php b/tests/unit/framework/helpers/FileHelperTest.php index 896218e..7c0f8c4 100644 --- a/tests/unit/framework/helpers/FileHelperTest.php +++ b/tests/unit/framework/helpers/FileHelperTest.php @@ -275,9 +275,9 @@ class FileHelperTest extends TestCase { $basePath = $this->testFilePath; $dirName = $basePath . DIRECTORY_SEPARATOR . 'test_dir_level_1' . DIRECTORY_SEPARATOR . 'test_dir_level_2'; - $this->assertTrue(FileHelper::mkdir($dirName), 'FileHelper::mkdir should return true if directory was created!'); + $this->assertTrue(FileHelper::createDirectory($dirName), 'FileHelper::mkdir should return true if directory was created!'); $this->assertTrue(file_exists($dirName), 'Unable to create directory recursively!'); - $this->assertTrue(FileHelper::mkdir($dirName), 'FileHelper::mkdir should return true for already existing directories!'); + $this->assertTrue(FileHelper::createDirectory($dirName), 'FileHelper::mkdir should return true for already existing directories!'); } public function testGetMimeTypeByExtension()