This commit is contained in:
Roly Rudy Gutierrez Pinto
2018-08-28 09:34:11 -04:00
committed by Paula Quispe
parent 88b61567e2
commit d263c5a7ca
27 changed files with 658 additions and 97 deletions

View File

@@ -87,7 +87,8 @@
"thirdparty/pake/pakeFunction.php", "thirdparty/pake/pakeFunction.php",
"thirdparty/HTMLPurifier/HTMLPurifier.auto.php", "thirdparty/HTMLPurifier/HTMLPurifier.auto.php",
"workflow/engine/classes/class.pmFunctions.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": { "autoload-dev": {

View File

@@ -3,14 +3,16 @@
namespace Maveriks; namespace Maveriks;
use Bootstrap; use Bootstrap;
use G;
use Illuminate\Foundation\Http\Kernel;
use Luracast\Restler\Format\UploadFormat;
use Luracast\Restler\RestException;
use Maveriks\Util; use Maveriks\Util;
use ProcessMaker\Core\System; use ProcessMaker\Core\System;
use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Services; use ProcessMaker\Services;
use ProcessMaker\Services\Api; use ProcessMaker\Services\Api;
use Luracast\Restler\RestException; use ProcessMaker\Validation\ValidationUploadedFiles;
use Illuminate\Foundation\Http\Kernel;
use G;
/** /**
* Web application bootstrap * Web application bootstrap
@@ -252,8 +254,6 @@ class WebApplication
*/ */
protected function initRest($uri, $version, $multipart = false) 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 contains directory where Services Classes are allocated
$servicesDir = $this->workflowDir . 'engine' . DS . 'src' . DS . 'ProcessMaker' . DS . 'Services' . DS; $servicesDir = $this->workflowDir . 'engine' . DS . 'src' . DS . 'ProcessMaker' . DS . 'Services' . DS;
// $apiDir - contains directory to scan classes and add them to Restler // $apiDir - contains directory to scan classes and add them to Restler
@@ -331,6 +331,19 @@ class WebApplication
$this->rest->setOverridingFormats('JsonFormat', 'UploadFormat'); $this->rest->setOverridingFormats('JsonFormat', 'UploadFormat');
UploadFormat::$customValidationFunction = function($target) {
$validator = ValidationUploadedFiles::getValidationUploadedFiles()->runRules([
'filename' => $target['name'],
'path' => $target['tmp_name']
]);
if ($validator->fails()) {
if ($validator->getStatus() === 429) {
throw new RestException($validator->getStatus());
}
}
return true;
};
// scan all api directory to find api classes // scan all api directory to find api classes
$classesList = Util\Common::rglob($apiDir . "/*"); $classesList = Util\Common::rglob($apiDir . "/*");

View File

@@ -4,6 +4,7 @@ use ProcessMaker\Core\System;
use ProcessMaker\AuditLog\AuditLog; use ProcessMaker\AuditLog\AuditLog;
use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Services\OAuth2\Server; use ProcessMaker\Services\OAuth2\Server;
use ProcessMaker\Validation\ValidationUploadedFiles;
class G class G
{ {
@@ -1183,7 +1184,7 @@ class G
\Bootstrap::registerMonologPhpUploadExecution('phpExecution', 200, 'Php Execution', $filename); \Bootstrap::registerMonologPhpUploadExecution('phpExecution', 200, 'Php Execution', $filename);
require_once($filename); require_once($filename);
} else { } 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); \Bootstrap::registerMonologPhpUploadExecution('phpExecution', 550, $message, $filename);
echo $message; echo $message;
} }
@@ -5488,6 +5489,16 @@ class G
*/ */
public static function verifyInputDocExtension($InpDocAllowedFiles, $fileName, $filesTmpName) 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 // Initialize variables
$res = new stdclass(); $res = new stdclass();
$res->status = false; $res->status = false;
@@ -5497,14 +5508,6 @@ class G
$aux = pathinfo($fileName); $aux = pathinfo($fileName);
$fileExtension = isset($aux['extension']) ? strtolower($aux['extension']) : ''; $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 required extension is *.* don't validate
if (in_array('*', $allowedTypes)) { if (in_array('*', $allowedTypes)) {
$res->status = true; $res->status = true;

View File

@@ -24851,12 +24851,24 @@ msgstr "The default configuration was not defined"
msgid "The change might cause data loss in the PM table. Do you want to continue?" 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?" 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 # TRANSLATION
# LABEL/ID_THE_REASON_REASSIGN_USER_EMPTY # LABEL/ID_THE_REASON_REASSIGN_USER_EMPTY
#: LABEL/ID_THE_REASON_REASSIGN_USER_EMPTY #: LABEL/ID_THE_REASON_REASSIGN_USER_EMPTY
msgid "Please complete the reassign reason." msgid "Please complete the reassign reason."
msgstr "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 # TRANSLATION
# LABEL/ID_THE_USERNAME_EMAIL_IS_INCORRECT # LABEL/ID_THE_USERNAME_EMAIL_IS_INCORRECT
#: LABEL/ID_THE_USERNAME_EMAIL_IS_INCORRECT #: LABEL/ID_THE_USERNAME_EMAIL_IS_INCORRECT
@@ -25181,6 +25193,12 @@ msgstr "Today"
msgid "Tools" msgid "Tools"
msgstr "Tools" msgstr "Tools"
# TRANSLATION
# LABEL/ID_TOO_MANY_REQUESTS
#: LABEL/ID_TOO_MANY_REQUESTS
msgid "Too many requests"
msgstr "Too many requests"
# TRANSLATION # TRANSLATION
# LABEL/ID_TOP_MARGIN # LABEL/ID_TOP_MARGIN
#: LABEL/ID_TOP_MARGIN #: LABEL/ID_TOP_MARGIN

View File

@@ -2,6 +2,7 @@
use ProcessMaker\Core\System; use ProcessMaker\Core\System;
use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Validation\ValidationUploadedFiles;
/** /**
* adminProxy.php * adminProxy.php
@@ -1025,7 +1026,14 @@ class adminProxy extends HttpProxyController
*/ */
public function uploadImage() public function uploadImage()
{ {
//!dataSystem ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
echo G::json_encode([
'success' => true,
'failed' => true,
'message' => $validator->getMessage()
]);
exit();
});
$filter = new InputFilter(); $filter = new InputFilter();
$_SERVER["REQUEST_URI"] = $filter->xssFilterHard($_SERVER["REQUEST_URI"]); $_SERVER["REQUEST_URI"] = $filter->xssFilterHard($_SERVER["REQUEST_URI"]);

View File

@@ -8,6 +8,8 @@
*/ */
use ProcessMaker\Core\System; use ProcessMaker\Core\System;
use ProcessMaker\Validation\Exception429;
use ProcessMaker\Validation\ValidationUploadedFiles;
header("Content-type: text/html;charset=utf-8"); header("Content-type: text/html;charset=utf-8");
require_once 'classes/model/AdditionalTables.php'; require_once 'classes/model/AdditionalTables.php';
@@ -723,6 +725,9 @@ class pmTablesProxy extends HttpProxyController
} }
try { try {
ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
throw new Exception429($validator->getMessage());
});
$result = new stdClass(); $result = new stdClass();
$errors = ''; $errors = '';
$fromConfirm = false; $fromConfirm = false;
@@ -891,6 +896,11 @@ class pmTablesProxy extends HttpProxyController
} }
$result->message = $msg; $result->message = $msg;
} catch (Exception429 $e) {
$result = new stdClass();
$result->success = false;
$result->errorType = 'notice';
$result->message = $e->getMessage();
} catch (Exception $e) { } catch (Exception $e) {
$result = new stdClass(); $result = new stdClass();
$result->fromAdmin = $fromAdmin; $result->fromAdmin = $fromAdmin;

View File

@@ -61035,7 +61035,9 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE
( 'LABEL','ID_THE_APPLICATION_IS_NOT_CANCELED','en','Error: The application {0} is not canceled.','2016-06-15') , ( '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_DEFAULT_CONFIGURATION','en','The default configuration was not defined','2016-11-16') ,
( '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_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_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_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_MONTH','en','This Month','2014-01-15') ,
( 'LABEL','ID_THIS_QUARTER','en','This quarter','2014-01-15') , ( 'LABEL','ID_THIS_QUARTER','en','This quarter','2014-01-15') ,
@@ -61092,6 +61094,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_TO','en','To','2014-01-15') ,
( 'LABEL','ID_TODAY','en','Today','2014-01-15') , ( 'LABEL','ID_TODAY','en','Today','2014-01-15') ,
( 'LABEL','ID_TOOLS','en','Tools','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_TOP_MARGIN','en','Top Margin','2014-01-15') ,
( 'LABEL','ID_TOTAL_CASES','en','Total Cases','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') , ( 'LABEL','ID_TOTAL_CASES_REASSIGNED','en','Total Cases Reassigned','2014-01-15') ,

View File

@@ -1,6 +1,7 @@
<?php <?php
use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Validation\ValidationUploadedFiles;
$filter = new InputFilter(); $filter = new InputFilter();
$_POST = $filter->xssFilterHard($_POST); $_POST = $filter->xssFilterHard($_POST);
@@ -1445,6 +1446,15 @@ function checkTree($uidOriginFolder, $uidNewFolder)
*/ */
function uploadExternalDocument() 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 = [];
$response['action'] = $_POST['action'] . " - " . $_POST['option']; $response['action'] = $_POST['action'] . " - " . $_POST['option'];
$response['error'] = "error"; $response['error'] = "error";
@@ -1531,18 +1541,6 @@ function uploadExternalDocument()
//Read. Instance Document classes //Read. Instance Document classes
if (!empty($quequeUpload)) { 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']; $docUid = $_POST['docUid'];
$appDocUid = isset($_POST['APP_DOC_UID']) ? $_POST['APP_DOC_UID'] : ""; $appDocUid = isset($_POST['APP_DOC_UID']) ? $_POST['APP_DOC_UID'] : "";
$docVersion = isset($_POST['docVersion']) ? $_POST['docVersion'] : ""; $docVersion = isset($_POST['docVersion']) ? $_POST['docVersion'] : "";

View File

@@ -2,6 +2,8 @@
use ProcessMaker\Core\System; use ProcessMaker\Core\System;
use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Validation\Exception429;
use ProcessMaker\Validation\ValidationUploadedFiles;
function runBgProcessmaker($task, $log) function runBgProcessmaker($task, $log)
{ {
@@ -16,6 +18,9 @@ function runBgProcessmaker($task, $log)
} }
try { try {
ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
throw new Exception429($validator->getMessage());
});
if (isset($_REQUEST["action"])) { if (isset($_REQUEST["action"])) {
$action = $_REQUEST["action"]; $action = $_REQUEST["action"];
} else { } else {
@@ -312,6 +317,15 @@ try {
$result["addons"] = array(); $result["addons"] = array();
} }
G::outRes(G::json_encode($result)); G::outRes(G::json_encode($result));
} catch (Exception429 $e) {
$token = strtotime("now");
PMException::registerErrorLog($e, $token);
G::outRes(
G::json_encode(array(
"success" => false,
"errors" => $e->getMessage()
))
);
} catch (Exception $e) { } catch (Exception $e) {
$token = strtotime("now"); $token = strtotime("now");
PMException::registerErrorLog($e, $token); PMException::registerErrorLog($e, $token);

View File

@@ -27,6 +27,7 @@
global $RBAC; global $RBAC;
use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Validation\ValidationUploadedFiles;
$RBAC->requirePermissions("PM_SETUP_ADVANCE"); $RBAC->requirePermissions("PM_SETUP_ADVANCE");
require_once PATH_CORE . 'methods' . PATH_SEP . 'enterprise' . PATH_SEP . 'enterprise.php'; require_once PATH_CORE . 'methods' . PATH_SEP . 'enterprise' . PATH_SEP . 'enterprise.php';
@@ -35,6 +36,9 @@ $response = array();
$status = 1; $status = 1;
try { try {
ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
throw new Exception($validator->getMessage());
});
if (!isset($_FILES["form"]["error"]["PLUGIN_FILENAME"]) || $_FILES["form"]["error"]["PLUGIN_FILENAME"] == 1) { 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."; $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.";

View File

@@ -23,6 +23,16 @@
*/ */
use \ProcessMaker\Importer\XmlImporter; 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); ini_set("max_execution_time", 0);
$affectedGroups = array(); $affectedGroups = array();

View File

@@ -1,5 +1,7 @@
<?php <?php
use ProcessMaker\Validation\ValidationUploadedFiles;
sleep(1); sleep(1);
global $RBAC; global $RBAC;
if ($RBAC->userCanAccess('PM_FACTORY') == 1) { if ($RBAC->userCanAccess('PM_FACTORY') == 1) {
@@ -25,26 +27,23 @@ if ($RBAC->userCanAccess('PM_FACTORY') == 1) {
} }
} }
$fileName = $_FILES['form']['name']; ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
$canUploadPhpFile = true; $response = [
$extension = pathinfo($fileName, PATHINFO_EXTENSION); 'result' => 0,
if (\Bootstrap::getDisablePhpUploadExecution() === 1 && $extension === 'php') { 'msg' => $validator->getMessage()
$message = \G::LoadTranslation('THE_UPLOAD_OF_PHP_FILES_WAS_DISABLED'); ];
\Bootstrap::registerMonologPhpUploadExecution('phpUpload', 550, $message, $fileName); print_r(G::json_encode($response));
$canUploadPhpFile = false; die();
} });
if ($_FILES['form']['error'] == "0" && $canUploadPhpFile) { $fileName = $_FILES['form']['name'];
if ($_FILES['form']['error'] == "0") {
G::uploadFile($_FILES['form']['tmp_name'], $sDirectory, $fileName); G::uploadFile($_FILES['form']['tmp_name'], $sDirectory, $fileName);
$msg = "Uploaded (" . (round((filesize($sDirectory . $fileName) / 1024) * 10) / 10) . " kb)"; $msg = "Uploaded (" . (round((filesize($sDirectory . $fileName) / 1024) * 10) / 10) . " kb)";
$result = 1; $result = 1;
} else { } else {
$msg = "Failed"; $msg = "Failed";
if ($canUploadPhpFile === false) {
$msg = $message;
}
$result = 0; $result = 0;
} }
echo "{'result': $result, 'msg':'$msg'}"; echo "{'result': $result, 'msg':'$msg'}";
} }

View File

@@ -2,6 +2,8 @@
require_once "classes/model/Language.php"; require_once "classes/model/Language.php";
use ProcessMaker\Validation\ValidationUploadedFiles;
global $RBAC; global $RBAC;
$access = $RBAC->userCanAccess('PM_SETUP_ADVANCE'); $access = $RBAC->userCanAccess('PM_SETUP_ADVANCE');
@@ -24,6 +26,9 @@ if ($access != 1) {
$result = new stdClass(); $result = new stdClass();
try { try {
ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
throw new Exception($validator->getMessage());
});
//if the xmlform path is writeable //if the xmlform path is writeable
if (!is_writable(PATH_XMLFORM)) { if (!is_writable(PATH_XMLFORM)) {
throw new Exception(G::LoadTranslation('IMPORT_LANGUAGE_ERR_NO_WRITABLE')); throw new Exception(G::LoadTranslation('IMPORT_LANGUAGE_ERR_NO_WRITABLE'));

View File

@@ -26,11 +26,15 @@
use ProcessMaker\Core\System; use ProcessMaker\Core\System;
use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Validation\ValidationUploadedFiles;
global $RBAC; global $RBAC;
$RBAC->requirePermissions('PM_SETUP_ADVANCE'); $RBAC->requirePermissions('PM_SETUP_ADVANCE');
try { try {
ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
throw new Exception($validator->getMessage());
});
//load the variables //load the variables
if (!isset($_FILES['form']['error']['PLUGIN_FILENAME']) || $_FILES['form']['error']['PLUGIN_FILENAME'] == 1) { if (!isset($_FILES['form']['error']['PLUGIN_FILENAME']) || $_FILES['form']['error']['PLUGIN_FILENAME'] == 1) {
throw (new Exception(G::loadTranslation('ID_ERROR_UPLOADING_PLUGIN_FILENAME'))); throw (new Exception(G::loadTranslation('ID_ERROR_UPLOADING_PLUGIN_FILENAME')));

View File

@@ -1,6 +1,7 @@
<?php <?php
use ProcessMaker\Core\System; use ProcessMaker\Core\System;
use ProcessMaker\Validation\ValidationUploadedFiles;
if (! isset( $_REQUEST['action'] )) { if (! isset( $_REQUEST['action'] )) {
$res['success'] = false; $res['success'] = false;
@@ -199,6 +200,9 @@ function newSkin ($baseSkin = 'classic')
function importSkin () function importSkin ()
{ {
try { try {
ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
throw new Exception($validator->getMessage());
});
if (! isset( $_FILES['uploadedFile'] )) { if (! isset( $_FILES['uploadedFile'] )) {
throw (new Exception( G::LoadTranslation( 'ID_SKIN_FILE_REQUIRED' ) )); throw (new Exception( G::LoadTranslation( 'ID_SKIN_FILE_REQUIRED' ) ));
} }

View File

@@ -1,28 +1,29 @@
<?php <?php
namespace ProcessMaker\BusinessModel\Cases; 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 AppDelegation;
use AppDelegationPeer; use AppDelegationPeer;
use Users; use AppDocument;
use Configurations; use AppDocumentPeer;
use Bootstrap;
use WsBase;
use ApplicationPeer;
use ProcessMaker\BusinessModel\ProcessSupervisor;
use ProcessMaker\BusinessModel\Cases AS BusinessModelCases;
use Cases;
use ProcessUserPeer;
use AppFolder; 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 class InputDocument
@@ -936,6 +937,12 @@ class InputDocument
*/ */
public function uploadFileCase($files, $caseInstance, $aData, $userUid, $appUid, $delIndex) 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(); $arrayField = array();
$arrayFileName = array(); $arrayFileName = array();
$arrayFileTmpName = 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); $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 = new AppDocument();
$oAppDocument->create($aFields); $oAppDocument->create($aFields);

View File

@@ -196,11 +196,6 @@ class FilesManager
if ($extention == '.exe') { if ($extention == '.exe') {
throw new \Exception(\G::LoadTranslation('ID_FILE_UPLOAD_INCORRECT_EXTENSION')); 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; break;
default: default:
$sDirectory = PATH_DATA_MAILTEMPLATES . $sProcessUID . PATH_SEP . $sSubDirectory . $aData['prf_filename']; $sDirectory = PATH_DATA_MAILTEMPLATES . $sProcessUID . PATH_SEP . $sSubDirectory . $aData['prf_filename'];

View File

@@ -995,16 +995,6 @@ class Light
$confEnvSetting = $config->getFormats(); $confEnvSetting = $config->getFormats();
$user = new Users(); $user = new Users();
foreach ($requestData as $k => $file) { 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(); $cases = new Cases();
$delIndex = $cases->getCurrentDelegation($appUid, $userUid); $delIndex = $cases->getCurrentDelegation($appUid, $userUid);
$docUid = !empty($file['docUid']) ? $file['docUid'] : -1; $docUid = !empty($file['docUid']) ? $file['docUid'] : -1;

View File

@@ -66,7 +66,9 @@ class System
'logging_level' => 'INFO', 'logging_level' => 'INFO',
'smtp_timeout' => 20, 'smtp_timeout' => 20,
'google_map_api_key' => '', 'google_map_api_key' => '',
'google_map_signature' => '' 'google_map_signature' => '',
'logging_level' => 'INFO',
'upload_attempts_limit_per_user' => '60,1'
); );
/** /**

View File

@@ -23,6 +23,7 @@ use ProcessMaker\Project\Adapter;
use ProcessMaker\Services\Api; use ProcessMaker\Services\Api;
use ProcessMaker\Services\Api\Project\Activity\Step; use ProcessMaker\Services\Api\Project\Activity\Step;
use ProcessMaker\Util\DateTime; use ProcessMaker\Util\DateTime;
use ProcessMaker\Validation\Exception429;
use RBAC; use RBAC;
use stdclass; use stdclass;
use StepPeer; use StepPeer;
@@ -1466,10 +1467,11 @@ class Light extends Api
$userUid = $this->getUserId(); $userUid = $this->getUserId();
$oMobile = new BusinessModelLight(); $oMobile = new BusinessModelLight();
$filesUids = $oMobile->postUidUploadFiles($userUid, $app_uid, $request_data); $filesUids = $oMobile->postUidUploadFiles($userUid, $app_uid, $request_data);
} catch (Exception429 $e) {
throw new RestException($e->getStatus());
} catch (Exception $e) { } catch (Exception $e) {
throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
} }
return $filesUids; return $filesUids;
} }
@@ -1501,10 +1503,11 @@ class Light extends Api
$userUid = $this->getUserId(); $userUid = $this->getUserId();
$oMobile = new BusinessModelLight(); $oMobile = new BusinessModelLight();
$response = $oMobile->documentUploadFiles($userUid, $app_uid, $app_doc_uid, $request_data); $response = $oMobile->documentUploadFiles($userUid, $app_uid, $app_doc_uid, $request_data);
} catch (Exception429 $e) {
throw new RestException($e->getStatus());
} catch (Exception $e) { } catch (Exception $e) {
throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage())); throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
} }
return $response; return $response;
} }

View File

@@ -1,8 +1,11 @@
<?php <?php
namespace ProcessMaker\Services\Api\Project; namespace ProcessMaker\Services\Api\Project;
use \ProcessMaker\Services\Api; use Exception;
use \Luracast\Restler\RestException; use Luracast\Restler\RestException;
use ProcessMaker\BusinessModel\FilesManager as FilesManagerBusinessModel;
use ProcessMaker\Services\Api;
use ProcessMaker\Validation\Exception429;
/** /**
* Project\ProjectUsers Api Controller * Project\ProjectUsers Api Controller
@@ -57,11 +60,13 @@ class FilesManager extends Api
$userUid = $this->getUserId(); $userUid = $this->getUserId();
$request_data = (array)($request_data); $request_data = (array)($request_data);
$request_data = array_merge(array('prf_content' => $prf_content ), $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); $arrayData = $filesManager->addProcessFilesManager($prj_uid, $userUid, $request_data);
//Response //Response
$response = $arrayData; $response = $arrayData;
} catch (\Exception $e) { } catch (Exception429 $e) {
throw new RestException($e->getStatus());
} catch (Exception $e) {
//response //response
throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()); throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
} }
@@ -85,11 +90,13 @@ class FilesManager extends Api
public function doPostProcessFilesManagerUpload($prj_uid, $prf_uid) public function doPostProcessFilesManagerUpload($prj_uid, $prf_uid)
{ {
try { try {
$filesManager = new \ProcessMaker\BusinessModel\FilesManager(); $filesManager = new FilesManagerBusinessModel();
$sData = $filesManager->uploadProcessFilesManager($prj_uid, $prf_uid); $sData = $filesManager->uploadProcessFilesManager($prj_uid, $prf_uid);
//Response //Response
$response = $sData; $response = $sData;
} catch (\Exception $e) { } catch (Exception429 $e) {
throw new RestException($e->getStatus());
} catch (Exception $e) {
//response //response
throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()); throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
} }

View File

@@ -0,0 +1,23 @@
<?php
namespace ProcessMaker\Validation;
use Exception;
class Exception429 extends Exception
{
/**
* Status code: too many requests.
* @var int
*/
private $status = 429;
/**
* Get status code.
* @return int
*/
function getStatus()
{
return $this->status;
}
}

View 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;
}
}

View File

@@ -0,0 +1,167 @@
<?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 ProcessMaker\Validation\Validator;
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);
});
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;
}
$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;
}
}

View 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;
}
}

View File

@@ -283,7 +283,10 @@ Ext.onReady(function () {
} }
else { else {
var messageError = ""; 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 //| 1-> Fail in the type of the image
messageError = _('ID_ERROR_UPLOADING_IMAGE_TYPE'); messageError = _('ID_ERROR_UPLOADING_IMAGE_TYPE');
} }

View File

@@ -6,6 +6,7 @@ use ProcessMaker\Core\AppEvent;
use ProcessMaker\ChangeLog\ChangeLog; use ProcessMaker\ChangeLog\ChangeLog;
/*----------------------------------********---------------------------------*/ /*----------------------------------********---------------------------------*/
use ProcessMaker\Plugins\PluginRegistry; use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Validation\ValidationUploadedFiles;
/** /**
* bootstrap - ProcessMaker Bootstrap * bootstrap - ProcessMaker Bootstrap
@@ -818,7 +819,7 @@ if (substr(SYS_COLLECTION, 0, 8) === 'gulliver') {
$isWebEntry = \ProcessMaker\BusinessModel\WebEntry::isWebEntry(SYS_COLLECTION, $phpFile); $isWebEntry = \ProcessMaker\BusinessModel\WebEntry::isWebEntry(SYS_COLLECTION, $phpFile);
if (\Bootstrap::getDisablePhpUploadExecution() === 1 && !$isWebEntry) { 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); \Bootstrap::registerMonologPhpUploadExecution('phpExecution', 550, $message, $phpFile);
echo $message; echo $message;
die(); die();
@@ -1085,6 +1086,8 @@ if (!defined('EXECUTE_BY_CRON')) {
$oPluginRegistry->init(); $oPluginRegistry->init();
if ($isControllerCall) { //Instance the Controller object and call the request method if ($isControllerCall) { //Instance the Controller object and call the request method
ValidationUploadedFiles::getValidationUploadedFiles()
->runRulesToAllUploadedFiles();
$controller = new $controllerClass(); $controller = new $controllerClass();
$controller->setHttpRequestData($_REQUEST);//NewRelic Snippet - By JHL $controller->setHttpRequestData($_REQUEST);//NewRelic Snippet - By JHL
transactionLog($controllerAction); transactionLog($controllerAction);
@@ -1105,6 +1108,8 @@ if (!defined('EXECUTE_BY_CRON')) {
->setLanguage(SYS_LANG) ->setLanguage(SYS_LANG)
->getUsrIdByUsrUid(empty($_SESSION['USER_LOGGED']) ? '' : $_SESSION['USER_LOGGED']); ->getUsrIdByUsrUid(empty($_SESSION['USER_LOGGED']) ? '' : $_SESSION['USER_LOGGED']);
/*----------------------------------********---------------------------------*/ /*----------------------------------********---------------------------------*/
ValidationUploadedFiles::getValidationUploadedFiles()
->runRulesToAllUploadedFiles();
require_once $phpFile; require_once $phpFile;
} }