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|<plugin-name>]
        - 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 <myWorkspace>
        - 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
This commit is contained in:
Victor Saisa Lopez
2014-11-19 16:47:22 -04:00
parent a827623bc3
commit 8ddabd73db
14 changed files with 784 additions and 54 deletions

View File

@@ -52,6 +52,9 @@ pake_task('new-plugin', 'project_exists');
pake_desc("Update the plugin attributes in all workspaces\n args: <plugin-name>"); pake_desc("Update the plugin attributes in all workspaces\n args: <plugin-name>");
pake_task("update-plugin-attributes", "project_exists"); pake_task("update-plugin-attributes", "project_exists");
pake_desc("Check disabled code in plugins\n args: [enterprise-plugin|custom-plugin|all|<plugin-name>]");
pake_task("check-plugin-disabled-code", "project_exists");
pake_desc("pack plugin in .tar file \n args: <plugin>"); pake_desc("pack plugin in .tar file \n args: <plugin>");
pake_task('pack-plugin', 'project_exists'); 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";
}
}

View File

@@ -0,0 +1,218 @@
<?php
if (!defined("T_ML_COMMENT")) {
define("T_ML_COMMENT", T_COMMENT);
} else {
if (!defined("T_DOC_COMMENT")) {
define("T_DOC_COMMENT", T_ML_COMMENT);
}
}
class CodeScanner
{
private $arrayDisabledCode = array();
/**
* Constructor of the class
*
* return void
*/
public function __construct($option)
{
try {
switch ($option) {
case "DISABLED_CODE":
$this->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("<?php\n" . $source);
foreach ($arrayToken as $value) {
$token = $value;
if (is_array($token)) {
list($id, $text, $lineNumber) = $token;
if (!in_array($id, $arrayDisabledTokenAux)) {
foreach ($this->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;
}
}
}

View File

@@ -174,7 +174,7 @@ CLI::taskRun("runStructureDirectories");
CLI::taskName("database-generate-self-service-by-value"); CLI::taskName("database-generate-self-service-by-value");
CLI::taskDescription(<<<EOT CLI::taskDescription(<<<EOT
Generate or upgrade the table "self-service by value" Generate or upgrade the table "self-service by value".
This command populate the table "self-service by value", this for the cases when This command populate the table "self-service by value", this for the cases when
a task it's defined with "Self Service Value Based Assignment" in "Assignment Rules". a task it's defined with "Self Service Value Based Assignment" in "Assignment Rules".
@@ -186,6 +186,19 @@ EOT
CLI::taskArg("workspace-name", true, true); CLI::taskArg("workspace-name", true, true);
CLI::taskRun("run_database_generate_self_service_by_value"); CLI::taskRun("run_database_generate_self_service_by_value");
CLI::taskName("check-workspace-disabled-code");
CLI::taskDescription(<<<EOT
Check disabled code for the specified workspace(s).
This command is for check disabled code for the specified workspace(s).
If no workspace is specified, the command will be run in all workspaces. More
than one workspace can be specified.
EOT
);
CLI::taskArg("workspace-name", true, true);
CLI::taskRun("run_check_workspace_disabled_code");
/** /**
* Function run_info * Function run_info
* access public * access public
@@ -522,7 +535,62 @@ function run_database_generate_self_service_by_value($args, $opts)
} catch (Exception $e) { } catch (Exception $e) {
echo "Errors generating the table \"self-service by value\" of workspace " . CLI::info($workspace->name) . ": " . CLI::error($e->getMessage()) . "\n"; echo "Errors generating the table \"self-service by value\" of workspace " . CLI::info($workspace->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) { } catch (Exception $e) {
echo CLI::error($e->getMessage()) . "\n"; echo CLI::error($e->getMessage()) . "\n";
} }

View File

@@ -3234,12 +3234,23 @@ class Cases
} else { } else {
$sStepUid = $sStepUidObj; $sStepUid = $sStepUidObj;
} }
$delimiter = DBAdapter::getStringDelimiter();
$c = new Criteria(); $c = new Criteria();
$c->clearSelectColumns(); $c->clearSelectColumns();
$c->addSelectColumn(TriggersPeer::TRI_UID); $c->addSelectColumn(TriggersPeer::TRI_UID);
$c->addAsColumn("TRI_TITLE", ContentPeer::CON_VALUE);
$c->addSelectColumn(StepTriggerPeer::ST_CONDITION); $c->addSelectColumn(StepTriggerPeer::ST_CONDITION);
$c->addSelectColumn(TriggersPeer::TRI_TYPE); $c->addSelectColumn(TriggersPeer::TRI_TYPE);
$c->addSelectColumn(TriggersPeer::TRI_WEBBOT); $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::STEP_UID, $sStepUid);
$c->add(StepTriggerPeer::TAS_UID, $sTasUid); $c->add(StepTriggerPeer::TAS_UID, $sTasUid);
$c->add(StepTriggerPeer::ST_TYPE, $sTriggerType); $c->add(StepTriggerPeer::ST_TYPE, $sTriggerType);
@@ -3247,13 +3258,13 @@ class Cases
$c->addAscendingOrderByColumn(StepTriggerPeer::ST_POSITION); $c->addAscendingOrderByColumn(StepTriggerPeer::ST_POSITION);
$rs = TriggersPeer::doSelectRS($c); $rs = TriggersPeer::doSelectRS($c);
$rs->setFetchmode(ResultSet::FETCHMODE_ASSOC); $rs->setFetchmode(ResultSet::FETCHMODE_ASSOC);
$rs->next();
$row = $rs->getRow(); while ($rs->next()) {
while (is_array($row)) {
$aTriggers[] = $row;
$rs->next();
$row = $rs->getRow(); $row = $rs->getRow();
$aTriggers[] = $row;
} }
return $aTriggers; return $aTriggers;
} }
@@ -3270,22 +3281,55 @@ class Cases
public function executeTriggers($sTasUid, $sStepType, $sStepUidObj, $sTriggerType, $aFields = array()) public function executeTriggers($sTasUid, $sStepType, $sStepUidObj, $sTriggerType, $aFields = array())
{ {
G::LoadClass("codeScanner");
$aTriggers = $this->loadTriggers($sTasUid, $sStepType, $sStepUidObj, $sTriggerType); $aTriggers = $this->loadTriggers($sTasUid, $sStepType, $sStepUidObj, $sTriggerType);
if (count($aTriggers) > 0) { if (count($aTriggers) > 0) {
global $oPMScript; global $oPMScript;
$oPMScript = new PMScript(); $oPMScript = new PMScript();
$oPMScript->setFields($aFields); $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) { 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 .= "<br />- " . $aTrigger["TRI_TITLE"] . ": " . $strCodeAndLine;
continue;
}
//Execute
$bExecute = true; $bExecute = true;
if ($aTrigger['ST_CONDITION'] !== '') { if ($aTrigger['ST_CONDITION'] !== '') {
$oPMScript->setScript($aTrigger['ST_CONDITION']); $oPMScript->setScript($aTrigger['ST_CONDITION']);
$bExecute = $oPMScript->evaluate(); $bExecute = $oPMScript->evaluate();
} }
if ($bExecute) { if ($bExecute) {
$oPMScript->setScript($aTrigger['TRI_WEBBOT']); $oPMScript->setScript($aTrigger['TRI_WEBBOT']);
$oPMScript->execute(); $oPMScript->execute();
} }
} }
if ($strFoundDisabledCode != "") {
G::SendTemporalMessage(G::LoadTranslation("ID_DISABLED_CODE_TRIGGER_TO_EXECUTE", array($strFoundDisabledCode)), "", "string");
}
return $oPMScript->aFields; return $oPMScript->aFields;
} else { } else {
return $aFields; return $aFields;

View File

@@ -4420,6 +4420,103 @@ class Processes
throw ($oError); 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 //end class processes

View File

@@ -1551,7 +1551,7 @@ class workspaceTools
foreach ($metadata->databases as $db) { foreach ($metadata->databases as $db) {
if ($dbName != $newDBNames[$db->name]) { if ($dbName != $newDBNames[$db->name]) {
$dbName = $newDBNames[$db->name]; $dbName = $newDBNames[$db->name];
if (mysql_select_db($dbName, $link)) { if (mysql_select_db($dbName, $link)) {
if(!$overwrite) { if(!$overwrite) {
throw new Exception("Destination Database already exist (use -o to overwrite)"); throw new Exception("Destination Database already exist (use -o to overwrite)");
@@ -1819,4 +1819,26 @@ class workspaceTools
throw $e; 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;
}
}
} }

View File

@@ -165,7 +165,7 @@ class AppHistory extends BaseAppHistory
$title = $arrayOutputDocumentData["OUT_DOC_TITLE"] . " (" . G::LoadTranslation("ID_OUTPUT_DOCUMENT") . ")"; $title = $arrayOutputDocumentData["OUT_DOC_TITLE"] . " (" . G::LoadTranslation("ID_OUTPUT_DOCUMENT") . ")";
break; break;
case "ASSIGN_TASK": case "ASSIGN_TASK":
$title = G::LoadTranslation("ASSIGN_TASK") . " (" . G::LoadTranslation("ID_TRIGGERS") . ")"; $title = G::LoadTranslation("ID_ASSIGN_TASK") . " (" . G::LoadTranslation("ID_TRIGGERS") . ")";
break; break;
} }

View File

@@ -26,6 +26,63 @@ use ProcessMaker\Importer\XmlImporter;
ini_set("max_execution_time", 0); 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"]) && if (isset($_FILES["PROCESS_FILENAME"]) &&
pathinfo($_FILES["PROCESS_FILENAME"]["name"], PATHINFO_EXTENSION) == "pmx" pathinfo($_FILES["PROCESS_FILENAME"]["name"], PATHINFO_EXTENSION) == "pmx"
) { ) {
@@ -286,17 +343,17 @@ if ($action == "uploadFileNewProcessExist") {
$importer->throwExceptionIfExistsReservedWordsSql($oData); $importer->throwExceptionIfExistsReservedWordsSql($oData);
//**cheking if the PRO_CREATE_USER exist**// //**cheking if the PRO_CREATE_USER exist**//
$usrCrtr = $oData->process['PRO_CREATE_USER']; $usrCrtr = $oData->process['PRO_CREATE_USER'];
$exist = new Users(); $exist = new Users();
if($exist->userExists($usrCrtr)){ if($exist->userExists($usrCrtr)){
$usrInfo = $exist->getAllInformation($usrCrtr); $usrInfo = $exist->getAllInformation($usrCrtr);
if ($usrInfo['status'] == 'CLOSED'){ if ($usrInfo['status'] == 'CLOSED'){
$oData->process['PRO_CREATE_USER'] = $_SESSION['USER_LOGGED']; $oData->process['PRO_CREATE_USER'] = $_SESSION['USER_LOGGED'];
} }
} else { } else {
$oData->process['PRO_CREATE_USER'] = $_SESSION['USER_LOGGED']; $oData->process['PRO_CREATE_USER'] = $_SESSION['USER_LOGGED'];
} }
$Fields['PRO_FILENAME'] = $filename; $Fields['PRO_FILENAME'] = $filename;

View File

@@ -43,16 +43,38 @@ if ($handle = opendir( PATH_PLUGINS )) {
$oPluginRegistry->disablePlugin( $details->sNamespace ); $oPluginRegistry->disablePlugin( $details->sNamespace );
$size = file_put_contents( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() ); $size = file_put_contents( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() );
G::auditLog("DisablePlugin", "Plugin Name: ".$details->sNamespace); G::auditLog("DisablePlugin", "Plugin Name: ".$details->sNamespace);
print "size saved : $size <br>"; //print "size saved : $size <br>";
} else { } else {
//print "change to ENABLED"; $pluginName = str_replace(".php", "", $pluginFile);
require_once (PATH_PLUGINS . $pluginFile);
$details = $oPluginRegistry->getPluginDetails( $pluginFile ); if (is_file(PATH_PLUGINS . $pluginName . ".php") && is_dir(PATH_PLUGINS . $pluginName)) {
$oPluginRegistry->enablePlugin( $details->sNamespace ); //Check disabled code
$oPluginRegistry->setupPlugins(); //get and setup enabled plugins G::LoadClass("codeScanner");
$size = file_put_contents( PATH_DATA_SITE . 'plugin.singleton', $oPluginRegistry->serializeInstance() );
G::auditLog("EnablePlugin", "Plugin Name: ".$details->sNamespace); $arraySystemConfiguration = System::getSystemConfiguration(PATH_CONFIG . "env.ini");
print "size saved : $size <br>";
$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 <br>";
}
} }
} }
} }

View File

@@ -162,6 +162,20 @@ try {
} }
$res = $tar->extract( $path ); $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 ); $sContent = file_get_contents( $path . $pluginFile );
$chain = preg_quote( 'extends enterprisePlugin' ); $chain = preg_quote( 'extends enterprisePlugin' );
if (strpos( $sContent, $chain )) { if (strpos( $sContent, $chain )) {
@@ -237,14 +251,14 @@ try {
$oPluginRegistry->setupPlugins(); //get and setup enabled plugins $oPluginRegistry->setupPlugins(); //get and setup enabled plugins
$size = file_put_contents( PATH_DATA_SITE . "plugin.singleton", $oPluginRegistry->serializeInstance() ); $size = file_put_contents( PATH_DATA_SITE . "plugin.singleton", $oPluginRegistry->serializeInstance() );
$response = $oPluginRegistry->verifyTranslation( $details->sNamespace); $response = $oPluginRegistry->verifyTranslation( $details->sNamespace);
G::auditLog("InstallPlugin", "Plugin Name: ".$details->sNamespace ); G::auditLog("InstallPlugin", "Plugin Name: ".$details->sNamespace );
//if ($response->recordsCountSuccess <= 0) { //if ($response->recordsCountSuccess <= 0) {
//throw (new Exception( 'The plugin ' . $details->sNamespace . ' couldn\'t verify any translation item. Verified Records:' . $response->recordsCountSuccess)); //throw (new Exception( 'The plugin ' . $details->sNamespace . ' couldn\'t verify any translation item. Verified Records:' . $response->recordsCountSuccess));
//} //}
G::header( "Location: pluginsMain" ); G::header( "Location: pluginsMain" );
die(); die();
} catch (Exception $e) { } catch (Exception $e) {

View File

@@ -63,13 +63,17 @@ if (isset( $sfunction ) && $sfunction == 'lookforNameTrigger') {
} }
} }
print $flag;
//print'krlos';return ; echo $flag;
} else { } else {
G::LoadClass("processMap");
G::LoadClass("codeScanner");
$response = array();
try { try {
$oTrigger = new Triggers(); $oTrigger = new Triggers();
G::LoadClass( 'processMap' );
$oProcessMap = new processMap( new DBConnection() ); $oProcessMap = new processMap( new DBConnection() );
if (isset( $_POST['form'] )) { if (isset( $_POST['form'] )) {
$value = $_POST['form']; $value = $_POST['form'];
@@ -77,6 +81,25 @@ if (isset( $sfunction ) && $sfunction == 'lookforNameTrigger') {
$value = $_POST; $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'] != '') { if ($value['TRI_UID'] != '') {
$oTrigger->load( $value['TRI_UID'] ); $oTrigger->load( $value['TRI_UID'] );
} else { } else {
@@ -86,15 +109,17 @@ if (isset( $sfunction ) && $sfunction == 'lookforNameTrigger') {
//print_r($_POST['form']);die; //print_r($_POST['form']);die;
$oTrigger->update( $value ); $oTrigger->update( $value );
if (! isset( $_POST['mode'] )) { //if (! isset( $_POST['mode'] )) {
$oProcessMap->triggersList( $value['PRO_UID'] ); // $oProcessMap->triggersList( $value['PRO_UID'] );
} //}
$result->success = true;
$result->msg = G::LoadTranslation( 'ID_TRIGGERS_SAVED' ); $response["success"] = true;
$response["msg"] = G::LoadTranslation("ID_TRIGGERS_SAVED");
} catch (Exception $e) { } catch (Exception $e) {
$result->success = false; $response["success"] = false;
$result->msg = $e->getMessage(); $response["msg"] = $e->getMessage();
} }
print G::json_encode( $result );
echo G::json_encode($response);
} }

View File

@@ -1166,6 +1166,19 @@ importProcess = function()
var resp_ = Ext.util.JSON.decode(resp.response.responseText); var resp_ = Ext.util.JSON.decode(resp.response.responseText);
if (resp_.status) {
if (resp_.status == "DISABLED-CODE") {
Ext.MessageBox.show({
title: _("ID_ERROR"),
msg: "<div style=\"overflow: auto; width: 500px; height: 150px;\">" + stringReplace("\\x0A", "<br />", resp_.message) + "</div>", //\n 10
icon: Ext.MessageBox.ERROR,
buttons: Ext.MessageBox.OK
});
return;
}
}
if (resp_.catchMessage == "") { if (resp_.catchMessage == "") {
if (resp_.ExistProcessInDatabase == "0") { if (resp_.ExistProcessInDatabase == "0") {
if (resp_.ExistGroupsInDatabase == "0") { if (resp_.ExistGroupsInDatabase == "0") {

View File

@@ -179,7 +179,7 @@ Ext.onReady(function(){
}); });
if (typeof(__PLUGIN_ERROR__) !== 'undefined') { 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 }, params : { UIDS : ids },
method: 'GET', method: 'GET',
success: function ( result, request ) { 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 = ''; var site = '';
if (SYS_SKIN.substring(0,2) == 'ux') { if (SYS_SKIN.substring(0,2) == 'ux') {
site = PROCESSMAKER_URL + '/main?st=admin&s='+parent._NODE_SELECTED; site = PROCESSMAKER_URL + '/main?st=admin&s='+parent._NODE_SELECTED;
@@ -319,3 +327,4 @@ capitalize = function(s){
s = s.toLowerCase(); s = s.toLowerCase();
return s.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } ); return s.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase(); } );
}; };

View File

@@ -86,16 +86,38 @@ window.onbeforeunload=function(){
} }
}; };
function triggerSave1(form){ function triggerSave1(form)
ajax_post(form.action, form, 'POST'); {
if(opener) { ajax_post(
if(@QSTEP_UID!="" && @QST_TYPE!="" && opener.showTriggers) form.action,
opener.showTriggers(@QSTEP_UID,@QST_TYPE); form,
if(opener.reloadTriggersShortList) "POST",
opener.reloadTriggersShortList(); function (responseText)
} {
window.close(); 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
);
} }
]]>
]]></JS> </JS>
</dynaForm> </dynaForm>