diff --git a/composer.json b/composer.json index c3a78cb5f..25714d395 100644 --- a/composer.json +++ b/composer.json @@ -88,7 +88,8 @@ "thirdparty/pake/pakeFunction.php", "thirdparty/HTMLPurifier/HTMLPurifier.auto.php", "workflow/engine/classes/class.pmFunctions.php", - "workflow/engine/src/ProcessMaker/Util/helpers.php" + "workflow/engine/src/ProcessMaker/Util/helpers.php", + "framework/src/Maveriks/Extension/Restler/UploadFormat.php" ] }, "autoload-dev": { diff --git a/config/customMimeTypes.php b/config/customMimeTypes.php new file mode 100644 index 000000000..c78f3e0fa --- /dev/null +++ b/config/customMimeTypes.php @@ -0,0 +1,36 @@ + 'text/plain', + 'doc' => ['application/msword', 'text/html'], + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'exe' => ['application/x-msdownload', 'application/x-dosexec'], + 'gif' => 'image/gif', + 'htm' => 'text/html', + 'html' => 'text/html', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'mp3' => 'audio/mpeg', + 'mp4' => 'video/mp4', + 'ppt' => 'application/vnd.ms-office', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'pm' => 'text/plain', + 'pmt' => 'text/plain', + 'pmx' => 'application/xml', + 'po' => 'text/x-po', + 'pdf' => 'application/pdf', + 'png' => 'image/png', + 'php' => 'text/x-php', + 'rar' => 'application/x-rar', + 'txt' => 'text/plain', + 'wmv' => ['video/x-ms-asf', 'video/x-ms-wmv'], + 'xls' => ['application/vnd.ms-excel', 'text/plain'], + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'zip' => 'application/zip', +]; diff --git a/framework/src/Maveriks/WebApplication.php b/framework/src/Maveriks/WebApplication.php index fe9632e83..8b93a5a28 100644 --- a/framework/src/Maveriks/WebApplication.php +++ b/framework/src/Maveriks/WebApplication.php @@ -3,14 +3,16 @@ namespace Maveriks; use Bootstrap; +use G; +use Illuminate\Foundation\Http\Kernel; +use Luracast\Restler\Format\UploadFormat; +use Luracast\Restler\RestException; use Maveriks\Util; use ProcessMaker\Core\System; use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Services; use ProcessMaker\Services\Api; -use Luracast\Restler\RestException; -use Illuminate\Foundation\Http\Kernel; -use G; +use ProcessMaker\Validation\ValidationUploadedFiles; /** * Web application bootstrap @@ -252,8 +254,6 @@ class WebApplication */ protected function initRest($uri, $version, $multipart = false) { - require_once $this->rootDir . "/framework/src/Maveriks/Extension/Restler/UploadFormat.php"; - // $servicesDir contains directory where Services Classes are allocated $servicesDir = $this->workflowDir . 'engine' . DS . 'src' . DS . 'ProcessMaker' . DS . 'Services' . DS; // $apiDir - contains directory to scan classes and add them to Restler @@ -331,6 +331,17 @@ class WebApplication $this->rest->setOverridingFormats('JsonFormat', 'UploadFormat'); + UploadFormat::$customValidationFunction = function($target) { + $validator = ValidationUploadedFiles::getValidationUploadedFiles()->runRules([ + 'filename' => $target['name'], + 'path' => $target['tmp_name'] + ]); + if ($validator->fails()) { + throw new RestException($validator->getStatus(), $validator->getMessage()); + } + return true; + }; + // scan all api directory to find api classes $classesList = Util\Common::rglob($apiDir . "/*"); diff --git a/gulliver/system/class.g.php b/gulliver/system/class.g.php index 563fce0e5..5b63e720e 100644 --- a/gulliver/system/class.g.php +++ b/gulliver/system/class.g.php @@ -4,6 +4,7 @@ use ProcessMaker\Core\System; use ProcessMaker\AuditLog\AuditLog; use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Services\OAuth2\Server; +use ProcessMaker\Validation\ValidationUploadedFiles; class G { @@ -1183,7 +1184,7 @@ class G \Bootstrap::registerMonologPhpUploadExecution('phpExecution', 200, 'Php Execution', $filename); require_once($filename); } else { - $message = G::LoadTranslation('THE_PHP_FILES_EXECUTION_WAS_DISABLED'); + $message = G::LoadTranslation('ID_THE_PHP_FILES_EXECUTION_WAS_DISABLED'); \Bootstrap::registerMonologPhpUploadExecution('phpExecution', 550, $message, $filename); echo $message; } @@ -5488,6 +5489,16 @@ class G */ public static function verifyInputDocExtension($InpDocAllowedFiles, $fileName, $filesTmpName) { + $error = null; + ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) use(&$error) { + $error = new stdclass(); + $error->status = false; + $error->message = $validator->getMessage(); + }); + if (!is_null($error)) { + return $error; + } + // Initialize variables $res = new stdclass(); $res->status = false; @@ -5497,14 +5508,6 @@ class G $aux = pathinfo($fileName); $fileExtension = isset($aux['extension']) ? strtolower($aux['extension']) : ''; - if (\Bootstrap::getDisablePhpUploadExecution() === 1 && $fileExtension === 'php') { - $message = \G::LoadTranslation('THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED'); - \Bootstrap::registerMonologPhpUploadExecution('phpUpload', 550, $message, $fileName); - $res->status = false; - $res->message = $message; - return $res; - } - // If required extension is *.* don't validate if (in_array('*', $allowedTypes)) { $res->status = true; diff --git a/workflow/engine/content/translations/english/processmaker.en.po b/workflow/engine/content/translations/english/processmaker.en.po index dd02ad0eb..57caa88d5 100644 --- a/workflow/engine/content/translations/english/processmaker.en.po +++ b/workflow/engine/content/translations/english/processmaker.en.po @@ -24851,18 +24851,36 @@ msgstr "Error: The application {0} is not canceled." msgid "The default configuration was not defined" msgstr "The default configuration was not defined" +# TRANSLATION +# LABEL/ID_THE_MIMETYPE_EXTENSION_ERROR +#: LABEL/ID_THE_MIMETYPE_EXTENSION_ERROR +msgid "The mime type does not correspond to the permitted extension, please verify your file." +msgstr "The mime type does not correspond to the permitted extension, please verify your file." + # TRANSLATION # LABEL/ID_THE_NAME_CHANGE_MAY_CAUSE_DATA_LOSS #: LABEL/ID_THE_NAME_CHANGE_MAY_CAUSE_DATA_LOSS msgid "The change might cause data loss in the PM table. Do you want to continue?" msgstr "The change might cause data loss in the PM table. Do you want to continue?" +# TRANSLATION +# LABEL/ID_THE_PHP_FILES_EXECUTION_WAS_DISABLED +#: LABEL/ID_THE_PHP_FILES_EXECUTION_WAS_DISABLED +msgid "The PHP files execution was disabled please contact the system administrator." +msgstr "The PHP files execution was disabled please contact the system administrator." + # TRANSLATION # LABEL/ID_THE_REASON_REASSIGN_USER_EMPTY #: LABEL/ID_THE_REASON_REASSIGN_USER_EMPTY msgid "Please complete the reassign reason." msgstr "Please complete the reassign reason." +# TRANSLATION +# LABEL/ID_THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED +#: LABEL/ID_THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED +msgid "The upload of PHP files was disabled please contact the system administrator." +msgstr "The upload of PHP files was disabled please contact the system administrator." + # TRANSLATION # LABEL/ID_THE_USERNAME_EMAIL_IS_INCORRECT #: LABEL/ID_THE_USERNAME_EMAIL_IS_INCORRECT @@ -25187,6 +25205,12 @@ msgstr "Today" msgid "Tools" msgstr "Tools" +# TRANSLATION +# LABEL/ID_TOO_MANY_REQUESTS +#: LABEL/ID_TOO_MANY_REQUESTS +msgid "Too many requests" +msgstr "Too many requests" + # TRANSLATION # LABEL/ID_TOP_MARGIN #: LABEL/ID_TOP_MARGIN @@ -25913,6 +25937,18 @@ msgstr "The uploaded file exceeds the upload_max_filesize directive in php.ini" msgid "The file has not been attached because the extension is not allowed or because the content doesn't correspond." msgstr "The file has not been attached because the extension is not allowed or because the content doesn't correspond." +# TRANSLATION +# LABEL/ID_UPLOAD_INVALID_DOC_MAX_FILESIZE +#: LABEL/ID_UPLOAD_INVALID_DOC_MAX_FILESIZE +msgid "File size exceeds the allowable limit of {0}" +msgstr "File size exceeds the allowable limit of {0}" + +# TRANSLATION +# LABEL/ID_UPLOAD_INVALID_DOC_TYPE_FILE +#: LABEL/ID_UPLOAD_INVALID_DOC_TYPE_FILE +msgid "Invalid file format, please upload a file with one of the following formats {0}" +msgstr "Invalid file format, please upload a file with one of the following formats {0}" + # TRANSLATION # LABEL/ID_UPLOAD_ERR_NO_FILE #: LABEL/ID_UPLOAD_ERR_NO_FILE diff --git a/workflow/engine/controllers/adminProxy.php b/workflow/engine/controllers/adminProxy.php index 6c86f2c06..4809054bc 100644 --- a/workflow/engine/controllers/adminProxy.php +++ b/workflow/engine/controllers/adminProxy.php @@ -2,6 +2,7 @@ use ProcessMaker\Core\System; use ProcessMaker\Plugins\PluginRegistry; +use ProcessMaker\Validation\ValidationUploadedFiles; /** * adminProxy.php @@ -1025,7 +1026,14 @@ class adminProxy extends HttpProxyController */ public function uploadImage() { - //!dataSystem + ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) { + echo G::json_encode([ + 'success' => true, + 'failed' => true, + 'message' => $validator->getMessage() + ]); + exit(); + }); $filter = new InputFilter(); $_SERVER["REQUEST_URI"] = $filter->xssFilterHard($_SERVER["REQUEST_URI"]); diff --git a/workflow/engine/controllers/pmTablesProxy.php b/workflow/engine/controllers/pmTablesProxy.php index ed62a64a1..798271ccd 100644 --- a/workflow/engine/controllers/pmTablesProxy.php +++ b/workflow/engine/controllers/pmTablesProxy.php @@ -8,6 +8,8 @@ */ use ProcessMaker\Core\System; +use ProcessMaker\Validation\ExceptionRestApi; +use ProcessMaker\Validation\ValidationUploadedFiles; header("Content-type: text/html;charset=utf-8"); require_once 'classes/model/AdditionalTables.php'; @@ -723,6 +725,9 @@ class pmTablesProxy extends HttpProxyController } try { + ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) { + throw new ExceptionRestApi($validator->getMessage()); + }); $result = new stdClass(); $errors = ''; $fromConfirm = false; @@ -891,6 +896,11 @@ class pmTablesProxy extends HttpProxyController } $result->message = $msg; + } catch (ExceptionRestApi $e) { + $result = new stdClass(); + $result->success = false; + $result->errorType = 'notice'; + $result->message = $e->getMessage(); } catch (Exception $e) { $result = new stdClass(); $result->fromAdmin = $fromAdmin; diff --git a/workflow/engine/data/mysql/insert.sql b/workflow/engine/data/mysql/insert.sql index bbbb1f3ca..a7cd4f3e4 100644 --- a/workflow/engine/data/mysql/insert.sql +++ b/workflow/engine/data/mysql/insert.sql @@ -61035,8 +61035,11 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE ( 'LABEL','ID_THERE_PROBLEM_SENDING_EMAIL','en','There was a problem sending the email to','2016-04-08') , ( 'LABEL','ID_THE_APPLICATION_IS_NOT_CANCELED','en','Error: The application {0} is not canceled.','2016-06-15') , ( 'LABEL','ID_THE_DEFAULT_CONFIGURATION','en','The default configuration was not defined','2016-11-16') , +( 'LABEL','ID_THE_MIMETYPE_EXTENSION_ERROR','en','The mime type does not correspond to the permitted extension, please verify your file.','2018-10-2') , ( 'LABEL','ID_THE_NAME_CHANGE_MAY_CAUSE_DATA_LOSS','en','The change might cause data loss in the PM table. Do you want to continue?','2017-03-30') , +( 'LABEL','ID_THE_PHP_FILES_EXECUTION_WAS_DISABLED','en','The PHP files execution was disabled please contact the system administrator.','2018-04-20') , ( 'LABEL','ID_THE_REASON_REASSIGN_USER_EMPTY','en','Please complete the reassign reason.','2016-10-20') , +( 'LABEL','ID_THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED','en','The upload of PHP files was disabled please contact the system administrator.','2018-04-20') , ( 'LABEL','ID_THE_USERNAME_EMAIL_IS_INCORRECT','en','The username or email is incorrect','2018-01-18') , ( 'LABEL','ID_THIS_MONTH','en','This Month','2014-01-15') , ( 'LABEL','ID_THIS_QUARTER','en','This quarter','2014-01-15') , @@ -61093,6 +61096,7 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE ( 'LABEL','ID_TO','en','To','2014-01-15') , ( 'LABEL','ID_TODAY','en','Today','2014-01-15') , ( 'LABEL','ID_TOOLS','en','Tools','2014-01-15') , +( 'LABEL','ID_TOO_MANY_REQUESTS','en','Too many requests','2018-04-25') , ( 'LABEL','ID_TOP_MARGIN','en','Top Margin','2014-01-15') , ( 'LABEL','ID_TOTAL_CASES','en','Total Cases','2014-01-15') , ( 'LABEL','ID_TOTAL_CASES_REASSIGNED','en','Total Cases Reassigned','2014-01-15') , @@ -61216,6 +61220,8 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE ( 'LABEL','ID_UPLOAD_ERR_FORM_SIZE','en','The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form','2014-01-15') , ( 'LABEL','ID_UPLOAD_ERR_INI_SIZE','en','The uploaded file exceeds the upload_max_filesize directive in php.ini','2014-01-15') , ( 'LABEL','ID_UPLOAD_ERR_NOT_ALLOWED_EXTENSION','en','The file has not been attached because the extension is not allowed or because the content doesn''t correspond.','2014-10-21') , +( 'LABEL','ID_UPLOAD_INVALID_DOC_MAX_FILESIZE','en','File size exceeds the allowable limit of {0}','2018-11-06') , +( 'LABEL','ID_UPLOAD_INVALID_DOC_TYPE_FILE','en','Invalid file format, please upload a file with one of the following formats {0}','2018-11-05') , ( 'LABEL','ID_UPLOAD_ERR_NO_FILE','en','No file was uploaded','2014-01-15') , ( 'LABEL','ID_UPLOAD_ERR_NO_TMP_DIR','en','Missing a temporary folder','2014-01-15') , ( 'LABEL','ID_UPLOAD_ERR_PARTIAL','en','The uploaded file was only partially uploaded','2014-01-15') , diff --git a/workflow/engine/methods/appFolder/appFolderAjax.php b/workflow/engine/methods/appFolder/appFolderAjax.php index b75f038b5..33072d250 100644 --- a/workflow/engine/methods/appFolder/appFolderAjax.php +++ b/workflow/engine/methods/appFolder/appFolderAjax.php @@ -1,6 +1,7 @@ xssFilterHard($_POST); @@ -1445,6 +1446,15 @@ function checkTree($uidOriginFolder, $uidNewFolder) */ function uploadExternalDocument() { + ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) { + $response = [ + 'error' => $validator->getMessage(), + 'message' => $validator->getMessage(), + 'success' => false + ]; + print_r(G::json_encode($response)); + die(); + }); $response = []; $response['action'] = $_POST['action'] . " - " . $_POST['option']; $response['error'] = "error"; @@ -1531,18 +1541,6 @@ function uploadExternalDocument() //Read. Instance Document classes if (!empty($quequeUpload)) { - foreach ($quequeUpload as $key => $fileObj) { - $extension = pathinfo($fileObj['fileName'], PATHINFO_EXTENSION); - if (\Bootstrap::getDisablePhpUploadExecution() === 1 && $extension === 'php') { - $message = \G::LoadTranslation('THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED'); - \Bootstrap::registerMonologPhpUploadExecution('phpUpload', 550, $message, $fileObj['fileName']); - $response['error'] = $message; - $response['message'] = $message; - $response['success'] = false; - print_r(G::json_encode($response)); - exit(); - } - } $docUid = $_POST['docUid']; $appDocUid = isset($_POST['APP_DOC_UID']) ? $_POST['APP_DOC_UID'] : ""; $docVersion = isset($_POST['docVersion']) ? $_POST['docVersion'] : ""; diff --git a/workflow/engine/methods/enterprise/addonsStoreAction.php b/workflow/engine/methods/enterprise/addonsStoreAction.php index 9dc5133af..05ff152dd 100644 --- a/workflow/engine/methods/enterprise/addonsStoreAction.php +++ b/workflow/engine/methods/enterprise/addonsStoreAction.php @@ -2,6 +2,8 @@ use ProcessMaker\Core\System; use ProcessMaker\Plugins\PluginRegistry; +use ProcessMaker\Validation\ExceptionRestApi; +use ProcessMaker\Validation\ValidationUploadedFiles; function runBgProcessmaker($task, $log) { @@ -16,6 +18,9 @@ function runBgProcessmaker($task, $log) } try { + ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) { + throw new ExceptionRestApi($validator->getMessage()); + }); if (isset($_REQUEST["action"])) { $action = $_REQUEST["action"]; } else { @@ -312,6 +317,15 @@ try { $result["addons"] = array(); } G::outRes(G::json_encode($result)); +} catch (ExceptionRestApi $e) { + $token = strtotime("now"); + PMException::registerErrorLog($e, $token); + G::outRes( + G::json_encode(array( + "success" => false, + "errors" => $e->getMessage() + )) + ); } catch (Exception $e) { $token = strtotime("now"); PMException::registerErrorLog($e, $token); diff --git a/workflow/engine/methods/enterprise/pluginsImportFile.php b/workflow/engine/methods/enterprise/pluginsImportFile.php index 490d3f204..64939795f 100644 --- a/workflow/engine/methods/enterprise/pluginsImportFile.php +++ b/workflow/engine/methods/enterprise/pluginsImportFile.php @@ -27,6 +27,7 @@ global $RBAC; use ProcessMaker\Plugins\PluginRegistry; +use ProcessMaker\Validation\ValidationUploadedFiles; $RBAC->requirePermissions("PM_SETUP_ADVANCE"); require_once PATH_CORE . 'methods' . PATH_SEP . 'enterprise' . PATH_SEP . 'enterprise.php'; @@ -35,6 +36,9 @@ $response = array(); $status = 1; try { + ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) { + throw new Exception($validator->getMessage()); + }); if (!isset($_FILES["form"]["error"]["PLUGIN_FILENAME"]) || $_FILES["form"]["error"]["PLUGIN_FILENAME"] == 1) { $str = "There was an error uploading the file, probably the file size if greater than upload_max_filesize parameter in php.ini, please check this parameter and try again."; diff --git a/workflow/engine/methods/processes/processes_Import_Ajax.php b/workflow/engine/methods/processes/processes_Import_Ajax.php index 870db04eb..0f724bc58 100644 --- a/workflow/engine/methods/processes/processes_Import_Ajax.php +++ b/workflow/engine/methods/processes/processes_Import_Ajax.php @@ -23,6 +23,16 @@ */ use \ProcessMaker\Importer\XmlImporter; +use ProcessMaker\Validation\ValidationUploadedFiles; + +ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) { + echo G::json_encode([ + 'status' => 'ERROR', + 'success' => true, + 'catchMessage' => $validator->getMessage() + ]); + exit(); +}); ini_set("max_execution_time", 0); $affectedGroups = array(); diff --git a/workflow/engine/methods/processes/processes_doUpload.php b/workflow/engine/methods/processes/processes_doUpload.php index 07cdf06e4..db0077ef9 100644 --- a/workflow/engine/methods/processes/processes_doUpload.php +++ b/workflow/engine/methods/processes/processes_doUpload.php @@ -1,5 +1,7 @@ userCanAccess('PM_FACTORY') == 1) { @@ -25,26 +27,23 @@ if ($RBAC->userCanAccess('PM_FACTORY') == 1) { } } - $fileName = $_FILES['form']['name']; - $canUploadPhpFile = true; - $extension = pathinfo($fileName, PATHINFO_EXTENSION); - if (\Bootstrap::getDisablePhpUploadExecution() === 1 && $extension === 'php') { - $message = \G::LoadTranslation('THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED'); - \Bootstrap::registerMonologPhpUploadExecution('phpUpload', 550, $message, $fileName); - $canUploadPhpFile = false; - } + ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) { + $response = [ + 'result' => 0, + 'msg' => $validator->getMessage() + ]; + print_r(G::json_encode($response)); + die(); + }); - if ($_FILES['form']['error'] == "0" && $canUploadPhpFile) { + $fileName = $_FILES['form']['name']; + if ($_FILES['form']['error'] == "0") { G::uploadFile($_FILES['form']['tmp_name'], $sDirectory, $fileName); $msg = "Uploaded (" . (round((filesize($sDirectory . $fileName) / 1024) * 10) / 10) . " kb)"; $result = 1; } else { $msg = "Failed"; - if ($canUploadPhpFile === false) { - $msg = $message; - } $result = 0; } - echo "{'result': $result, 'msg':'$msg'}"; } diff --git a/workflow/engine/methods/setup/languages_Import.php b/workflow/engine/methods/setup/languages_Import.php index ce808315b..1a1f3fa55 100644 --- a/workflow/engine/methods/setup/languages_Import.php +++ b/workflow/engine/methods/setup/languages_Import.php @@ -2,6 +2,8 @@ require_once "classes/model/Language.php"; +use ProcessMaker\Validation\ValidationUploadedFiles; + global $RBAC; $access = $RBAC->userCanAccess('PM_SETUP_ADVANCE'); @@ -24,6 +26,9 @@ if ($access != 1) { $result = new stdClass(); try { + ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) { + throw new Exception($validator->getMessage()); + }); //if the xmlform path is writeable if (!is_writable(PATH_XMLFORM)) { throw new Exception(G::LoadTranslation('IMPORT_LANGUAGE_ERR_NO_WRITABLE')); diff --git a/workflow/engine/methods/setup/pluginsImportFile.php b/workflow/engine/methods/setup/pluginsImportFile.php index 3cb70b2d0..8ddce45fa 100644 --- a/workflow/engine/methods/setup/pluginsImportFile.php +++ b/workflow/engine/methods/setup/pluginsImportFile.php @@ -26,11 +26,15 @@ use ProcessMaker\Core\System; use ProcessMaker\Plugins\PluginRegistry; +use ProcessMaker\Validation\ValidationUploadedFiles; global $RBAC; $RBAC->requirePermissions('PM_SETUP_ADVANCE'); try { + ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) { + throw new Exception($validator->getMessage()); + }); //load the variables if (!isset($_FILES['form']['error']['PLUGIN_FILENAME']) || $_FILES['form']['error']['PLUGIN_FILENAME'] == 1) { throw (new Exception(G::loadTranslation('ID_ERROR_UPLOADING_PLUGIN_FILENAME'))); diff --git a/workflow/engine/methods/setup/skin_Ajax.php b/workflow/engine/methods/setup/skin_Ajax.php index d939fac45..ad47b31bb 100644 --- a/workflow/engine/methods/setup/skin_Ajax.php +++ b/workflow/engine/methods/setup/skin_Ajax.php @@ -1,6 +1,7 @@ dispach(function($validator) { + throw new Exception($validator->getMessage()); + }); if (! isset( $_FILES['uploadedFile'] )) { throw (new Exception( G::LoadTranslation( 'ID_SKIN_FILE_REQUIRED' ) )); } diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Cases/InputDocument.php b/workflow/engine/src/ProcessMaker/BusinessModel/Cases/InputDocument.php index f8e177c1e..1b73cb143 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Cases/InputDocument.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Cases/InputDocument.php @@ -1,28 +1,29 @@ dispach(function($validator) { + G::SendMessageText($validator->getMessage(), "ERROR"); + $url = explode("sys" . config("system.workspace"), $_SERVER['HTTP_REFERER']); + G::header("location: " . "/sys" . config("system.workspace") . $url[1]); + die(); + }); $arrayField = array(); $arrayFileName = array(); $arrayFileTmpName = array(); @@ -1034,16 +1041,6 @@ class InputDocument $aFields = array("APP_UID" => $appUid, "DEL_INDEX" => $delIndex, "USR_UID" => $userUid, "DOC_UID" => -1, "APP_DOC_TYPE" => "ATTACHED", "APP_DOC_CREATE_DATE" => date("Y-m-d H:i:s"), "APP_DOC_COMMENT" => "", "APP_DOC_TITLE" => "", "APP_DOC_FILENAME" => $arrayFileName[$i], "APP_DOC_FIELDNAME" => $fieldName); } - $sExtension = pathinfo($aFields["APP_DOC_FILENAME"]); - if (Bootstrap::getDisablePhpUploadExecution() === 1 && $sExtension["extension"] === 'php') { - $message = G::LoadTranslation('THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED'); - Bootstrap::registerMonologPhpUploadExecution('phpUpload', 550, $message, 'processmaker.log'); - G::SendMessageText($message, "ERROR"); - $backUrlObj = explode("sys" . config("system.workspace"), $_SERVER['HTTP_REFERER']); - G::header("location: " . "/sys" . config("system.workspace") . $backUrlObj[1]); - die(); - } - $oAppDocument = new AppDocument(); $oAppDocument->create($aFields); diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php b/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php index 2a91bcde0..c1260a5dd 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php @@ -196,11 +196,6 @@ class FilesManager if ($extention == '.exe') { throw new \Exception(\G::LoadTranslation('ID_FILE_UPLOAD_INCORRECT_EXTENSION')); } - if (\Bootstrap::getDisablePhpUploadExecution() === 1 && $extention === '.php' && !$isImport) { - $message = \G::LoadTranslation('THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED'); - \Bootstrap::registerMonologPhpUploadExecution('phpUpload', 550, $message, $aData['prf_filename']); - throw new \Exception($message); - } break; default: $sDirectory = PATH_DATA_MAILTEMPLATES . $sProcessUID . PATH_SEP . $sSubDirectory . $aData['prf_filename']; diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Light.php b/workflow/engine/src/ProcessMaker/BusinessModel/Light.php index eaeba18ec..8ee6a3b2d 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Light.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Light.php @@ -32,6 +32,8 @@ use ProcessMaker\Core\RoutingScreen; use ProcessMaker\Core\System; use ProcessMaker\Services\Api\Project\Activity\Step as ActivityStep; use ProcessMaker\Util\DateTime; +use ProcessMaker\Validation\ExceptionRestApi; +use ProcessMaker\Validation\Validator; use ProcessPeer; use Propel; use RBAC; @@ -995,16 +997,6 @@ class Light $confEnvSetting = $config->getFormats(); $user = new Users(); foreach ($requestData as $k => $file) { - $ext = pathinfo($file['name'], PATHINFO_EXTENSION); - if (Bootstrap::getDisablePhpUploadExecution() === 1 && $ext === 'php') { - $message = G::LoadTranslation('THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED'); - Bootstrap::registerMonologPhpUploadExecution('phpUpload', 550, $message, $file['name']); - $response[$k]['error'] = array( - "code" => "400", - "message" => $message - ); - continue; - } $cases = new Cases(); $delIndex = $cases->getCurrentDelegation($appUid, $userUid); $docUid = !empty($file['docUid']) ? $file['docUid'] : -1; @@ -1071,7 +1063,7 @@ class Light * * @throws Exception */ - public function documentUploadFiles($userUid, $app_uid, $app_doc_uid, $request_data) + public function documentUploadFiles($userUid, $app_uid, $app_doc_uid) { $response = array("status" => "fail"); if (isset($_FILES["form"]["name"]) && count($_FILES["form"]["name"]) > 0) { @@ -1107,6 +1099,58 @@ class Light } } if (count($arrayField) > 0) { + //rule validation + $appDocument = new AppDocument(); + $appDocument->load($app_doc_uid); + $inputDocument = new InputDocument(); + $ifInputExist = $inputDocument->InputExists($appDocument->getDocUid()); + if ($ifInputExist) { + $inputProperties = $inputDocument->load($appDocument->getDocUid()); + $inpDocTypeFile = $inputProperties['INP_DOC_TYPE_FILE']; + $inpDocMaxFilesize = (int) $inputProperties["INP_DOC_MAX_FILESIZE"]; + $inpDocMaxFilesizeUnit = $inputProperties["INP_DOC_MAX_FILESIZE_UNIT"]; + } + + for ($i = 0; $ifInputExist && $i < count($arrayField); $i++) { + $file = [ + 'filename' => $arrayFileName[$i], + 'path' => $arrayFileTmpName[$i] + ]; + $validator = new Validator(); + //rule: extension + $validator->addRule() + ->validate($file, function($file) use($inpDocTypeFile) { + $result = G::verifyInputDocExtension($inpDocTypeFile, $file->filename, $file->path); + return $result->status === false; + }) + ->status(415) + ->message(G::LoadTranslation('ID_UPLOAD_INVALID_DOC_TYPE_FILE', [$inpDocTypeFile])) + ->log(function($rule) { + Bootstrap::registerMonologPhpUploadExecution('phpUpload', 250, $rule->getMessage(), $rule->getData()->filename); + }); + + //rule: maximum file size + $validator->addRule() + ->validate($file, function($file) use($inpDocMaxFilesize, $inpDocMaxFilesizeUnit) { + if ($inpDocMaxFilesize > 0) { + $totalMaxFileSize = $inpDocMaxFilesize * ($inpDocMaxFilesizeUnit == "MB" ? 1024 * 1024 : 1024); + $fileSize = filesize($file->path); + if ($fileSize > $totalMaxFileSize) { + return true; + } + } + return false; + }) + ->status(413) + ->message(G::LoadTranslation("ID_UPLOAD_INVALID_DOC_MAX_FILESIZE", [$inpDocMaxFilesize . $inpDocMaxFilesizeUnit])) + ->log(function($rule) { + Bootstrap::registerMonologPhpUploadExecution('phpUpload', 250, $rule->getMessage(), $rule->getData()->filename); + }); + $validator->validate(); + if ($validator->fails()) { + throw new ExceptionRestApi($validator->getMessage(), $validator->getStatus()); + } + } for ($i = 0; $i <= count($arrayField) - 1; $i++) { if ($arrayFileError[$i] == 0) { $indocUid = null; diff --git a/workflow/engine/src/ProcessMaker/Core/System.php b/workflow/engine/src/ProcessMaker/Core/System.php index fb760c8fc..85e449cb4 100644 --- a/workflow/engine/src/ProcessMaker/Core/System.php +++ b/workflow/engine/src/ProcessMaker/Core/System.php @@ -66,7 +66,10 @@ class System 'logging_level' => 'INFO', 'smtp_timeout' => 20, 'google_map_api_key' => '', - 'google_map_signature' => '' + 'google_map_signature' => '', + 'logging_level' => 'INFO', + 'upload_attempts_limit_per_user' => '60,1', + 'files_white_list' => '' ); /** diff --git a/workflow/engine/src/ProcessMaker/Services/Api/Light.php b/workflow/engine/src/ProcessMaker/Services/Api/Light.php index 11f126b25..9f4233246 100644 --- a/workflow/engine/src/ProcessMaker/Services/Api/Light.php +++ b/workflow/engine/src/ProcessMaker/Services/Api/Light.php @@ -23,6 +23,7 @@ use ProcessMaker\Project\Adapter; use ProcessMaker\Services\Api; use ProcessMaker\Services\Api\Project\Activity\Step; use ProcessMaker\Util\DateTime; +use ProcessMaker\Validation\ExceptionRestApi; use RBAC; use stdclass; use StepPeer; @@ -1466,10 +1467,11 @@ class Light extends Api $userUid = $this->getUserId(); $oMobile = new BusinessModelLight(); $filesUids = $oMobile->postUidUploadFiles($userUid, $app_uid, $request_data); + } catch (ExceptionRestApi $e) { + throw new RestException($e->getCode(), $e->getMessage()); } catch (Exception $e) { - throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); + throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()); } - return $filesUids; } @@ -1500,11 +1502,12 @@ class Light extends Api try { $userUid = $this->getUserId(); $oMobile = new BusinessModelLight(); - $response = $oMobile->documentUploadFiles($userUid, $app_uid, $app_doc_uid, $request_data); + $response = $oMobile->documentUploadFiles($userUid, $app_uid, $app_doc_uid); + } catch (ExceptionRestApi $e) { + throw new RestException($e->getCode(), $e->getMessage()); } catch (Exception $e) { throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); } - return $response; } diff --git a/workflow/engine/src/ProcessMaker/Services/Api/Project/FilesManager.php b/workflow/engine/src/ProcessMaker/Services/Api/Project/FilesManager.php index 043ec9326..55c22fb9d 100644 --- a/workflow/engine/src/ProcessMaker/Services/Api/Project/FilesManager.php +++ b/workflow/engine/src/ProcessMaker/Services/Api/Project/FilesManager.php @@ -1,8 +1,11 @@ getUserId(); $request_data = (array)($request_data); $request_data = array_merge(array('prf_content' => $prf_content ), $request_data); - $filesManager = new \ProcessMaker\BusinessModel\FilesManager(); + $filesManager = new FilesManagerBusinessModel(); $arrayData = $filesManager->addProcessFilesManager($prj_uid, $userUid, $request_data); //Response $response = $arrayData; - } catch (\Exception $e) { + } catch (ExceptionRestApi $e) { + throw new RestException($e->getCode(), $e->getMessage()); + } catch (Exception $e) { //response throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()); } @@ -85,11 +90,13 @@ class FilesManager extends Api public function doPostProcessFilesManagerUpload($prj_uid, $prf_uid) { try { - $filesManager = new \ProcessMaker\BusinessModel\FilesManager(); + $filesManager = new FilesManagerBusinessModel(); $sData = $filesManager->uploadProcessFilesManager($prj_uid, $prf_uid); //Response $response = $sData; - } catch (\Exception $e) { + } catch (ExceptionRestApi $e) { + throw new RestException($e->getCode(), $e->getMessage()); + } catch (Exception $e) { //response throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()); } diff --git a/workflow/engine/src/ProcessMaker/Validation/ExceptionRestApi.php b/workflow/engine/src/ProcessMaker/Validation/ExceptionRestApi.php new file mode 100644 index 000000000..e781a81c6 --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Validation/ExceptionRestApi.php @@ -0,0 +1,10 @@ +data; + } + + /** + * Get the Closure function. + * @return Closure + */ + function getCallback() + { + return $this->callback; + } + + /** + * Gets the Closure function that applies the validation rule. + * @return Closure + */ + function getCallbackLog() + { + return $this->callbackLog; + } + + /** + * Get the message to be saved in the log if the rule is not fulfilled. + * @return string + */ + function getMessage() + { + return $this->message; + } + + /** + * Get status code. + * @return int + */ + function getStatus() + { + return $this->status; + } + + /** + * Registers the data and the Closure function that contains the validation + * rule. + * @param array $data + * @param Closure $callback + * @return Rule + */ + public function validate($data, $callback = null) + { + $this->data = (object) $data; + if (is_callable($callback)) { + $this->callback = $callback; + } + return $this; + } + + /** + * Registers the customized message in case the validation rule is not met. + * @param string $message + * @return Rule + */ + public function message($message = "") + { + $this->message = $message; + return $this; + } + + /** + * Set status code. + * @param int $status + * @return $this + */ + function status($status = 0) + { + $this->status = $status; + return $this; + } + + /** + * Registers the Closure function in case the validation rule is not met. + * @param Closure $callback + * @return Rule + */ + public function log($callback = null) + { + if (is_callable($callback)) { + $this->callbackLog = $callback; + } + return $this; + } +} diff --git a/workflow/engine/src/ProcessMaker/Validation/ValidationUploadedFiles.php b/workflow/engine/src/ProcessMaker/Validation/ValidationUploadedFiles.php new file mode 100644 index 000000000..42b11989b --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Validation/ValidationUploadedFiles.php @@ -0,0 +1,241 @@ +addRule() + ->validate($file, function($file) { + $filesystem = new Filesystem(); + $extension = $filesystem->extension($file->filename); + + return Bootstrap::getDisablePhpUploadExecution() === 1 && $extension === 'php'; + }) + ->status(550) + ->message(G::LoadTranslation('ID_THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED')) + ->log(function($rule) { + /** + * Levels supported by MonologProvider is: + * 100 "DEBUG" + * 200 "INFO" + * 250 "NOTICE" + * 300 "WARNING" + * 400 "ERROR" + * 500 "CRITICAL" + * 550 "ALERT" + * 600 "EMERGENCY" + */ + Bootstrap::registerMonologPhpUploadExecution('phpUpload', 550, $rule->getMessage(), $rule->getData()->filename); + }); + + //rule: upload_attempts_limit_per_user + $validator->addRule() + ->validate($file, function($file) { + $systemConfiguration = System::getSystemConfiguration('', '', config("system.workspace")); + $filesWhiteList = explode(',', $systemConfiguration['upload_attempts_limit_per_user']); + $userId = Server::getUserId(); + $key = config("system.workspace") . '/' . $userId; + $attemps = (int) trim($filesWhiteList[0]); + $minutes = (int) trim($filesWhiteList[1]); + $pastAttemps = Cache::remember($key, $minutes, function() { + return 1; + }); + //We only increase when the file path exists, useful when pre-validation is done. + if (isset($file->path)) { + Cache::increment($key, 1); + } + if ($pastAttemps <= $attemps) { + return false; + } + return true; + }) + ->status(429) + ->message(G::LoadTranslation('ID_TOO_MANY_REQUESTS')) + ->log(function($rule) { + /** + * Levels supported by MonologProvider is: + * 100 "DEBUG" + * 200 "INFO" + * 250 "NOTICE" + * 300 "WARNING" + * 400 "ERROR" + * 500 "CRITICAL" + * 550 "ALERT" + * 600 "EMERGENCY" + */ + Bootstrap::registerMonologPhpUploadExecution('phpUpload', 250, $rule->getMessage(), $rule->getData()->filename); + }); + + //rule: mimeType + $validator->addRule() + ->validate($file, function($file) { + $path = isset($file->path) ? $file->path : ""; + $filesystem = new Filesystem(); + if (!$filesystem->exists($path)) { + return false; + } + + $extension = $filesystem->extension($file->filename); + $mimeType = $filesystem->mimeType($path); + + $file = new File($path); + $guessExtension = $file->guessExtension(); + $mimeTypeFile = $file->getMimeType(); + + //mimeType known + if ($extension === $guessExtension && $mimeType === $mimeTypeFile) { + return false; + } + //mimeType custom + $customMimeTypes = config("customMimeTypes"); + $customMimeType = isset($customMimeTypes[$extension]) ? $customMimeTypes[$extension] : null; + if (is_string($customMimeType)) { + if ($customMimeType === $mimeType) { + return false; + } + } + if (is_array($customMimeType)) { + foreach ($customMimeType as $value) { + if ($value === $mimeType) { + return false; + } + } + } + //files_white_list + $systemConfiguration = System::getSystemConfiguration('', '', config("system.workspace")); + $filesWhiteList = explode(',', $systemConfiguration['files_white_list']); + if (in_array($extension, $filesWhiteList)) { + return false; + } + return true; + }) + ->status(415) + ->message(G::LoadTranslation('ID_THE_MIMETYPE_EXTENSION_ERROR')) + ->log(function($rule) { + /** + * Levels supported by MonologProvider is: + * 100 "DEBUG" + * 200 "INFO" + * 250 "NOTICE" + * 300 "WARNING" + * 400 "ERROR" + * 500 "CRITICAL" + * 550 "ALERT" + * 600 "EMERGENCY" + */ + Bootstrap::registerMonologPhpUploadExecution('phpUpload', 250, $rule->getMessage(), $rule->getData()->filename); + }); + + return $validator->validate(); + } + + /** + * File upload validation. + * + * @return $this + */ + public function runRulesToAllUploadedFiles() + { + $files = $_FILES; + if (!is_array($files)) { + return; + } + $this->fails = []; + foreach ($files as $file) { + $data = (object) $file; + if (!is_array($data->name) || !is_array($data->tmp_name)) { + $data->name = [$data->name]; + $data->tmp_name = [$data->tmp_name]; + } + foreach ($data->name as $key => $value) { + if (empty($value)) { + continue; + } + if (is_array($value)) { + foreach ($value as $rowKey => $rowValue) { + foreach ($rowValue as $cellKey => $cellValue) { + if (empty($cellValue)) { + continue; + } + $validator = $this->runRules(['filename' => $cellValue, 'path' => $data->tmp_name[$key][$rowKey][$cellKey]]); + if ($validator->fails()) { + $this->fails[] = $validator; + } + } + } + continue; + } + $validator = $this->runRules(['filename' => $value, 'path' => $data->tmp_name[$key]]); + if ($validator->fails()) { + $this->fails[] = $validator; + } + } + } + return $this; + } + + /** + * Get the first error and call the argument function. + * + * @param function $callback + * @return $this + */ + public function dispach($callback) + { + if (!empty($this->fails[0])) { + if (!empty($callback) && is_callable($callback)) { + $callback($this->fails[0], $this->fails); + } + } + return $this; + } + + /** + * It obtains a single object to be used as a record of the whole environment. + * + * @return object + */ + public static function getValidationUploadedFiles() + { + if (self::$validationUploadedFiles === null) { + self::$validationUploadedFiles = new ValidationUploadedFiles(); + } + return self::$validationUploadedFiles; + } +} diff --git a/workflow/engine/src/ProcessMaker/Validation/Validator.php b/workflow/engine/src/ProcessMaker/Validation/Validator.php new file mode 100644 index 000000000..0fc1fe428 --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Validation/Validator.php @@ -0,0 +1,138 @@ +message; + } + + /** + * Get status code. + * @return int + */ + function getStatus() + { + return $this->status; + } + + /** + * Get the Closure function. + * @return Closure + */ + function getCallback() + { + return $this->callback; + } + + /** + * Add a validation rule. + * The rules are verified in the order in which they have been added. + * + * @param Rule $rule + * @return Rule + */ + public function addRule($rule = null) + { + if (!$rule instanceof Rule) { + $rule = new Rule(); + } + $this->rules[] = $rule; + return $rule; + } + + /** + * Process all added validation rules. + * @return Validator + */ + public function validate() + { + $this->message = ""; + $this->status = 0; + $this->fails = false; + foreach ($this->rules as $rule) { + $callback = $rule->getCallback(); + if (is_callable($callback)) { + if ($callback($rule->getData())) { + $this->message = $rule->getMessage(); + $this->status = $rule->getStatus(); + $this->fails = true; + $getCallbackLog = $rule->getCallbackLog(); + if (is_callable($getCallbackLog)) { + $getCallbackLog($rule); + } + break; + } + } + } + $callbackAfter = $this->getCallback(); + if (is_callable($callbackAfter)) { + $callbackAfter($this); + } + return $this; + } + + /** + * Get the current status of the validation, the value is true if there was a + * failure and false if all the validation rules have been passed. + * @return boolean + */ + public function fails() + { + return $this->fails; + } + + /** + * The Closure function is called when the validation process is finished. + * @param Closure $callback + * @return Validator + */ + public function after($callback) + { + if (is_callable($callback)) { + $this->callback = $callback; + } + return $this; + } +} diff --git a/workflow/engine/templates/admin/pmLogo.js b/workflow/engine/templates/admin/pmLogo.js index 1993cdf44..c4327afd1 100644 --- a/workflow/engine/templates/admin/pmLogo.js +++ b/workflow/engine/templates/admin/pmLogo.js @@ -283,7 +283,10 @@ Ext.onReady(function () { } else { var messageError = ""; - if (obj.failed == "1") { + if (obj.failed === true) { + messageError = obj.message; + } + else if (obj.failed == "1") { //| 1-> Fail in the type of the image messageError = _('ID_ERROR_UPLOADING_IMAGE_TYPE'); } diff --git a/workflow/public_html/sysGeneric.php b/workflow/public_html/sysGeneric.php index 773910f0e..ae4928652 100644 --- a/workflow/public_html/sysGeneric.php +++ b/workflow/public_html/sysGeneric.php @@ -6,6 +6,7 @@ use ProcessMaker\Core\AppEvent; use ProcessMaker\ChangeLog\ChangeLog; /*----------------------------------********---------------------------------*/ use ProcessMaker\Plugins\PluginRegistry; +use ProcessMaker\Validation\ValidationUploadedFiles; /** * bootstrap - ProcessMaker Bootstrap @@ -818,7 +819,7 @@ if (substr(SYS_COLLECTION, 0, 8) === 'gulliver') { $isWebEntry = \ProcessMaker\BusinessModel\WebEntry::isWebEntry(SYS_COLLECTION, $phpFile); if (\Bootstrap::getDisablePhpUploadExecution() === 1 && !$isWebEntry) { - $message = \G::LoadTranslation('THE_PHP_FILES_EXECUTION_WAS_DISABLED'); + $message = \G::LoadTranslation('ID_THE_PHP_FILES_EXECUTION_WAS_DISABLED'); \Bootstrap::registerMonologPhpUploadExecution('phpExecution', 550, $message, $phpFile); echo $message; die(); @@ -1085,6 +1086,8 @@ if (!defined('EXECUTE_BY_CRON')) { $oPluginRegistry->init(); if ($isControllerCall) { //Instance the Controller object and call the request method + ValidationUploadedFiles::getValidationUploadedFiles() + ->runRulesToAllUploadedFiles(); $controller = new $controllerClass(); $controller->setHttpRequestData($_REQUEST);//NewRelic Snippet - By JHL transactionLog($controllerAction); @@ -1105,6 +1108,8 @@ if (!defined('EXECUTE_BY_CRON')) { ->setLanguage(SYS_LANG) ->getUsrIdByUsrUid(empty($_SESSION['USER_LOGGED']) ? '' : $_SESSION['USER_LOGGED']); /*----------------------------------********---------------------------------*/ + ValidationUploadedFiles::getValidationUploadedFiles() + ->runRulesToAllUploadedFiles(); require_once $phpFile; }