File permissions changes
This commit is contained in:
@@ -44,7 +44,6 @@ class Manager
|
||||
if (isset($config)) {
|
||||
$params = array(
|
||||
'defaultPermissions' => $config->get('defaultPermissions'),
|
||||
'permissionMap' => $config->get('permissionMap'),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -381,11 +380,11 @@ class Manager
|
||||
{
|
||||
$fullPath = $this->concatPaths($path);
|
||||
|
||||
if (file_exists($fullPath) && is_dir($path)) {
|
||||
if (file_exists($fullPath) && is_dir($fullPath)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$defaultPermissions = $this->getPermissionUtils()->getDefaultPermissions();
|
||||
$defaultPermissions = $this->getPermissionUtils()->getRequiredPermissions($fullPath);
|
||||
|
||||
if (!isset($permission)) {
|
||||
$permission = (string) $defaultPermissions['dir'];
|
||||
@@ -393,7 +392,11 @@ class Manager
|
||||
}
|
||||
|
||||
try {
|
||||
$umask = @umask(0);
|
||||
$result = mkdir($fullPath, $permission, true);
|
||||
if ($umask) {
|
||||
@umask($umask);
|
||||
}
|
||||
|
||||
if (!empty($defaultPermissions['user'])) {
|
||||
$this->getPermissionUtils()->chown($fullPath);
|
||||
@@ -484,11 +487,11 @@ class Manager
|
||||
*/
|
||||
public function checkCreateFile($filePath)
|
||||
{
|
||||
$defaultPermissions = $this->getPermissionUtils()->getDefaultPermissions();
|
||||
$defaultPermissions = $this->getPermissionUtils()->getRequiredPermissions($filePath);
|
||||
|
||||
if (file_exists($filePath)) {
|
||||
if (!is_writable($filePath) && !in_array($this->getPermissionUtils()->getCurrentPermission($filePath), array($defaultPermissions['file'], $defaultPermissions['dir']))) {
|
||||
return $this->getPermissionUtils()->setDefaultPermissions($filePath, true);
|
||||
return $this->getPermissionUtils()->setDefaultPermissions($filePath);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -504,7 +507,7 @@ class Manager
|
||||
}
|
||||
|
||||
if (touch($filePath)) {
|
||||
return $this->getPermissionUtils()->setDefaultPermissions($filePath, true);
|
||||
return $this->getPermissionUtils()->setDefaultPermissions($filePath);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Utils\File;
|
||||
use Espo\Core\Utils,
|
||||
Espo\Core\Exceptions\Error;
|
||||
|
||||
use Espo\Core\Utils;
|
||||
use Espo\Core\Exceptions\Error;
|
||||
|
||||
class Permission
|
||||
{
|
||||
@@ -44,47 +45,45 @@ class Permission
|
||||
|
||||
protected $permissionErrorRules = null;
|
||||
|
||||
protected $params = array(
|
||||
'defaultPermissions' => array (
|
||||
'dir' => '0775',
|
||||
'file' => '0664',
|
||||
'user' => '',
|
||||
'group' => '',
|
||||
),
|
||||
'permissionMap' => array(
|
||||
protected $writableMap = [
|
||||
'data' => [
|
||||
'recursive' => true,
|
||||
],
|
||||
'application/Espo/Modules' => [
|
||||
'recursive' => false,
|
||||
],
|
||||
'client/modules' => [
|
||||
'recursive' => false,
|
||||
],
|
||||
'custom/Espo/Custom' => [
|
||||
'recursive' => true,
|
||||
],
|
||||
];
|
||||
|
||||
/** array('0664', '0775') */
|
||||
'writable' => array(
|
||||
'data',
|
||||
'custom',
|
||||
),
|
||||
|
||||
/** array('0644', '0755') */
|
||||
'readable' => array(
|
||||
'api',
|
||||
'application',
|
||||
'client',
|
||||
'vendor',
|
||||
'index.php',
|
||||
'cron.php',
|
||||
'rebuild.php',
|
||||
'main.html',
|
||||
'reset.html',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
protected $permissionRules = array(
|
||||
'writable' => array('0664', '0775'),
|
||||
'readable' => array('0644', '0755'),
|
||||
);
|
||||
protected $defaultPermissions = [
|
||||
'dir' => '0755',
|
||||
'file' => '0644',
|
||||
'user' => null,
|
||||
'group' => null,
|
||||
];
|
||||
|
||||
protected $writablePermissions = [
|
||||
'file' => '0664',
|
||||
'dir' => '0775',
|
||||
];
|
||||
|
||||
public function __construct(Manager $fileManager, array $params = null)
|
||||
{
|
||||
$this->fileManager = $fileManager;
|
||||
if (isset($params)) {
|
||||
$this->params = $params;
|
||||
|
||||
if ($params) {
|
||||
foreach ($params as $paramName => $paramValue) {
|
||||
switch ($paramName) {
|
||||
case 'defaultPermissions':
|
||||
$this->defaultPermissions = array_merge($this->defaultPermissions, $paramValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,11 +92,6 @@ class Permission
|
||||
return $this->fileManager;
|
||||
}
|
||||
|
||||
protected function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default settings
|
||||
*
|
||||
@@ -105,14 +99,34 @@ class Permission
|
||||
*/
|
||||
public function getDefaultPermissions()
|
||||
{
|
||||
$params = $this->getParams();
|
||||
return $params['defaultPermissions'];
|
||||
return $this->defaultPermissions;
|
||||
}
|
||||
|
||||
|
||||
public function getPermissionRules()
|
||||
public function getWritableMap()
|
||||
{
|
||||
return $this->permissionRules;
|
||||
return $this->writableMap;
|
||||
}
|
||||
|
||||
public function getWritableList()
|
||||
{
|
||||
return array_keys($this->writableMap);
|
||||
}
|
||||
|
||||
public function getRequiredPermissions($path)
|
||||
{
|
||||
$permission = $this->getDefaultPermissions();
|
||||
|
||||
foreach ($this->getWritableMap() as $writablePath => $writableOptions) {
|
||||
if (!$writableOptions['recursive'] && $path == $writablePath) {
|
||||
return array_merge($permission, $this->writablePermissions);
|
||||
}
|
||||
|
||||
if ($writableOptions['recursive'] && substr($path, 0, strlen($writablePath)) == $writablePath) {
|
||||
return array_merge($permission, $this->writablePermissions);
|
||||
}
|
||||
}
|
||||
|
||||
return $permission;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,7 +143,7 @@ class Permission
|
||||
return false;
|
||||
}
|
||||
|
||||
$permission = $this->getDefaultPermissions();
|
||||
$permission = $this->getRequiredPermissions($path);
|
||||
|
||||
$result = $this->chmod($path, array($permission['file'], $permission['dir']), $recurse);
|
||||
if (!empty($permission['user'])) {
|
||||
@@ -342,8 +356,8 @@ class Permission
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function chgrpRecurse($path, $group) {
|
||||
|
||||
protected function chgrpRecurse($path, $group)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
@@ -461,60 +475,38 @@ class Permission
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function setMapPermission($mode = null)
|
||||
public function setMapPermission()
|
||||
{
|
||||
$this->permissionError = array();
|
||||
$this->permissionErrorRules = array();
|
||||
|
||||
$params = $this->getParams();
|
||||
|
||||
$permissionRules = $this->permissionRules;
|
||||
if (isset($mode)) {
|
||||
foreach ($permissionRules as &$value) {
|
||||
$value = $mode;
|
||||
}
|
||||
}
|
||||
|
||||
$result = true;
|
||||
foreach ($params['permissionMap'] as $type => $items) {
|
||||
|
||||
$permission = $permissionRules[$type];
|
||||
foreach ($this->getWritableMap() as $path => $options) {
|
||||
if (!file_exists($path)) continue;
|
||||
|
||||
foreach ($items as $item) {
|
||||
try {
|
||||
$this->chmod($path, $this->writablePermissions, $options['recursive']);
|
||||
} catch (\Throwable $e) {}
|
||||
|
||||
if (file_exists($item)) {
|
||||
/** check is writable */
|
||||
$res = is_writable($path);
|
||||
|
||||
try {
|
||||
$this->chmod($item, $permission, true);
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
$res = is_readable($item);
|
||||
|
||||
/** check is wtitable */
|
||||
if ($type == 'writable') {
|
||||
|
||||
$res &= is_writable($item);
|
||||
|
||||
if (is_dir($item)) {
|
||||
$name = uniqid();
|
||||
|
||||
try {
|
||||
$res &= $this->getFileManager()->putContents(array($item, $name), 'test');
|
||||
$res &= $this->getFileManager()->removeFile($name, $item);
|
||||
} catch (\Exception $e) {
|
||||
$res = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$res) {
|
||||
$result = false;
|
||||
$this->permissionError[] = $item;
|
||||
$this->permissionErrorRules[$item] = $permission;
|
||||
}
|
||||
if (is_dir($path)) {
|
||||
try {
|
||||
$name = uniqid();
|
||||
$res &= $this->getFileManager()->putContents([$path, $name], 'test');
|
||||
$res &= $this->getFileManager()->removeFile($name, $path);
|
||||
} catch (\Throwable $e) {
|
||||
$res = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$res) {
|
||||
$result = false;
|
||||
$this->permissionError[] = $path;
|
||||
$this->permissionErrorRules[$path] = $this->writablePermissions;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
@@ -607,4 +599,3 @@ class Permission
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -159,11 +159,12 @@ class SystemRequirements
|
||||
{
|
||||
return $this->getRequiredList('permissionRequirements', [
|
||||
'permissionMap.writable',
|
||||
'permissionMap.readable',
|
||||
], $additionalData);
|
||||
], $additionalData, [
|
||||
'permissionMap.writable' => $this->getFileManager()->getPermissionUtils()->getWritableList(),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getRequiredList($type, $checkList, array $additionalData = null)
|
||||
protected function getRequiredList($type, $checkList, array $additionalData = null, array $predefinedData = [])
|
||||
{
|
||||
$config = $this->getConfig();
|
||||
|
||||
@@ -172,7 +173,8 @@ class SystemRequirements
|
||||
foreach ($checkList as $itemName) {
|
||||
$methodName = 'check' . ucfirst($type);
|
||||
if (method_exists($this, $methodName)) {
|
||||
$result = $this->$methodName($itemName, $config->get($itemName), $additionalData);
|
||||
$itemValue = isset($predefinedData[$itemName]) ? $predefinedData[$itemName] : $config->get($itemName);
|
||||
$result = $this->$methodName($itemName, $itemValue, $additionalData);
|
||||
$list = array_merge($list, $result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,31 +29,9 @@
|
||||
|
||||
return [
|
||||
'defaultPermissions' => [
|
||||
'dir' => '0775',
|
||||
'file' => '0664',
|
||||
'user' => '',
|
||||
'group' => ''
|
||||
],
|
||||
'permissionMap' => [
|
||||
/** array('0664', '0775') */
|
||||
'writable' => [
|
||||
'data',
|
||||
'custom',
|
||||
'application/Espo/Modules',
|
||||
'client/modules'
|
||||
],
|
||||
/** array('0644', '0755') */
|
||||
'readable' => [
|
||||
'api',
|
||||
'application',
|
||||
'client',
|
||||
'vendor',
|
||||
'index.php',
|
||||
'cron.php',
|
||||
'rebuild.php',
|
||||
'clear_cache.php'
|
||||
],
|
||||
],
|
||||
'jobMaxPortion' => 15, /** Max number of jobs per one execution. */
|
||||
'jobPeriod' => 7800, /** Max execution time (in seconds) allocated for a sinle job. If exceeded then set to Failed.*/
|
||||
'jobPeriodForActiveProcess' => 36000, /** Max execution time (in seconds) allocated for a sinle job with active process. If exceeded then set to Failed.*/
|
||||
@@ -89,10 +67,8 @@ return [
|
||||
'crud',
|
||||
'logger',
|
||||
'isInstalled',
|
||||
'defaultPermissions',
|
||||
'systemUser',
|
||||
'permissionMap',
|
||||
'permissionRules',
|
||||
'defaultPermissions',
|
||||
'passwordSalt',
|
||||
'cryptKey',
|
||||
'apiSecretKeys',
|
||||
|
||||
@@ -45,8 +45,6 @@ class Installer
|
||||
|
||||
protected $isAuth = false;
|
||||
|
||||
protected $permissionMap;
|
||||
|
||||
protected $permissionError;
|
||||
|
||||
private $passwordHash;
|
||||
@@ -88,10 +86,6 @@ class Installer
|
||||
require_once('install/core/SystemHelper.php');
|
||||
$this->systemHelper = new SystemHelper();
|
||||
|
||||
$configPath = $this->getConfig()->getConfigPath();
|
||||
$this->permissionMap = $this->getConfig()->get('permissionMap');
|
||||
$this->permissionMap['writable'][] = $configPath;
|
||||
|
||||
$this->databaseHelper = new \Espo\Core\Utils\Database\Helper($this->getConfig());
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ class SystemHelper extends \Espo\Core\Utils\System
|
||||
|
||||
protected $combineOperator = '&&';
|
||||
|
||||
protected $writableMap;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->config = include('config.php');
|
||||
@@ -50,6 +52,9 @@ class SystemHelper extends \Espo\Core\Utils\System
|
||||
}
|
||||
|
||||
$this->apiPath = $this->config['apiPath'];
|
||||
|
||||
$permission = new \Espo\Core\Utils\File\Permission(new \Espo\Core\Utils\File\Manager());
|
||||
$this->writableMap = $permission->getWritableMap();
|
||||
}
|
||||
|
||||
protected function getMainConfig($optionName, $returns = null)
|
||||
@@ -124,7 +129,7 @@ class SystemHelper extends \Espo\Core\Utils\System
|
||||
return $cd.$sudoStr.'chown -R '.$owner.':'.$group.' '.$path;
|
||||
}
|
||||
|
||||
public function getChmodCommand($path, $permissions = array('755'), $isSudo = false, $isFile = null, $isCd = true)
|
||||
public function getChmodCommand($path, $permissions = ['755'], $isRecursive = true, $isSudo = false, $isFile = null)
|
||||
{
|
||||
$path = empty($path) ? '.' : $path;
|
||||
if (is_array($path)) {
|
||||
@@ -133,27 +138,32 @@ class SystemHelper extends \Espo\Core\Utils\System
|
||||
|
||||
$sudoStr = $isSudo ? 'sudo ' : '';
|
||||
|
||||
$cd = $isCd ? $this->getCd(true) : '';
|
||||
|
||||
if (is_string($permissions)) {
|
||||
$permissions = (array) $permissions;
|
||||
}
|
||||
|
||||
if (!isset($isFile) && count($permissions) == 1) {
|
||||
return $cd. $sudoStr . 'find '.$path.' -type d -exec ' . $sudoStr . 'chmod '.$permissions[0].' {} +';
|
||||
if ($isRecursive) {
|
||||
return $sudoStr . 'find '. $path .' -type d -exec ' . $sudoStr . 'chmod '. $permissions[0] .' {} +';
|
||||
}
|
||||
return $sudoStr . 'chmod '. $permissions[0] .' '. $path;
|
||||
}
|
||||
|
||||
$bufPerm = (count($permissions) == 1) ? array_fill(0, 2, $permissions[0]) : $permissions;
|
||||
|
||||
$commands = array();
|
||||
|
||||
if ($isCd) {
|
||||
$commands[] = $this->getCd();
|
||||
if ($isRecursive) {
|
||||
$commands[] = $sudoStr. 'find '.$path.' -type f -exec ' .$sudoStr.'chmod '.$bufPerm[0].' {} +';
|
||||
$commands[] = $sudoStr . 'find '.$path.' -type d -exec ' .$sudoStr. 'chmod '.$bufPerm[1].' {} +';
|
||||
} else {
|
||||
if (file_exists($path) && is_file($path)) {
|
||||
$commands[] = $sudoStr. 'chmod '. $bufPerm[0] .' '. $path;
|
||||
} else {
|
||||
$commands[] = $sudoStr. 'chmod '. $bufPerm[1] .' '. $path;
|
||||
}
|
||||
}
|
||||
|
||||
$commands[] = $sudoStr. 'find '.$path.' -type f -exec ' .$sudoStr.'chmod '.$bufPerm[0].' {} +';//.'chmod '.$bufPerm[0].' $(find '.$path.' -type f)';
|
||||
$commands[] = $sudoStr . 'find '.$path.' -type d -exec ' .$sudoStr. 'chmod '.$bufPerm[1].' {} +';//.'chmod '.$bufPerm[1].' $(find '.$path.' -type d)';
|
||||
|
||||
if (count($permissions) >= 2) {
|
||||
return implode(' ' . $this->combineOperator . ' ', $commands);
|
||||
}
|
||||
@@ -187,7 +197,7 @@ class SystemHelper extends \Espo\Core\Utils\System
|
||||
* @param bool $isFile
|
||||
* @return string
|
||||
*/
|
||||
public function getPermissionCommands($path, $permissions = array('644', '755'), $isSudo = false, $isFile = null, $changeOwner = true)
|
||||
public function getPermissionCommands($path, $permissions = ['644', '755'], $isSudo = false, $isFile = null, $changeOwner = true, $isCd = true)
|
||||
{
|
||||
if (is_string($path)) {
|
||||
$path = array_fill(0, 2, $path);
|
||||
@@ -195,7 +205,30 @@ class SystemHelper extends \Espo\Core\Utils\System
|
||||
list($chmodPath, $chownPath) = $path;
|
||||
|
||||
$commands = array();
|
||||
$commands[] = $this->getChmodCommand($chmodPath, $permissions, $isSudo, $isFile);
|
||||
|
||||
if ($isCd) {
|
||||
$commands[] = $this->getCd();
|
||||
}
|
||||
|
||||
$chmodPath = (array) $chmodPath;
|
||||
|
||||
$pathList = [];
|
||||
$recursivePathList = [];
|
||||
foreach ($chmodPath as $pathItem) {
|
||||
if (isset($this->writableMap[$pathItem]) && !$this->writableMap[$pathItem]['recursive']) {
|
||||
$pathList[] = $pathItem;
|
||||
continue;
|
||||
}
|
||||
$recursivePathList[] = $pathItem;
|
||||
}
|
||||
|
||||
if (!empty($pathList)) {
|
||||
$commands[] = $this->getChmodCommand($pathList, $permissions, false, $isSudo, $isFile);
|
||||
}
|
||||
|
||||
if (!empty($recursivePathList)) {
|
||||
$commands[] = $this->getChmodCommand($recursivePathList, $permissions, true, $isSudo, $isFile);
|
||||
}
|
||||
|
||||
if ($changeOwner) {
|
||||
$chown = $this->getChownCommand($chownPath, $isSudo, false);
|
||||
|
||||
@@ -50,7 +50,7 @@ if (!$installer->checkPermission()) {
|
||||
$changeOwner = false;
|
||||
}
|
||||
}
|
||||
$result['errorMsg'] = $langs['messages']['Permission denied to'] . ':<br><pre>/'.implode('<br>/', $urls).'</pre>';
|
||||
$result['errorMsg'] = $langs['messages']['Permission denied to'] . ':<br><pre>'.implode('<br>', $urls).'</pre>';
|
||||
$result['errorFixInstruction'] = str_replace( '"{C}"' , $instruction, $langs['messages']['permissionInstruction']) . "<br>" .
|
||||
str_replace( '{CSU}' , $instructionSU, $langs['messages']['operationNotPermitted']);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user