From dbc046517481a09abeeeda894ab17dd5c91d9828 Mon Sep 17 00:00:00 2001 From: Roly Rudy Gutierrez Pinto Date: Tue, 30 Jun 2020 11:23:41 -0400 Subject: [PATCH] PMCORE-1349 [19511] Multiple file fields dont work with Action By Email --- database/factories/AppDocumentFactory.php | 41 ++++ .../methods/cases/CasesShowDocumentTest.php | 69 ++++++ .../services/ActionsByEmailDataFormTest.php | 83 +++++++ .../ProcessMaker/Services/Api/CasesTest.php | 216 ++++++++++++++++++ .../methods/cases/cases_ShowDocument.php | 7 +- .../services/ActionsByEmailDataForm.php | 20 +- .../src/ProcessMaker/Model/AppDocument.php | 14 ++ .../src/ProcessMaker/Services/Api/Cases.php | 4 + 8 files changed, 449 insertions(+), 5 deletions(-) create mode 100644 database/factories/AppDocumentFactory.php create mode 100644 tests/unit/workflow/engine/methods/cases/CasesShowDocumentTest.php create mode 100644 tests/unit/workflow/engine/methods/services/ActionsByEmailDataFormTest.php create mode 100644 tests/unit/workflow/engine/src/ProcessMaker/Services/Api/CasesTest.php create mode 100644 workflow/engine/src/ProcessMaker/Model/AppDocument.php diff --git a/database/factories/AppDocumentFactory.php b/database/factories/AppDocumentFactory.php new file mode 100644 index 000000000..3796d1649 --- /dev/null +++ b/database/factories/AppDocumentFactory.php @@ -0,0 +1,41 @@ +define(\ProcessMaker\Model\AppDocument::class, function (Faker $faker) { + $user = factory(\ProcessMaker\Model\User::class)->create(); + $process = factory(\ProcessMaker\Model\Process::class)->create(); + $task = factory(\ProcessMaker\Model\Task::class)->create([ + 'PRO_UID' => $process->PRO_UID, + 'PRO_ID' => $process->PRO_ID + ]); + $application = factory(\ProcessMaker\Model\Application::class)->create([ + 'PRO_UID' => $process->PRO_UID, + 'APP_INIT_USER' => $user->USR_UID, + 'APP_CUR_USER' => $user->USR_UID + ]); + return [ + 'APP_DOC_UID' => G::generateUniqueID(), + 'APP_DOC_FILENAME' => $faker->name . '.' . $faker->fileExtension, + 'APP_DOC_TITLE' => $faker->title, + 'APP_DOC_COMMENT' => '', + 'DOC_VERSION' => 1, + 'APP_UID' => $application->APP_UID, + 'DEL_INDEX' => 1, + 'DOC_UID' => -1, + 'DOC_ID' => 0, + 'USR_UID' => $user->USR_UID, + 'APP_DOC_TYPE' => 'ATTACHED', + 'APP_DOC_CREATE_DATE' => $faker->dateTime(), + 'APP_DOC_INDEX' => 1, + 'FOLDER_UID' => '', + 'APP_DOC_PLUGIN' => '', + 'APP_DOC_TAGS' => null, + 'APP_DOC_STATUS' => 'ACTIVE', + 'APP_DOC_STATUS_DATE' => '', + 'APP_DOC_FIELDNAME' => '', + 'APP_DOC_DRIVE_DOWNLOAD' => 'a:0:{}', + 'SYNC_WITH_DRIVE' => 'UNSYNCHRONIZED', + 'SYNC_PERMISSIONS' => null + ]; +}); diff --git a/tests/unit/workflow/engine/methods/cases/CasesShowDocumentTest.php b/tests/unit/workflow/engine/methods/cases/CasesShowDocumentTest.php new file mode 100644 index 000000000..04e1e4dfa --- /dev/null +++ b/tests/unit/workflow/engine/methods/cases/CasesShowDocumentTest.php @@ -0,0 +1,69 @@ +initRBAC(); + + $appDocument = factory(AppDocument::class)->create([ + 'APP_DOC_FILENAME' => 'text.txt' + ]); + + $_GET['a'] = $appDocument->APP_DOC_UID; + $_GET['v'] = '1'; + + $path = G::getPathFromUID($appDocument->APP_UID); + $file = G::getPathFromFileUID($appDocument->APP_UID, $appDocument->APP_DOC_UID); + $realPath = PATH_DOCUMENT . $path . '/' . $file[0] . $file[1] . '_' . 1 . '.txt'; + $dirs = explode('/', $realPath); + $filename = array_pop($dirs); + $path = ''; + foreach ($dirs as $value) { + if (empty($value)) { + continue; + } + $path = $path . PATH_SEP . $value; + if (!file_exists($path)) { + mkdir($path); + } + } + $expected = 'test'; + file_put_contents($realPath, $expected); + $_SERVER['HTTP_USER_AGENT'] = ''; + + //assert file content + ob_start(); + $fileName = PATH_METHODS . 'cases/cases_ShowDocument.php'; + require_once $fileName; + $content = ob_get_contents(); + ob_end_clean(); + + $this->assertEquals($expected, $content); + } +} diff --git a/tests/unit/workflow/engine/methods/services/ActionsByEmailDataFormTest.php b/tests/unit/workflow/engine/methods/services/ActionsByEmailDataFormTest.php new file mode 100644 index 000000000..308008eb9 --- /dev/null +++ b/tests/unit/workflow/engine/methods/services/ActionsByEmailDataFormTest.php @@ -0,0 +1,83 @@ +create(); + + $pathData = PATH_TRUNK . "tests/resources/dynaform1.json"; + $content = file_get_contents($pathData); + + $dynaform = factory(\ProcessMaker\Model\Dynaform::class)->create([ + 'PRO_UID' => $process->PRO_UID, + 'DYN_CONTENT' => $content + ]); + $delegation = factory(\ProcessMaker\Model\Delegation::class)->state('closed')->create([ + 'PRO_UID' => $process->PRO_UID + ]); + + global $RBAC; + $_GET["APP_UID"] = G::encrypt($delegation->APP_UID, URL_KEY); + $_GET["DEL_INDEX"] = G::encrypt($delegation->DEL_INDEX, URL_KEY); + $_GET["DYN_UID"] = G::encrypt($dynaform->DYN_UID, URL_KEY); + $_GET["ABER"] = G::encrypt($delegation->APP_UID, URL_KEY); + $_GET["BROWSER_TIME_ZONE_OFFSET"] = "-14400"; + $_REQUEST = $_GET; + $cached = [ + 'zLhSk5TeEQrNFI2RXFEVktyUGpnczV1WEJNWVp6cjYxbTU3R29mVXVZNWhZQT0=' => true + ]; + Cache::put(PmLicenseManager::CACHE_KEY . '.' . config("system.workspace"), $cached, Carbon::now()->addDay(1)); + + ob_start(); + $fileName = PATH_METHODS . 'services/ActionsByEmailDataForm.php'; + require_once $fileName; + $content = ob_get_contents(); + ob_end_clean(); + + $this->assertNotEmpty($content); + $this->assertContains('ID_ABE_FORM_ALREADY_FILLED', $content); + } +} diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Services/Api/CasesTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Services/Api/CasesTest.php new file mode 100644 index 000000000..a0afdbdb5 --- /dev/null +++ b/tests/unit/workflow/engine/src/ProcessMaker/Services/Api/CasesTest.php @@ -0,0 +1,216 @@ +getProperty('userId'); + $reflectionPropertyUserId->setAccessible(true); + $reflectionPropertyUserId->setValue($userUid); + + $reflectionPropertyDSN = $reflection->getProperty('dsn'); + $reflectionPropertyDSN->setAccessible(true); + $reflectionPropertyDSN->setValue('mysql:host=' . env('DB_HOST') . ';dbname=' . env('DB_DATABASE')); + + $reflectionPropertyUserName = $reflection->getProperty('dbUser'); + $reflectionPropertyUserName->setAccessible(true); + $reflectionPropertyUserName->setValue(env('DB_USERNAME')); + + $reflectionPropertyPassword = $reflection->getProperty('dbPassword'); + $reflectionPropertyPassword->setAccessible(true); + $reflectionPropertyPassword->setValue(env('DB_PASSWORD')); + + //application + Defaults::$cacheDirectory = PATH_DB . config('system.workspace') . PATH_SEP; + HumanReadableCache::$cacheDir = PATH_DB . config('system.workspace') . PATH_SEP; + + $rest = new Restler(true); + $rest->setFlagMultipart(false); + $rest->setAPIVersion('1.0'); + $rest->addAuthenticationClass('ProcessMaker\\Services\\OAuth2\\Server', ''); + $rest->addAuthenticationClass('ProcessMaker\\Policies\\AccessControl'); + $rest->addAuthenticationClass('ProcessMaker\\Policies\\ControlUnderUpdating'); + + $rest->apiMethodInfo = new ApiMethodInfo(); + return $rest; + } + + /** + * This test verify isAllowed method expecting RestException. + * @test + * @covers ProcessMaker\Services\Api\Cases::__isAllowed + */ + public function it_should_test_isAllowed_method_try_exception() + { + $user = factory(\ProcessMaker\Model\User::class)->create(); + $rest = $this->initializeRestApi($user->USR_UID); + + //assert exception + $this->expectException(RestException::class); + + $cases = new Cases(); + $cases->parameters = []; + $cases->__isAllowed(); + } + + /** + * This test verify isAllowed method doGetCaseVariables option. + * @test + * @covers ProcessMaker\Services\Api\Cases::__isAllowed + */ + public function it_should_test_isAllowed_method_doGetCaseVariables_option() + { + $user = factory(\ProcessMaker\Model\User::class)->create(); + $process = factory(\ProcessMaker\Model\Process::class)->create(); + $task = factory(\ProcessMaker\Model\Task::class)->create([ + 'PRO_UID' => $process->PRO_UID, + 'PRO_ID' => $process->PRO_ID + ]); + $dynaform = factory(\ProcessMaker\Model\Dynaform::class)->create([ + 'PRO_UID' => $process->PRO_UID + ]); + $application = factory(\ProcessMaker\Model\Application::class)->create([ + 'PRO_UID' => $process->PRO_UID, + 'APP_INIT_USER' => $user->USR_UID, + 'APP_CUR_USER' => $user->USR_UID + ]); + $delegation = factory(\ProcessMaker\Model\Delegation::class)->create([ + 'APP_UID' => $application->APP_UID, + 'APP_NUMBER' => $application->APP_NUMBER, + 'DEL_INDEX' => 1, + 'PRO_UID' => $process->PRO_UID, + 'PRO_ID' => $process->PRO_ID, + 'TAS_UID' => $task->TAS_UID, + 'TAS_ID' => $task->TAS_ID, + 'USR_UID' => $user->USR_UID, + 'USR_ID' => $user->USR_ID + ]); + + $rest = $this->initializeRestApi($user->USR_UID); + $rest->apiMethodInfo->methodName = 'doGetCaseVariables'; + $rest->apiMethodInfo->arguments = [ + 'app_uid' => 0, + 'dyn_uid' => 1, + 'app_index' => 2 + ]; + + //assert + $cases = new Cases(); + $cases->parameters = [ + $application->APP_UID, + $dynaform->DYN_UID, + 1 + ]; + $cases->restler = $rest; + $expected = $cases->__isAllowed(); + + $this->assertTrue($expected); + } + + /** + * This test verify isAllowed method doGetCaseVariables option with delegation user. + * @test + * @covers ProcessMaker\Services\Api\Cases::__isAllowed + */ + public function it_should_test_isAllowed_method_doGetCaseVariables_option_without_delegation_user() + { + $user = factory(\ProcessMaker\Model\User::class)->create(); + $process = factory(\ProcessMaker\Model\Process::class)->create(); + $task = factory(\ProcessMaker\Model\Task::class)->create([ + 'PRO_UID' => $process->PRO_UID, + 'PRO_ID' => $process->PRO_ID + ]); + $dynaform = factory(\ProcessMaker\Model\Dynaform::class)->create([ + 'PRO_UID' => $process->PRO_UID + ]); + $application = factory(\ProcessMaker\Model\Application::class)->create([ + 'PRO_UID' => $process->PRO_UID, + 'APP_INIT_USER' => $user->USR_UID, + 'APP_CUR_USER' => $user->USR_UID + ]); + + $rest = $this->initializeRestApi($user->USR_UID); + $rest->apiMethodInfo->methodName = 'doGetCaseVariables'; + $rest->apiMethodInfo->arguments = [ + 'app_uid' => 0, + 'dyn_uid' => 1, + 'app_index' => 2 + ]; + + //assert + $cases = new Cases(); + $cases->parameters = [ + $application->APP_UID, + $dynaform->DYN_UID, + 1 + ]; + $cases->restler = $rest; + $expected = $cases->__isAllowed(); + + $this->assertFalse($expected); + } + + /** + * This test verify isAllowed method doGetCaseVariables option with guest user. + * @test + * @covers ProcessMaker\Services\Api\Cases::__isAllowed + */ + public function it_should_test_isAllowed_method_doGetCaseVariables_option_with_guest_user() + { + $user = factory(\ProcessMaker\Model\User::class)->create(); + $process = factory(\ProcessMaker\Model\Process::class)->create(); + $task = factory(\ProcessMaker\Model\Task::class)->create([ + 'PRO_UID' => $process->PRO_UID, + 'PRO_ID' => $process->PRO_ID + ]); + $dynaform = factory(\ProcessMaker\Model\Dynaform::class)->create([ + 'PRO_UID' => $process->PRO_UID + ]); + $application = factory(\ProcessMaker\Model\Application::class)->create([ + 'PRO_UID' => $process->PRO_UID, + 'APP_INIT_USER' => $user->USR_UID, + 'APP_CUR_USER' => $user->USR_UID + ]); + + $rest = $this->initializeRestApi(RBAC::GUEST_USER_UID); + $rest->apiMethodInfo->methodName = 'doGetCaseVariables'; + $rest->apiMethodInfo->arguments = [ + 'app_uid' => 0, + 'dyn_uid' => 1, + 'app_index' => 2 + ]; + + //assert + $cases = new Cases(); + $cases->parameters = [ + $application->APP_UID, + $dynaform->DYN_UID, + 1 + ]; + $cases->restler = $rest; + $expected = $cases->__isAllowed(); + + $this->assertTrue($expected); + } +} diff --git a/workflow/engine/methods/cases/cases_ShowDocument.php b/workflow/engine/methods/cases/cases_ShowDocument.php index d3a4d387f..768e5a814 100644 --- a/workflow/engine/methods/cases/cases_ShowDocument.php +++ b/workflow/engine/methods/cases/cases_ShowDocument.php @@ -44,7 +44,12 @@ if (empty($_GET['v'])) { //Check if the user can be download the input Document //Send the parameter v = Version //Send the parameter a = Case UID -if ($RBAC->userCanAccess('PM_FOLDERS_ALL') != 1 && defined('DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION') && DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION == 0) { +$isGuestUser = false; +if (!empty($_SESSION['GUEST_USER']) && $_SESSION['GUEST_USER'] === RBAC::GUEST_USER_UID) { + $isGuestUser = true; +} +$access = $RBAC->userCanAccess('PM_FOLDERS_ALL') != 1 && defined('DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION') && DISABLE_DOWNLOAD_DOCUMENTS_SESSION_VALIDATION == 0; +if ($access && $isGuestUser === false) { if (!$oAppDocument->canDownloadInput($_SESSION['USER_LOGGED'], $_GET['a'], $docVersion)) { G::header('Location: /errors/error403.php?url=' . urlencode($_SERVER['REQUEST_URI'])); die(); diff --git a/workflow/engine/methods/services/ActionsByEmailDataForm.php b/workflow/engine/methods/services/ActionsByEmailDataForm.php index d597caca1..02a01bc4f 100644 --- a/workflow/engine/methods/services/ActionsByEmailDataForm.php +++ b/workflow/engine/methods/services/ActionsByEmailDataForm.php @@ -48,7 +48,7 @@ if (isset($_GET['BROWSER_TIME_ZONE_OFFSET'])) { $record = []; $record['DYN_CONTENT'] = $configuration['DYN_CONTENT']; - $record['PRO_UID'] = $configuration['PRO_UID']; + $record['PRO_UID'] = $configuration['PRO_UID']; $record['CURRENT_DYNAFORM'] = G::decrypt($_REQUEST['DYN_UID'], URL_KEY); $record['APP_UID'] = $_REQUEST['APP_UID']; $record['DEL_INDEX'] = $_REQUEST['DEL_INDEX']; @@ -56,9 +56,21 @@ if (isset($_GET['BROWSER_TIME_ZONE_OFFSET'])) { $record['APP_DATA'] = $caseFields['APP_DATA']; if (is_null($caseFields['DEL_FINISH_DATE'])) { - $a = new PmDynaform($record); - - $a->printABE($action,$record); + //we define the guest user + $restore = false; + if (isset($_SESSION["USER_LOGGED"])) { + $restore = $_SESSION["USER_LOGGED"]; + } + $_SESSION["USER_LOGGED"] = RBAC::GUEST_USER_UID; + $_SESSION['GUEST_USER'] = RBAC::GUEST_USER_UID; + $pmDynaform = new PmDynaform($record); + //we must return to the original value of the session + if ($restore === false) { + unset($_SESSION["USER_LOGGED"]); + } else { + $_SESSION["USER_LOGGED"] = $restore; + } + $pmDynaform->printABE($action, $record); } else { $G_PUBLISH->AddContent( 'xmlform', diff --git a/workflow/engine/src/ProcessMaker/Model/AppDocument.php b/workflow/engine/src/ProcessMaker/Model/AppDocument.php new file mode 100644 index 000000000..0c37ce0cb --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Model/AppDocument.php @@ -0,0 +1,14 @@ +parameters[$arrayArgs['dyn_uid']]; $delIndex = $this->parameters[$arrayArgs['app_index']]; $userUid = $this->getUserId(); + //check the guest user + if ($userUid === RBAC::GUEST_USER_UID) { + return true; + } //Check if the user has the case $appDelegation = new AppDelegation(); $aCurUser = $appDelegation->getCurrentUsers($applicationUid, $delIndex);