Merged in feature/HOR-4508 (pull request #6649)
HOR-4508 Approved-by: Julio Cesar Laura Avendaño <contact@julio-laura.com>
This commit is contained in:
@@ -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": {
|
||||
|
||||
36
config/customMimeTypes.php
Normal file
36
config/customMimeTypes.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This is a partial list of the known types, add the type you want to be recognized,
|
||||
* this affects the whole application globally.
|
||||
*
|
||||
* https://www.iana.org/assignments/media-types/media-types.xml
|
||||
*/
|
||||
return [
|
||||
'dat' => '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',
|
||||
];
|
||||
@@ -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 . "/*");
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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') ,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use ProcessMaker\Plugins\PluginRegistry;
|
||||
use ProcessMaker\Validation\ValidationUploadedFiles;
|
||||
|
||||
$filter = new InputFilter();
|
||||
$_POST = $filter->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'] : "";
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.";
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use ProcessMaker\Validation\ValidationUploadedFiles;
|
||||
|
||||
sleep(1);
|
||||
global $RBAC;
|
||||
if ($RBAC->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'}";
|
||||
}
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -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')));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use ProcessMaker\Core\System;
|
||||
use ProcessMaker\Validation\ValidationUploadedFiles;
|
||||
|
||||
if (! isset( $_REQUEST['action'] )) {
|
||||
$res['success'] = false;
|
||||
@@ -199,6 +200,9 @@ function newSkin ($baseSkin = 'classic')
|
||||
function importSkin ()
|
||||
{
|
||||
try {
|
||||
ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
|
||||
throw new Exception($validator->getMessage());
|
||||
});
|
||||
if (! isset( $_FILES['uploadedFile'] )) {
|
||||
throw (new Exception( G::LoadTranslation( 'ID_SKIN_FILE_REQUIRED' ) ));
|
||||
}
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
<?php
|
||||
namespace ProcessMaker\BusinessModel\Cases;
|
||||
|
||||
use ProcessMaker\Plugins\PluginRegistry;
|
||||
use AppDocument;
|
||||
use AppDocumentPeer;
|
||||
use Exception;
|
||||
use Criteria;
|
||||
use ResultSet;
|
||||
use G;
|
||||
use ObjectPermissionPeer;
|
||||
use StepPeer;
|
||||
use StepSupervisorPeer;
|
||||
use AppDelegation;
|
||||
use AppDelegationPeer;
|
||||
use Users;
|
||||
use Configurations;
|
||||
use Bootstrap;
|
||||
use WsBase;
|
||||
use ApplicationPeer;
|
||||
use ProcessMaker\BusinessModel\ProcessSupervisor;
|
||||
use ProcessMaker\BusinessModel\Cases AS BusinessModelCases;
|
||||
use Cases;
|
||||
use ProcessUserPeer;
|
||||
use AppDocument;
|
||||
use AppDocumentPeer;
|
||||
use AppFolder;
|
||||
use ApplicationPeer;
|
||||
use Bootstrap;
|
||||
use Cases;
|
||||
use Configurations;
|
||||
use Criteria;
|
||||
use Exception;
|
||||
use G;
|
||||
use ObjectPermissionPeer;
|
||||
use ProcessMaker\BusinessModel\Cases AS BusinessModelCases;
|
||||
use ProcessMaker\BusinessModel\ProcessSupervisor;
|
||||
use ProcessMaker\Plugins\PluginRegistry;
|
||||
use ProcessMaker\Validation\ValidationUploadedFiles;
|
||||
use ProcessUserPeer;
|
||||
use ResultSet;
|
||||
use StepPeer;
|
||||
use StepSupervisorPeer;
|
||||
use Users;
|
||||
use WsBase;
|
||||
|
||||
|
||||
class InputDocument
|
||||
@@ -936,6 +937,12 @@ class InputDocument
|
||||
*/
|
||||
public function uploadFileCase($files, $caseInstance, $aData, $userUid, $appUid, $delIndex)
|
||||
{
|
||||
ValidationUploadedFiles::getValidationUploadedFiles()->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);
|
||||
|
||||
|
||||
@@ -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'];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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' => ''
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<?php
|
||||
namespace ProcessMaker\Services\Api\Project;
|
||||
|
||||
use \ProcessMaker\Services\Api;
|
||||
use \Luracast\Restler\RestException;
|
||||
use Exception;
|
||||
use Luracast\Restler\RestException;
|
||||
use ProcessMaker\BusinessModel\FilesManager as FilesManagerBusinessModel;
|
||||
use ProcessMaker\Services\Api;
|
||||
use ProcessMaker\Validation\ExceptionRestApi;
|
||||
|
||||
/**
|
||||
* Project\ProjectUsers Api Controller
|
||||
@@ -57,11 +60,13 @@ class FilesManager extends Api
|
||||
$userUid = $this->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());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Validation;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ExceptionRestApi extends Exception
|
||||
{
|
||||
|
||||
}
|
||||
137
workflow/engine/src/ProcessMaker/Validation/Rule.php
Normal file
137
workflow/engine/src/ProcessMaker/Validation/Rule.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Validation;
|
||||
|
||||
/**
|
||||
* It contains a validation rule defined by the Closure function that must
|
||||
* return a boolean value, true if it has failed, and false if it has passed the
|
||||
* validation rule.
|
||||
*/
|
||||
class Rule
|
||||
{
|
||||
/**
|
||||
* Validation data defined by value and field.
|
||||
* @var object
|
||||
*/
|
||||
private $data = null;
|
||||
|
||||
/**
|
||||
* Validation rule.
|
||||
* @var Closure
|
||||
*/
|
||||
private $callback = null;
|
||||
|
||||
/**
|
||||
* Help to register when the rule is not met.
|
||||
* @var Closure
|
||||
*/
|
||||
private $callbackLog = null;
|
||||
|
||||
/**
|
||||
* Return message in case the rule is not met.
|
||||
* @var string
|
||||
*/
|
||||
private $message = "";
|
||||
|
||||
/**
|
||||
* Response status code.
|
||||
* @var int
|
||||
*/
|
||||
private $status = 0;
|
||||
|
||||
/**
|
||||
* Obtain validation data composed of field and value.
|
||||
* @return object
|
||||
*/
|
||||
function getData()
|
||||
{
|
||||
return $this->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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Validation;
|
||||
|
||||
use Bootstrap;
|
||||
use G;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use ProcessMaker\Core\System;
|
||||
use ProcessMaker\Services\OAuth2\Server;
|
||||
use Symfony\Component\HttpFoundation\File\File;
|
||||
|
||||
class ValidationUploadedFiles
|
||||
{
|
||||
/**
|
||||
* Single object instance to be used in the entire environment.
|
||||
*
|
||||
* @var object
|
||||
*/
|
||||
private static $validationUploadedFiles = null;
|
||||
|
||||
/**
|
||||
* List of evaluated items that have not passed the validation rules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $fails = [];
|
||||
|
||||
/**
|
||||
* Check if the loaded files comply with the validation rules, add here if you
|
||||
* want more validation rules.
|
||||
* Accept per argument an array or object that contains a "filename" and "path" values.
|
||||
* The rules are verified in the order in which they have been added.
|
||||
*
|
||||
* @param array|object $file
|
||||
* @return Validator
|
||||
*/
|
||||
public function runRules($file)
|
||||
{
|
||||
$validator = new Validator();
|
||||
|
||||
//rule: disable_php_upload_execution
|
||||
$validator->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;
|
||||
}
|
||||
}
|
||||
138
workflow/engine/src/ProcessMaker/Validation/Validator.php
Normal file
138
workflow/engine/src/ProcessMaker/Validation/Validator.php
Normal file
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace ProcessMaker\Validation;
|
||||
|
||||
use ProcessMaker\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Performs the validation process based on a list of validation rules.
|
||||
*/
|
||||
class Validator
|
||||
{
|
||||
/**
|
||||
* List of instances of the class 'Rule'.
|
||||
* @var array
|
||||
*/
|
||||
private $rules = [];
|
||||
|
||||
/**
|
||||
* Error message in the current validation rule.
|
||||
* @var string
|
||||
*/
|
||||
private $message = "";
|
||||
|
||||
/**
|
||||
* Response status code.
|
||||
* @var int
|
||||
*/
|
||||
private $status = 0;
|
||||
|
||||
/**
|
||||
* Current status of the validation, true if the validation has not been overcome.
|
||||
* @var boolean
|
||||
*/
|
||||
private $fails = false;
|
||||
|
||||
/**
|
||||
* Call after the validation process.
|
||||
* @var Closure
|
||||
*/
|
||||
private $callback = null;
|
||||
|
||||
/**
|
||||
* Get the message of the current validation if there was a failure.
|
||||
* @return string
|
||||
*/
|
||||
function getMessage()
|
||||
{
|
||||
return $this->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;
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user