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

@@ -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?"
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
@@ -25181,6 +25193,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

View 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"]);

View File

@@ -8,6 +8,8 @@
*/
use ProcessMaker\Core\System;
use ProcessMaker\Validation\Exception429;
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 Exception429($validator->getMessage());
});
$result = new stdClass();
$errors = '';
$fromConfirm = false;
@@ -891,6 +896,11 @@ class pmTablesProxy extends HttpProxyController
}
$result->message = $msg;
} catch (Exception429 $e) {
$result = new stdClass();
$result->success = false;
$result->errorType = 'notice';
$result->message = $e->getMessage();
} catch (Exception $e) {
$result = new stdClass();
$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_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_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') ,
@@ -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_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') ,

View File

@@ -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'] : "";

View File

@@ -2,6 +2,8 @@
use ProcessMaker\Core\System;
use ProcessMaker\Plugins\PluginRegistry;
use ProcessMaker\Validation\Exception429;
use ProcessMaker\Validation\ValidationUploadedFiles;
function runBgProcessmaker($task, $log)
{
@@ -16,6 +18,9 @@ function runBgProcessmaker($task, $log)
}
try {
ValidationUploadedFiles::getValidationUploadedFiles()->dispach(function($validator) {
throw new Exception429($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 (Exception429 $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);

View File

@@ -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.";

View File

@@ -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();

View File

@@ -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'}";
}

View File

@@ -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'));

View File

@@ -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')));

View File

@@ -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' ) ));
}

View File

@@ -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);

View File

@@ -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'];

View File

@@ -995,16 +995,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;

View File

@@ -66,7 +66,9 @@ 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'
);
/**

View File

@@ -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\Exception429;
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 (Exception429 $e) {
throw new RestException($e->getStatus());
} catch (Exception $e) {
throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage());
}
return $filesUids;
}
@@ -1501,10 +1503,11 @@ class Light extends Api
$userUid = $this->getUserId();
$oMobile = new BusinessModelLight();
$response = $oMobile->documentUploadFiles($userUid, $app_uid, $app_doc_uid, $request_data);
} catch (Exception429 $e) {
throw new RestException($e->getStatus());
} catch (Exception $e) {
throw (new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()));
}
return $response;
}

View File

@@ -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\Exception429;
/**
* 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 (Exception429 $e) {
throw new RestException($e->getStatus());
} 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 (Exception429 $e) {
throw new RestException($e->getStatus());
} catch (Exception $e) {
//response
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 {
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');
}

View File

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