From 8ddabd73db4a4acdf4e7512dff6ef21f6c00c06c Mon Sep 17 00:00:00 2001 From: Victor Saisa Lopez Date: Wed, 19 Nov 2014 16:47:22 -0400 Subject: [PATCH] PM-473 "Analisis de los resultados de escaneo de las..." SOLVED Issue: Analisis de los resultados de escaneo de las funciones en ProcessMaker. Plugin/trigger code scanner. Cause: Nueva solicitud de funciones Solution: Se ha implementado esta nueva funcionalidad, que consta de lo siguiente: - Escaneo de codigo al importar un plugin (no se aplica a plugins enterprise) - Escaneo de codigo al habilitar un plugin (si el plugin ya se encuentra fisicamente en el directorio de los plugins) - Escaneo de codigo al importar un proceso - Escaneo de codigo al crear/modificar codigo de un trigger - Escaneo de codigo al ejecutar un caso que tenga seteados triggers en sus steps (si el trigger tiene codigo no deseado, no se ejecuta el trigger) - Se ha agregado la opcion "check-plugin-disabled-code" al comando "./gulliver", el mismo muestra informacion sobre los plugins con codigo no deseado. Ej: $ ./gulliver check-plugin-disabled-code [enterprise-plugin|custom-plugin|all|] - Se ha agregado la opcion "check-workspace-disabled-code" al comando "./processmaker", el mismo muestra informacion sobre los workspaces con codigo no deseado en sus triggers. Ej: $ ./processmaker check-workspace-disabled-code - Por defecto ProcessMaker no realiza el escaneo de codigo, si se desea escanear codigo no deseado, se debera definir el atributo "enable_blacklist = 1" en el archivo "env.ini", este atributo no se aplica a las nuevas opciones creadas para los comandos "./gulliver" y "./processmaker" - Para una configuracion personalizada de codigo no deseado (lista negra), se pueden definir las mismas en el archivo "path/to/processmaker/workflow/engine/config/blacklist.ini" (si no existe el archivo se puede crear), o tambien en el atributo "disable_functions" esto en el archivo "php.ini" Ejemplo de "blacklist.ini": ;Classes ;======= DashletInterface ;Functions ;========= eval exec ;date ;echo strlen --- gulliver/bin/tasks/pakeGulliver.php | 119 ++++++++++ gulliver/system/class.codeScanner.php | 218 ++++++++++++++++++ workflow/engine/bin/tasks/cliWorkspaces.php | 70 +++++- workflow/engine/classes/class.case.php | 54 ++++- workflow/engine/classes/class.processes.php | 97 ++++++++ workflow/engine/classes/class.wsTools.php | 24 +- workflow/engine/classes/model/AppHistory.php | 2 +- .../processes/processes_Import_Ajax.php | 79 ++++++- .../engine/methods/setup/pluginsChange.php | 40 +++- .../methods/setup/pluginsImportFile.php | 18 +- .../engine/methods/triggers/triggers_Save.php | 47 +++- workflow/engine/templates/processes/main.js | 13 ++ .../engine/templates/setup/pluginsMain.js | 13 +- .../engine/xmlform/triggers/triggers_Edit.xml | 44 +++- 14 files changed, 784 insertions(+), 54 deletions(-) create mode 100644 gulliver/system/class.codeScanner.php diff --git a/gulliver/bin/tasks/pakeGulliver.php b/gulliver/bin/tasks/pakeGulliver.php index c4459e6bf..57b1dfa7a 100755 --- a/gulliver/bin/tasks/pakeGulliver.php +++ b/gulliver/bin/tasks/pakeGulliver.php @@ -52,6 +52,9 @@ pake_task('new-plugin', 'project_exists'); pake_desc("Update the plugin attributes in all workspaces\n args: "); pake_task("update-plugin-attributes", "project_exists"); +pake_desc("Check disabled code in plugins\n args: [enterprise-plugin|custom-plugin|all|]"); +pake_task("check-plugin-disabled-code", "project_exists"); + pake_desc("pack plugin in .tar file \n args: "); pake_task('pack-plugin', 'project_exists'); @@ -2641,3 +2644,119 @@ function run_update_plugin_attributes($task, $args) } } +function run_check_plugin_disabled_code($task, $args) +{ + try { + //Set variables + $option = (isset($args[0]))? trim($args[0]) : ""; + $option2 = strtoupper($option); + + switch ($option2) { + case "ENTERPRISE-PLUGIN": + break; + case "CUSTOM-PLUGIN": + case "ALL": + case "": + break; + default: + //PLUGIN-NAME + $option2 = "PLUGIN-NAME"; + break; + } + + if (is_dir(PATH_PLUGINS)) { + if ($dirh = opendir(PATH_PLUGINS)) { + G::LoadClass("system"); + + require_once("propel" . PATH_SEP . "Propel.php"); + require_once(PATH_CORE . "methods" . PATH_SEP . "enterprise" . PATH_SEP . "enterprise.php"); + + Propel::init(PATH_CORE . "config" . PATH_SEP . "databases.php"); + + $arrayData = array(); + + while (($file = readdir($dirh)) !== false) { + if (preg_match("/^.+\.php$/", $file)) { + $pluginName = str_replace(".php", "", $file); + + if (is_file(PATH_PLUGINS . $pluginName . ".php") && is_dir(PATH_PLUGINS . $pluginName)) { + require_once(PATH_PLUGINS . $pluginName . ".php"); + + $pluginClassName = $pluginName . "Plugin"; + + $p = new $pluginClassName(); + + switch ($option2) { + case "ENTERPRISE-PLUGIN": + if (get_parent_class($p) == "enterprisePlugin") { + $arrayData[] = $pluginName; + } + break; + case "CUSTOM-PLUGIN": + case "ALL": + case "": + if (get_parent_class($p) == "PMPlugin") { + $arrayData[] = $pluginName; + } + break; + default: + //PLUGIN-NAME + if ($pluginName == $option) { + $arrayData[] = $pluginName; + } + break; + } + } + } + } + + closedir($dirh); + + //Verify data + if ($option2 == "PLUGIN-NAME" && count($arrayData) == 0) { + throw new Exception("Error: The plugin does not exist"); + } + + //Check disabled code + if (count($arrayData) > 0) { + G::LoadClass("codeScanner"); + + $cs = new CodeScanner("DISABLED_CODE"); + + $strFoundDisabledCode = ""; + + foreach ($arrayData as $value) { + $pluginName = $value; + + $arrayFoundDisabledCode = array_merge($cs->checkDisabledCode("FILE", PATH_PLUGINS . $pluginName . ".php"), $cs->checkDisabledCode("PATH", PATH_PLUGINS . $pluginName)); + + if (count($arrayFoundDisabledCode) > 0) { + $strFoundDisabledCode .= (($strFoundDisabledCode != "")? "\n\n" : "") . "> " . $pluginName; + + foreach ($arrayFoundDisabledCode as $key2 => $value2) { + $strCodeAndLine = ""; + + foreach ($value2 as $key3 => $value3) { + $strCodeAndLine .= (($strCodeAndLine != "")? ", " : "") . $key3 . " (Lines " . implode(", ", $value3) . ")"; + } + + $strFoundDisabledCode .= "\n- " . str_replace(PATH_PLUGINS, "", $key2) . ": " . $strCodeAndLine; + } + } + } + + if ($strFoundDisabledCode != "") { + echo "The next plugins have the following unwanted code (this code should be removed):\n\n" . $strFoundDisabledCode . "\n\n"; + } else { + echo "The plugin(s) it's OK\n\n"; + } + } + } + } + + echo "Done!\n"; + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } +} + diff --git a/gulliver/system/class.codeScanner.php b/gulliver/system/class.codeScanner.php new file mode 100644 index 000000000..6a81881eb --- /dev/null +++ b/gulliver/system/class.codeScanner.php @@ -0,0 +1,218 @@ +setArrayDisabledCode(); + break; + } + } catch (Exception $e) { + throw $e; + } + } + + /** + * Set disabled code + * + * return void + */ + public function setArrayDisabledCode() + { + try { + //Disabled functions (PHP) + $disableFunctions = ini_get("disable_functions"); + + if ($disableFunctions != "") { + $this->arrayDisabledCode = array_filter(array_map("trim", explode(",", $disableFunctions))); + } + + //Disabled code (blacklist) + $fileDisabledCode = PATH_CONFIG . "blacklist.ini"; + + if (file_exists($fileDisabledCode)) { + $arrayAux = array_filter(array_map("trim", file($fileDisabledCode, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES))); + $arrayAux = array_filter($arrayAux, create_function("\$line", "return !preg_match(\"/^;.*\$/\", \$line);")); + + $this->arrayDisabledCode = array_unique(array_merge($this->arrayDisabledCode, $arrayAux)); + } + } catch (Exception $e) { + throw $e; + } + } + + /** + * Get disabled code + * + * return array Return array with disabled code + */ + public function getArrayDisabledCode() + { + try { + return $this->arrayDisabledCode; + } catch (Exception $e) { + throw $e; + } + } + + /** + * Verify if exists disabled code + * + * return bool Return true if exists disabled code, false otherwise + */ + public function existsDisabledCode() + { + try { + return count($this->arrayDisabledCode) > 0; + } catch (Exception $e) { + throw $e; + } + } + + /** + * Check disabled code in Source + * + * @param string $source Source + * + * return array Return array with disabled code found, array empty otherwise + */ + public function checkDisabledCodeInSource($source) + { + try { + if (!$this->existsDisabledCode()) { + //Return + return array(); + } + + if (trim($source) == "") { + //Return + return array(); + } + + //Search code + $arrayFoundCode = array(); + + $arrayDisabledTokenAux = array( + T_COMMENT, //// or #, and /* */ //Comments + T_ML_COMMENT, + T_DOC_COMMENT, ///** */ //PHPDoc style comments + T_VARIABLE, //$foo //Variables + T_CONSTANT_ENCAPSED_STRING, //"foo" or 'bar' //String syntax + T_DOUBLE_ARROW, //=> //Array syntax + T_OBJECT_OPERATOR //-> //Classes and objects + ); + + $arrayToken = token_get_all("arrayDisabledCode as $value2) { + $code = $value2; + + if (preg_match("/^" . $code . "$/i", trim($text))) { + $arrayFoundCode[$code][$lineNumber - 1] = $lineNumber - 1; + break; + } + } + } + } + } + + ksort($arrayFoundCode); + + //Return + return $arrayFoundCode; + } catch (Exception $e) { + throw $e; + } + } + + /** + * Check disabled code + * + * @param string $option Option (SOURCE, PATH, FILE) + * @param string $data Data + * + * return array Return array with disabled code found, array empty otherwise + */ + public function checkDisabledCode($option, $data) + { + try { + if (!$this->existsDisabledCode()) { + //Return + return array(); + } + + //Search code + $arrayFoundCode = array(); + + switch ($option) { + case "SOURCE": + $source = $data; + + $arrayAux = $this->checkDisabledCodeInSource($source); + + if (count($arrayAux) > 0) { + $arrayFoundCode["source"] = $arrayAux; + } + break; + case "PATH": + case "FILE": + $path = $data; + + if (is_dir($path)) { + if ($dirh = opendir($path)) { + while (($file = readdir($dirh)) !== false) { + if ($file != "" && $file != "." && $file != "..") { + $f = $path . PATH_SEP . $file; + + $arrayFoundCode = array_merge($arrayFoundCode, $this->checkDisabledCode((is_dir($f))? "PATH" : "FILE", $f)); + } + } + + closedir($dirh); + } + } else { + if (preg_match("/\.php$/", $path)) { + $source = file_get_contents($path); + + $arrayAux = $this->checkDisabledCodeInSource($source); + + if (count($arrayAux) > 0) { + $arrayFoundCode[$path] = $arrayAux; + } + } + } + break; + } + + //Return + return $arrayFoundCode; + } catch (Exception $e) { + throw $e; + } + } +} + diff --git a/workflow/engine/bin/tasks/cliWorkspaces.php b/workflow/engine/bin/tasks/cliWorkspaces.php index d89727167..1b1bc3106 100755 --- a/workflow/engine/bin/tasks/cliWorkspaces.php +++ b/workflow/engine/bin/tasks/cliWorkspaces.php @@ -174,7 +174,7 @@ CLI::taskRun("runStructureDirectories"); CLI::taskName("database-generate-self-service-by-value"); CLI::taskDescription(<<name) . ": " . CLI::error($e->getMessage()) . "\n"; } + + echo "\n"; } + + echo "Done!\n"; + } catch (Exception $e) { + echo CLI::error($e->getMessage()) . "\n"; + } +} + +function run_check_workspace_disabled_code($args, $opts) +{ + try { + $arrayWorkspace = get_workspaces_from_args($args); + + foreach ($arrayWorkspace as $value) { + $workspace = $value; + + echo "> Workspace: " . $workspace->name . "\n"; + + try { + $arrayFoundDisabledCode = $workspace->getDisabledCode(); + + if (count($arrayFoundDisabledCode) > 0) { + $strFoundDisabledCode = ""; + + foreach ($arrayFoundDisabledCode as $value2) { + $arrayProcessData = $value2; + + $strFoundDisabledCode .= ($strFoundDisabledCode != "")? "\n" : ""; + $strFoundDisabledCode .= " Process: " . $arrayProcessData["processTitle"] . "\n"; + $strFoundDisabledCode .= " Triggers:\n"; + + foreach ($arrayProcessData["triggers"] as $value3) { + $arrayTriggerData = $value3; + + $strCodeAndLine = ""; + + foreach ($arrayTriggerData["disabledCode"] as $key4 => $value4) { + $strCodeAndLine .= (($strCodeAndLine != "")? ", " : "") . $key4 . " (Lines " . implode(", ", $value4) . ")"; + } + + $strFoundDisabledCode .= " - " . $arrayTriggerData["triggerTitle"] . ": " . $strCodeAndLine . "\n"; + } + } + + echo $strFoundDisabledCode . "\n"; + } else { + echo "The workspace it's OK\n\n"; + } + } catch (Exception $e) { + echo "Errors to check disabled code: " . CLI::error($e->getMessage()) . "\n\n"; + } + } + + echo "Done!\n"; } catch (Exception $e) { echo CLI::error($e->getMessage()) . "\n"; } diff --git a/workflow/engine/classes/class.case.php b/workflow/engine/classes/class.case.php index a0966d2f3..d9441f9e2 100755 --- a/workflow/engine/classes/class.case.php +++ b/workflow/engine/classes/class.case.php @@ -3234,12 +3234,23 @@ class Cases } else { $sStepUid = $sStepUidObj; } + + $delimiter = DBAdapter::getStringDelimiter(); + $c = new Criteria(); $c->clearSelectColumns(); $c->addSelectColumn(TriggersPeer::TRI_UID); + $c->addAsColumn("TRI_TITLE", ContentPeer::CON_VALUE); $c->addSelectColumn(StepTriggerPeer::ST_CONDITION); $c->addSelectColumn(TriggersPeer::TRI_TYPE); $c->addSelectColumn(TriggersPeer::TRI_WEBBOT); + + $arrayCondition = array(); + $arrayCondition[] = array(TriggersPeer::TRI_UID, ContentPeer::CON_ID, Criteria::EQUAL); + $arrayCondition[] = array(ContentPeer::CON_CATEGORY, $delimiter . "TRI_TITLE" . $delimiter, Criteria::EQUAL); + $arrayCondition[] = array(ContentPeer::CON_LANG, $delimiter . SYS_LANG . $delimiter, Criteria::EQUAL); + $c->addJoinMC($arrayCondition, Criteria::LEFT_JOIN); + $c->add(StepTriggerPeer::STEP_UID, $sStepUid); $c->add(StepTriggerPeer::TAS_UID, $sTasUid); $c->add(StepTriggerPeer::ST_TYPE, $sTriggerType); @@ -3247,13 +3258,13 @@ class Cases $c->addAscendingOrderByColumn(StepTriggerPeer::ST_POSITION); $rs = TriggersPeer::doSelectRS($c); $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); - $rs->next(); - $row = $rs->getRow(); - while (is_array($row)) { - $aTriggers[] = $row; - $rs->next(); + + while ($rs->next()) { $row = $rs->getRow(); + + $aTriggers[] = $row; } + return $aTriggers; } @@ -3270,22 +3281,55 @@ class Cases public function executeTriggers($sTasUid, $sStepType, $sStepUidObj, $sTriggerType, $aFields = array()) { + G::LoadClass("codeScanner"); + $aTriggers = $this->loadTriggers($sTasUid, $sStepType, $sStepUidObj, $sTriggerType); + if (count($aTriggers) > 0) { global $oPMScript; + $oPMScript = new PMScript(); $oPMScript->setFields($aFields); + + $arraySystemConfiguration = System::getSystemConfiguration(PATH_CONFIG . "env.ini"); + + $cs = new CodeScanner((isset($arraySystemConfiguration["enable_blacklist"]) && (int)($arraySystemConfiguration["enable_blacklist"]) == 1)? "DISABLED_CODE" : ""); + + $strFoundDisabledCode = ""; + foreach ($aTriggers as $aTrigger) { + //Check disabled code + $arrayFoundDisabledCode = $cs->checkDisabledCode("SOURCE", $aTrigger["TRI_WEBBOT"]); + + if (count($arrayFoundDisabledCode) > 0) { + $strCodeAndLine = ""; + + foreach ($arrayFoundDisabledCode["source"] as $key => $value) { + $strCodeAndLine .= (($strCodeAndLine != "")? ", " : "") . G::LoadTranslation("ID_DISABLED_CODE_CODE_AND_LINE", array($key, implode(", ", $value))); + } + + $strFoundDisabledCode .= "
- " . $aTrigger["TRI_TITLE"] . ": " . $strCodeAndLine; + continue; + } + + //Execute $bExecute = true; + if ($aTrigger['ST_CONDITION'] !== '') { $oPMScript->setScript($aTrigger['ST_CONDITION']); $bExecute = $oPMScript->evaluate(); } + if ($bExecute) { $oPMScript->setScript($aTrigger['TRI_WEBBOT']); $oPMScript->execute(); } } + + if ($strFoundDisabledCode != "") { + G::SendTemporalMessage(G::LoadTranslation("ID_DISABLED_CODE_TRIGGER_TO_EXECUTE", array($strFoundDisabledCode)), "", "string"); + } + return $oPMScript->aFields; } else { return $aFields; diff --git a/workflow/engine/classes/class.processes.php b/workflow/engine/classes/class.processes.php index 90114a760..6606112b4 100755 --- a/workflow/engine/classes/class.processes.php +++ b/workflow/engine/classes/class.processes.php @@ -4420,6 +4420,103 @@ class Processes throw ($oError); } } + + /** + * Get disabled code + * + * @param string $processUid Unique id of Process + * + * return array Return array with disabled code found, array empty otherwise + */ + public function getDisabledCode($processUid = "") + { + try { + G::LoadClass("codeScanner"); + + $arrayDisabledCode = array(); + + //Set variables + $cs = new CodeScanner("DISABLED_CODE"); + + $delimiter = DBAdapter::getStringDelimiter(); + + //Processes + $criteria = new Criteria("workflow"); + + $criteria->addSelectColumn(ProcessPeer::PRO_UID); + $criteria->addAsColumn("PRO_TITLE", ContentPeer::CON_VALUE); + + $arrayCondition = array(); + $arrayCondition[] = array(ProcessPeer::PRO_UID, ContentPeer::CON_ID, Criteria::EQUAL); + $arrayCondition[] = array(ContentPeer::CON_CATEGORY, $delimiter . "PRO_TITLE" . $delimiter, Criteria::EQUAL); + $arrayCondition[] = array(ContentPeer::CON_LANG, $delimiter . SYS_LANG . $delimiter, Criteria::EQUAL); + $criteria->addJoinMC($arrayCondition, Criteria::LEFT_JOIN); + + if ($processUid != "") { + $criteria->add(ProcessPeer::PRO_UID, $processUid, Criteria::EQUAL); + } + + $rsCriteria = ProcessPeer::doSelectRS($criteria); + $rsCriteria->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + while ($rsCriteria->next()) { + $row = $rsCriteria->getRow(); + + $processUid = $row["PRO_UID"]; + $processTitle = $row["PRO_TITLE"]; + + //Triggers + $criteriaTrigger = new Criteria("workflow"); + + $criteriaTrigger->addSelectColumn(TriggersPeer::TRI_UID); + $criteriaTrigger->addAsColumn("TRI_TITLE", ContentPeer::CON_VALUE); + $criteriaTrigger->addSelectColumn(TriggersPeer::TRI_WEBBOT); + + $arrayCondition = array(); + $arrayCondition[] = array(TriggersPeer::TRI_UID, ContentPeer::CON_ID, Criteria::EQUAL); + $arrayCondition[] = array(ContentPeer::CON_CATEGORY, $delimiter . "TRI_TITLE" . $delimiter, Criteria::EQUAL); + $arrayCondition[] = array(ContentPeer::CON_LANG, $delimiter . SYS_LANG . $delimiter, Criteria::EQUAL); + $criteriaTrigger->addJoinMC($arrayCondition, Criteria::LEFT_JOIN); + + $criteriaTrigger->add(TriggersPeer::PRO_UID, $processUid, Criteria::EQUAL); + + $rsCriteriaTrigger = TriggersPeer::doSelectRS($criteriaTrigger); + $rsCriteriaTrigger->setFetchmode(ResultSet::FETCHMODE_ASSOC); + + while ($rsCriteriaTrigger->next()) { + $row = $rsCriteriaTrigger->getRow(); + + $triggerUid = $row["TRI_UID"]; + $triggerTitle = $row["TRI_TITLE"]; + $triggerWebbot = $row["TRI_WEBBOT"]; + + //Check disabled code + $arrayFoundDisabledCode = $cs->checkDisabledCode("SOURCE", $triggerWebbot); + + if (count($arrayFoundDisabledCode) > 0) { + if (!isset($arrayDisabledCode[$processUid])) { + $arrayDisabledCode[$processUid] = array( + "processUid" => $processUid, + "processTitle" => $processTitle, + "triggers" => array() + ); + } + + $arrayDisabledCode[$processUid]["triggers"][] = array( + "triggerUid" => $triggerUid, + "triggerTitle" => $triggerTitle, + "disabledCode" => $arrayFoundDisabledCode["source"], + ); + } + } + } + + //Return + return $arrayDisabledCode; + } catch (Exception $e) { + throw $e; + } + } } //end class processes diff --git a/workflow/engine/classes/class.wsTools.php b/workflow/engine/classes/class.wsTools.php index 963b534d9..0324f447a 100755 --- a/workflow/engine/classes/class.wsTools.php +++ b/workflow/engine/classes/class.wsTools.php @@ -1551,7 +1551,7 @@ class workspaceTools foreach ($metadata->databases as $db) { if ($dbName != $newDBNames[$db->name]) { $dbName = $newDBNames[$db->name]; - + if (mysql_select_db($dbName, $link)) { if(!$overwrite) { throw new Exception("Destination Database already exist (use -o to overwrite)"); @@ -1819,4 +1819,26 @@ class workspaceTools throw $e; } } + + /** + * Get disabled code + * + * return array Return array with disabled code found, array empty otherwise + */ + public function getDisabledCode() + { + try { + $this->initPropel(true); + + G::LoadClass("processes"); + + $process = new Processes(); + + //Return + return $process->getDisabledCode(); + } catch (Exception $e) { + throw $e; + } + } } + diff --git a/workflow/engine/classes/model/AppHistory.php b/workflow/engine/classes/model/AppHistory.php index a18cc2901..23e069d00 100755 --- a/workflow/engine/classes/model/AppHistory.php +++ b/workflow/engine/classes/model/AppHistory.php @@ -165,7 +165,7 @@ class AppHistory extends BaseAppHistory $title = $arrayOutputDocumentData["OUT_DOC_TITLE"] . " (" . G::LoadTranslation("ID_OUTPUT_DOCUMENT") . ")"; break; case "ASSIGN_TASK": - $title = G::LoadTranslation("ASSIGN_TASK") . " (" . G::LoadTranslation("ID_TRIGGERS") . ")"; + $title = G::LoadTranslation("ID_ASSIGN_TASK") . " (" . G::LoadTranslation("ID_TRIGGERS") . ")"; break; } diff --git a/workflow/engine/methods/processes/processes_Import_Ajax.php b/workflow/engine/methods/processes/processes_Import_Ajax.php index a2fc0f038..349fcfee3 100644 --- a/workflow/engine/methods/processes/processes_Import_Ajax.php +++ b/workflow/engine/methods/processes/processes_Import_Ajax.php @@ -26,6 +26,63 @@ use ProcessMaker\Importer\XmlImporter; ini_set("max_execution_time", 0); +if (isset($_FILES["PROCESS_FILENAME"]) && + pathinfo($_FILES["PROCESS_FILENAME"]["name"], PATHINFO_EXTENSION) == "pm" && + $_FILES["PROCESS_FILENAME"]["error"] == 0 +) { + //Check disabled code + $response = array(); + + try { + $fh = fopen($_FILES["PROCESS_FILENAME"]["tmp_name"], "rb"); + $content = fread($fh, (int)(fread($fh, 9))); + $data = unserialize($content); + fclose($fh); + + if (is_object($data) && isset($data->triggers) && is_array($data->triggers) && count($data->triggers) > 0) { + G::LoadClass("codeScanner"); + + $arraySystemConfiguration = System::getSystemConfiguration(PATH_CONFIG . "env.ini"); + + $cs = new CodeScanner((isset($arraySystemConfiguration["enable_blacklist"]) && (int)($arraySystemConfiguration["enable_blacklist"]) == 1)? "DISABLED_CODE" : ""); + + $strFoundDisabledCode = ""; + + foreach ($data->triggers as $value) { + $arrayTriggerData = $value; + + $arrayFoundDisabledCode = $cs->checkDisabledCode("SOURCE", $arrayTriggerData["TRI_WEBBOT"]); + + if (count($arrayFoundDisabledCode) > 0) { + $strCodeAndLine = ""; + + foreach ($arrayFoundDisabledCode["source"] as $key2 => $value2) { + $strCodeAndLine .= (($strCodeAndLine != "")? ", " : "") . G::LoadTranslation("ID_DISABLED_CODE_CODE_AND_LINE", array($key2, implode(", ", $value2))); + } + + $strFoundDisabledCode .= (($strFoundDisabledCode != "")? "\n" : "") . "- " . $arrayTriggerData["TRI_TITLE"] . ": " . $strCodeAndLine; + } + } + + if ($strFoundDisabledCode != "") { + $response["status"] = "DISABLED-CODE"; + $response["success"] = true; + $response["message"] = G::LoadTranslation("ID_DISABLED_CODE_PROCESS", array($data->process["PRO_TITLE"], "\n" . $strFoundDisabledCode)); + + echo G::json_encode($response); + exit(0); + } + } + } catch (Exception $e) { + $response["status"] = "ERROR"; + $response["success"] = true; + $response["catchMessage"] = $e->getMessage(); + + echo G::json_encode($response); + exit(0); + } +} + if (isset($_FILES["PROCESS_FILENAME"]) && pathinfo($_FILES["PROCESS_FILENAME"]["name"], PATHINFO_EXTENSION) == "pmx" ) { @@ -286,17 +343,17 @@ if ($action == "uploadFileNewProcessExist") { $importer->throwExceptionIfExistsReservedWordsSql($oData); - //**cheking if the PRO_CREATE_USER exist**// - $usrCrtr = $oData->process['PRO_CREATE_USER']; - - $exist = new Users(); - if($exist->userExists($usrCrtr)){ - $usrInfo = $exist->getAllInformation($usrCrtr); - if ($usrInfo['status'] == 'CLOSED'){ - $oData->process['PRO_CREATE_USER'] = $_SESSION['USER_LOGGED']; - } - } else { - $oData->process['PRO_CREATE_USER'] = $_SESSION['USER_LOGGED']; + //**cheking if the PRO_CREATE_USER exist**// + $usrCrtr = $oData->process['PRO_CREATE_USER']; + + $exist = new Users(); + if($exist->userExists($usrCrtr)){ + $usrInfo = $exist->getAllInformation($usrCrtr); + if ($usrInfo['status'] == 'CLOSED'){ + $oData->process['PRO_CREATE_USER'] = $_SESSION['USER_LOGGED']; + } + } else { + $oData->process['PRO_CREATE_USER'] = $_SESSION['USER_LOGGED']; } $Fields['PRO_FILENAME'] = $filename; diff --git a/workflow/engine/methods/setup/pluginsChange.php b/workflow/engine/methods/setup/pluginsChange.php index 27fec35fc..68895a2f2 100755 --- a/workflow/engine/methods/setup/pluginsChange.php +++ b/workflow/engine/methods/setup/pluginsChange.php @@ -43,16 +43,38 @@ if ($handle = opendir( PATH_PLUGINS )) { $oPluginRegistry->disablePlugin( $details->sNamespace ); $size = file_put_contents( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() ); G::auditLog("DisablePlugin", "Plugin Name: ".$details->sNamespace); - print "size saved : $size
"; + //print "size saved : $size
"; } else { - //print "change to ENABLED"; - require_once (PATH_PLUGINS . $pluginFile); - $details = $oPluginRegistry->getPluginDetails( $pluginFile ); - $oPluginRegistry->enablePlugin( $details->sNamespace ); - $oPluginRegistry->setupPlugins(); //get and setup enabled plugins - $size = file_put_contents( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() ); - G::auditLog("EnablePlugin", "Plugin Name: ".$details->sNamespace); - print "size saved : $size
"; + $pluginName = str_replace(".php", "", $pluginFile); + + if (is_file(PATH_PLUGINS . $pluginName . ".php") && is_dir(PATH_PLUGINS . $pluginName)) { + //Check disabled code + G::LoadClass("codeScanner"); + + $arraySystemConfiguration = System::getSystemConfiguration(PATH_CONFIG . "env.ini"); + + $cs = new CodeScanner((isset($arraySystemConfiguration["enable_blacklist"]) && (int)($arraySystemConfiguration["enable_blacklist"]) == 1)? "DISABLED_CODE" : ""); + + $arrayFoundDisabledCode = array_merge($cs->checkDisabledCode("FILE", PATH_PLUGINS . $pluginName . ".php"), $cs->checkDisabledCode("PATH", PATH_PLUGINS . $pluginName)); + + if (count($arrayFoundDisabledCode) > 0) { + $response = array(); + $response["status"] = "DISABLED-CODE"; + $response["message"] = G::LoadTranslation("ID_DISABLED_CODE_PLUGIN"); + + echo G::json_encode($response); + exit(0); + } + + //print "change to ENABLED"; + require_once(PATH_PLUGINS . $pluginFile); + $details = $oPluginRegistry->getPluginDetails($pluginFile); + $oPluginRegistry->enablePlugin($details->sNamespace); + $oPluginRegistry->setupPlugins(); //get and setup enabled plugins + $size = file_put_contents(PATH_DATA_SITE . "plugin.singleton", $oPluginRegistry->serializeInstance()); + G::auditLog("EnablePlugin", "Plugin Name: " . $details->sNamespace); + //print "size saved : $size
"; + } } } } diff --git a/workflow/engine/methods/setup/pluginsImportFile.php b/workflow/engine/methods/setup/pluginsImportFile.php index 3f3697e64..0f1fca33a 100755 --- a/workflow/engine/methods/setup/pluginsImportFile.php +++ b/workflow/engine/methods/setup/pluginsImportFile.php @@ -162,6 +162,20 @@ try { } $res = $tar->extract( $path ); + //Check disabled code + G::LoadClass("codeScanner"); + + $arraySystemConfiguration = System::getSystemConfiguration(PATH_CONFIG . "env.ini"); + + $cs = new CodeScanner((isset($arraySystemConfiguration["enable_blacklist"]) && (int)($arraySystemConfiguration["enable_blacklist"]) == 1)? "DISABLED_CODE" : ""); + + $arrayFoundDisabledCode = array_merge($cs->checkDisabledCode("FILE", $path . $pluginFile), $cs->checkDisabledCode("PATH", $path . $sClassName)); + + if (count($arrayFoundDisabledCode) > 0) { + throw new Exception(G::LoadTranslation("ID_DISABLED_CODE_PLUGIN")); + } + + //Check if is enterprise plugin $sContent = file_get_contents( $path . $pluginFile ); $chain = preg_quote( 'extends enterprisePlugin' ); if (strpos( $sContent, $chain )) { @@ -237,14 +251,14 @@ try { $oPluginRegistry->setupPlugins(); //get and setup enabled plugins $size = file_put_contents( PATH_DATA_SITE . "plugin.singleton", $oPluginRegistry->serializeInstance() ); - + $response = $oPluginRegistry->verifyTranslation( $details->sNamespace); G::auditLog("InstallPlugin", "Plugin Name: ".$details->sNamespace ); //if ($response->recordsCountSuccess <= 0) { //throw (new Exception( 'The plugin ' . $details->sNamespace . ' couldn\'t verify any translation item. Verified Records:' . $response->recordsCountSuccess)); //} - + G::header( "Location: pluginsMain" ); die(); } catch (Exception $e) { diff --git a/workflow/engine/methods/triggers/triggers_Save.php b/workflow/engine/methods/triggers/triggers_Save.php index 8e66b72fe..5f841c7d1 100755 --- a/workflow/engine/methods/triggers/triggers_Save.php +++ b/workflow/engine/methods/triggers/triggers_Save.php @@ -63,13 +63,17 @@ if (isset( $sfunction ) && $sfunction == 'lookforNameTrigger') { } } - print $flag; - //print'krlos';return ; + + echo $flag; } else { + G::LoadClass("processMap"); + G::LoadClass("codeScanner"); + + $response = array(); + try { $oTrigger = new Triggers(); - G::LoadClass( 'processMap' ); $oProcessMap = new processMap( new DBConnection() ); if (isset( $_POST['form'] )) { $value = $_POST['form']; @@ -77,6 +81,25 @@ if (isset( $sfunction ) && $sfunction == 'lookforNameTrigger') { $value = $_POST; } + if (isset($value["TRI_WEBBOT"])) { + //Check disabled code + $arraySystemConfiguration = System::getSystemConfiguration(PATH_CONFIG . "env.ini"); + + $cs = new CodeScanner((isset($arraySystemConfiguration["enable_blacklist"]) && (int)($arraySystemConfiguration["enable_blacklist"]) == 1)? "DISABLED_CODE" : ""); + + $arrayFoundDisabledCode = $cs->checkDisabledCode("SOURCE", $value["TRI_WEBBOT"]); + + if (count($arrayFoundDisabledCode) > 0) { + $strCodeAndLine = ""; + + foreach ($arrayFoundDisabledCode["source"] as $key => $value) { + $strCodeAndLine .= (($strCodeAndLine != "")? ", " : "") . G::LoadTranslation("ID_DISABLED_CODE_CODE_AND_LINE", array($key, implode(", ", $value))); + } + + throw new Exception(G::LoadTranslation("ID_DISABLED_CODE_TRIGGER", array($strCodeAndLine))); + } + } + if ($value['TRI_UID'] != '') { $oTrigger->load( $value['TRI_UID'] ); } else { @@ -86,15 +109,17 @@ if (isset( $sfunction ) && $sfunction == 'lookforNameTrigger') { //print_r($_POST['form']);die; $oTrigger->update( $value ); - if (! isset( $_POST['mode'] )) { - $oProcessMap->triggersList( $value['PRO_UID'] ); - } - $result->success = true; - $result->msg = G::LoadTranslation( 'ID_TRIGGERS_SAVED' ); + //if (! isset( $_POST['mode'] )) { + // $oProcessMap->triggersList( $value['PRO_UID'] ); + //} + + $response["success"] = true; + $response["msg"] = G::LoadTranslation("ID_TRIGGERS_SAVED"); } catch (Exception $e) { - $result->success = false; - $result->msg = $e->getMessage(); + $response["success"] = false; + $response["msg"] = $e->getMessage(); } - print G::json_encode( $result ); + + echo G::json_encode($response); } diff --git a/workflow/engine/templates/processes/main.js b/workflow/engine/templates/processes/main.js index 0d382edd6..84a191951 100755 --- a/workflow/engine/templates/processes/main.js +++ b/workflow/engine/templates/processes/main.js @@ -1166,6 +1166,19 @@ importProcess = function() var resp_ = Ext.util.JSON.decode(resp.response.responseText); + if (resp_.status) { + if (resp_.status == "DISABLED-CODE") { + Ext.MessageBox.show({ + title: _("ID_ERROR"), + msg: "
" + stringReplace("\\x0A", "
", resp_.message) + "
", //\n 10 + icon: Ext.MessageBox.ERROR, + buttons: Ext.MessageBox.OK + }); + + return; + } + } + if (resp_.catchMessage == "") { if (resp_.ExistProcessInDatabase == "0") { if (resp_.ExistGroupsInDatabase == "0") { diff --git a/workflow/engine/templates/setup/pluginsMain.js b/workflow/engine/templates/setup/pluginsMain.js index 2b918bbf0..230343eaa 100755 --- a/workflow/engine/templates/setup/pluginsMain.js +++ b/workflow/engine/templates/setup/pluginsMain.js @@ -179,7 +179,7 @@ Ext.onReady(function(){ }); if (typeof(__PLUGIN_ERROR__) !== 'undefined') { - PMExt.notify(_('ID_PLUGINS'), __PLUGIN_ERROR__); + PMExt.notify(_("ID_PLUGINS"), __PLUGIN_ERROR__, "error", 5); } }); @@ -253,7 +253,15 @@ function activeDeactive(){ params : { UIDS : ids }, method: 'GET', success: function ( result, request ) { - //Ext.MessageBox.alert('Success', 'Data return from the server: '+ result.responseText); + var dataResponse = Ext.util.JSON.decode(result.responseText); + + if (dataResponse.status) { + if (dataResponse.status == "DISABLED-CODE") { + PMExt.notify(_("ID_PLUGINS"), dataResponse.message, "error", 5); + return; + } + } + var site = ''; if (SYS_SKIN.substring(0,2) == 'ux') { site = PROCESSMAKER_URL + '/main?st=admin&s='+parent._NODE_SELECTED; @@ -319,3 +327,4 @@ capitalize = function(s){ s = s.toLowerCase(); return s.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } ); }; + diff --git a/workflow/engine/xmlform/triggers/triggers_Edit.xml b/workflow/engine/xmlform/triggers/triggers_Edit.xml index 9ba854e2b..33f296b36 100755 --- a/workflow/engine/xmlform/triggers/triggers_Edit.xml +++ b/workflow/engine/xmlform/triggers/triggers_Edit.xml @@ -86,16 +86,38 @@ window.onbeforeunload=function(){ } }; -function triggerSave1(form){ - ajax_post(form.action, form, 'POST'); - if(opener) { - if(@QSTEP_UID!="" && @QST_TYPE!="" && opener.showTriggers) - opener.showTriggers(@QSTEP_UID,@QST_TYPE); - if(opener.reloadTriggersShortList) - opener.reloadTriggersShortList(); - } - window.close(); +function triggerSave1(form) +{ + ajax_post( + form.action, + form, + "POST", + function (responseText) + { + var dataResponse = eval("(" + responseText + ")"); //json + + if (dataResponse.success) { + if (opener) { + if (@QSTEP_UID != "" && @QST_TYPE != "" && opener.showTriggers) { + opener.showTriggers(@QSTEP_UID, @QST_TYPE); + } + + if (opener.reloadTriggersShortList) { + opener.reloadTriggersShortList(); + } + } + + window.close(); + } else { + new leimnud.module.app.alert().make({ + label: dataResponse.msg + }); + } + }, + true + ); } - -]]> +]]> + +