Merged in bugfix/PMCORE-561 (pull request #7466)

PMCORE-561

Approved-by: Julio Cesar Laura Avendaño <contact@julio-laura.com>
This commit is contained in:
Andrea Adamczyk
2020-09-24 12:45:26 +00:00
committed by Julio Cesar Laura Avendaño
11 changed files with 355 additions and 13 deletions

View File

@@ -58,6 +58,7 @@ class RBAC
'ofToAssign' => ['PM_FACTORY'], 'ofToAssign' => ['PM_FACTORY'],
'usersGroup' => ['PM_FACTORY'], 'usersGroup' => ['PM_FACTORY'],
'canDeleteUser' => ['PM_USERS'], 'canDeleteUser' => ['PM_USERS'],
'privateProcesses' => ['PM_USERS'],
'deleteUser' => ['PM_USERS'], 'deleteUser' => ['PM_USERS'],
'changeUserStatus' => ['PM_USERS'], 'changeUserStatus' => ['PM_USERS'],
'availableGroups' => ['PM_USERS'], 'availableGroups' => ['PM_USERS'],

View File

@@ -0,0 +1,147 @@
<?php
namespace Tests\unit\workflow\engine\methods\users;
use ProcessMaker\Model\Configuration;
use ProcessMaker\Model\Process;
use ProcessMaker\Model\RbacUsers;
use ProcessMaker\Model\User;
use RBAC;
use Tests\TestCase;
class Users_AjaxTest extends TestCase
{
/**
* Set up the deprecated errors
*/
public function setUp()
{
parent::setUp();
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
}
/**
* Tests the users_ajax file with the privateProcesses action
* @test
*/
public function it_tests_the_users_ajax_file_private_processes_action()
{
$_POST = [];
//Declare the global variable
global $RBAC;
//Creates the user factory
$user = factory(User::class)->create();
$usrUid = $user['USR_UID'];
factory(Process::class)->create([
'PRO_CREATE_USER' => $usrUid,
'PRO_STATUS' => 'ACTIVE',
'PRO_TYPE_PROCESS' => 'PRIVATE',
]);
//Creates the configuration factory
factory(Configuration::class)->create([
'CFG_UID' => 'USER_PREFERENCES',
'OBJ_UID' => '',
'CFG_VALUE' => 'a:3:{s:12:"DEFAULT_LANG";s:0:"";s:12:"DEFAULT_MENU";s:8:"PM_SETUP";s:18:"DEFAULT_CASES_MENU";s:0:"";}',
'PRO_UID' => '',
'USR_UID' => $usrUid,
'APP_UID' => '',
]);
//Sets the needed variables
$_SESSION['USER_LOGGED'] = '00000000000000000000000000000001';
$_POST['action'] = 'privateProcesses';
$_POST['USR_UID'] = $usrUid;
$_REQUEST['function'] = 'privateProcesses';
$_GET['function'] = 'privateProcesses';
$RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$RBAC->initRBAC();
$RBAC->loadUserRolePermission('PROCESSMAKER', $_SESSION['USER_LOGGED']);
//Turn on output buffering
ob_start();
//Call the tested file
require_once PATH_TRUNK . 'workflow/engine/methods/users/users_Ajax.php';
//Return the contents of the output buffer
$outputBuffer = ob_get_contents();
//Clean the output buffer and turn off output buffering
ob_end_clean();
//Removing the BOM (Byte Order Mark)
if (0 === strpos(bin2hex($outputBuffer), 'efbbbf')) {
//Decode the JSON string
$res = json_decode(substr($outputBuffer, 3));
} else {
//Decode the JSON string
$res = json_decode($outputBuffer);
}
//Assert the response contains a row
$this->assertNotEmpty($res);
}
/**
* Tests the users_ajax file with the deleteUser action
* @test
*/
public function it_tests_the_users_ajax_file_delete_user_action()
{
//Declare the global variable
global $RBAC;
//Creates the user factory
$user = factory(User::class)->create();
factory(RbacUsers::class)->create([
'USR_UID' => $user['USR_UID'],
'USR_USERNAME' => $user->USR_USERNAME,
'USR_FIRSTNAME' => $user->USR_FIRSTNAME,
'USR_LASTNAME' => $user->USR_LASTNAME
]);
$usrUid = $user['USR_UID'];
$process = factory(Process::class)->create([
'PRO_CREATE_USER' => $usrUid,
'PRO_STATUS' => 'ACTIVE',
'PRO_TYPE_PROCESS' => 'PRIVATE',
]);
//Sets the needed variables
$_SESSION['USER_LOGGED'] = '00000000000000000000000000000001';
$_POST['action'] = 'userData';
$_POST['USR_UID'] = $usrUid;
$_REQUEST['function'] = 'deleteUser';
$_GET['function'] = 'deleteUser';
$_POST['private_processes'] = Process::where('PRO_ID', $process->PRO_ID)->get();
$RBAC = RBAC::getSingleton(PATH_DATA, session_id());
$RBAC->initRBAC();
$RBAC->loadUserRolePermission('PROCESSMAKER', $_SESSION['USER_LOGGED']);
//Turn on output buffering
ob_start();
//Call the tested file
require_once PATH_TRUNK . 'workflow/engine/methods/users/users_Ajax.php';
//Return the contents of the output buffer
$outputBuffer = ob_get_contents();
//Clean the output buffer and turn off output buffering
ob_end_clean();
//Removing the BOM (Byte Order Mark)
if (0 === strpos(bin2hex($outputBuffer), 'efbbbf')) {
//Decode the JSON string
$res = json_decode(substr($outputBuffer, 3));
} else {
//Decode the JSON string
$res = json_decode($outputBuffer);
}
//Asserts the result is null
$this->assertNull($res);
}
}

View File

@@ -183,4 +183,63 @@ class ProcessTest extends TestCase
$this->assertNotEquals($process2['PRO_UID'], $res[0]['PRO_UID']); $this->assertNotEquals($process2['PRO_UID'], $res[0]['PRO_UID']);
$this->assertNotEquals($process3['PRO_UID'], $res[0]['PRO_UID']); $this->assertNotEquals($process3['PRO_UID'], $res[0]['PRO_UID']);
} }
/**
* It tests the getProcessPrivateListByUser method
*
* @covers \ProcessMaker\Model\Process::getProcessPrivateListByUser()
* @test
*/
public function it_should_test_the_get_process_private_list_by_user_method()
{
//Create user
$user = factory(User::class)->create();
//Create process
factory(Process::class)->create([
'PRO_CREATE_USER' => $user['USR_UID'],
'PRO_STATUS' => 'ACTIVE',
'PRO_TYPE_PROCESS' => 'PRIVATE',
]);
//Create a Process object
$process = new Process();
//Call the getProcessPrivateListByUser() method
$res = $process->getProcessPrivateListByUser($user['USR_UID']);
// This asserts the result contains one row
$this->assertCount(1, $res);
}
/**
* It tests the convertPrivateProcessesToPublic method
*
* @covers \ProcessMaker\Model\Process::convertPrivateProcessesToPublic()
* @test
*/
public function it_should_test_the_convert_private_processes_to_public_method()
{
//Create user
$user = factory(User::class)->create();
//Create process
$pro = factory(Process::class)->create([
'PRO_CREATE_USER' => $user['USR_UID'],
'PRO_STATUS' => 'ACTIVE',
'PRO_TYPE_PROCESS' => 'PRIVATE',
]);
$p = Process::where('PRO_UID', $pro->PRO_UID)->get()->values()->toArray();
//Create a Process object
$process = new Process();
//Call the convertPrivateProcessesToPublic() method
$process->convertPrivateProcessesToPublic($p);
$p = Process::where('PRO_UID', $pro->PRO_UID)->get()->values();
// This asserts the process was converted from private to public
$this->assertEquals('PUBLIC', $p[0]->PRO_TYPE_PROCESS);
}
} }

View File

@@ -5,6 +5,7 @@ namespace Tests\unit\workflow\engine\src\ProcessMaker\Services\Api;
use Faker\Factory; use Faker\Factory;
use ProcessMaker\Model\Process; use ProcessMaker\Model\Process;
use ProcessMaker\Model\User; use ProcessMaker\Model\User;
use ProcessMaker\Model\RbacUsers;
use ProcessMaker\Importer\XmlImporter; use ProcessMaker\Importer\XmlImporter;
use ProcessMaker\Services\Api\Project; use ProcessMaker\Services\Api\Project;
use Tests\TestCase; use Tests\TestCase;
@@ -40,4 +41,52 @@ class ProjectTest extends TestCase
$this->assertNotEmpty($result); $this->assertNotEmpty($result);
} }
/**
* Tests the doGetProcess method
*
* @test
* @covers \ProcessMaker\Services\Api\Project::doGetProcess()
*/
public function it_should_test_the_do_get_process_method()
{
//Create user
$user = factory(User::class)->create();
factory(RbacUsers::class)->create([
'USR_UID' => $user->USR_UID,
'USR_USERNAME' => $user->USR_USERNAME,
'USR_FIRSTNAME' => $user->USR_FIRSTNAME,
'USR_LASTNAME' => $user->USR_LASTNAME
]);
//Create process
$process = factory(Process::class)->create([
'PRO_CREATE_USER' => $user->USR_UID,
'PRO_STATUS' => 'ACTIVE',
'PRO_TYPE_PROCESS' => 'PRIVATE',
]);
$project = new Project();
$res = $project->doGetProcess($process->PRO_UID);
//Asserts the response has the user information
$this->assertArrayHasKey('pro_create_username', $res);
$this->assertArrayHasKey('pro_create_firstname', $res);
$this->assertArrayHasKey('pro_create_lastname', $res);
}
/**
* Tests the doGetProcess with exception
*
* @test
* @covers \ProcessMaker\Services\Api\Project::doGetProcess()
*/
public function it_should_test_the_do_get_process_method_with_exception()
{
$project = new Project();
//This asserts the expected exception
$this->expectExceptionMessage("**ID_PROJECT_DOES_NOT_EXIST**");
$project->doGetProcess('');
}
} }

View File

@@ -323,6 +323,9 @@ class Process extends BaseProcess
if (isset($aData['PRO_DESCRIPTION'])) { if (isset($aData['PRO_DESCRIPTION'])) {
$oPro->setProDescriptionContent($aData['PRO_DESCRIPTION']); $oPro->setProDescriptionContent($aData['PRO_DESCRIPTION']);
} }
if (isset($aData['PRO_PROCESS_OWNER'])) {
$oPro->setProCreateUser($aData['PRO_PROCESS_OWNER']);
}
$res = $oPro->save(); $res = $oPro->save();
$con->commit(); $con->commit();

View File

@@ -19253,6 +19253,12 @@ msgstr "Do you want to delete this user ?"
msgid "The user can not be deleted while assigned as a supervisor. Do you want to delete it anyway?" msgid "The user can not be deleted while assigned as a supervisor. Do you want to delete it anyway?"
msgstr "The user can not be deleted while assigned as a supervisor. Do you want to delete it anyway?" msgstr "The user can not be deleted while assigned as a supervisor. Do you want to delete it anyway?"
# TRANSLATION
# LABEL/ID_MSG_CONFIRM_DELETE_USER_PRIVATE_PROCESSES
#: LABEL/ID_MSG_CONFIRM_DELETE_USER_PRIVATE_PROCESSES
msgid "This user has private processes, if you continue all the user's private processes will become public processes. Do you want to continue?"
msgstr "This user has private processes, if you continue all the user's private processes will become public processes. Do you want to continue?"
# TRANSLATION # TRANSLATION
# LABEL/ID_MSG_CONFIRM_DELETE_WEBBOT # LABEL/ID_MSG_CONFIRM_DELETE_WEBBOT
#: LABEL/ID_MSG_CONFIRM_DELETE_WEBBOT #: LABEL/ID_MSG_CONFIRM_DELETE_WEBBOT

View File

@@ -60092,6 +60092,7 @@ INSERT INTO TRANSLATION (TRN_CATEGORY,TRN_ID,TRN_LANG,TRN_VALUE,TRN_UPDATE_DATE
( 'LABEL','ID_MSG_CONFIRM_DELETE_TRIGGER','en','Do you want to delete this trigger?','2014-01-15') , ( 'LABEL','ID_MSG_CONFIRM_DELETE_TRIGGER','en','Do you want to delete this trigger?','2014-01-15') ,
( 'LABEL','ID_MSG_CONFIRM_DELETE_USER','en','Do you want to delete this user ?','2014-01-15') , ( 'LABEL','ID_MSG_CONFIRM_DELETE_USER','en','Do you want to delete this user ?','2014-01-15') ,
( 'LABEL','ID_MSG_CONFIRM_DELETE_USER_ASSINGED_SUPERVISOR','en','The user can not be deleted while assigned as a supervisor. Do you want to delete it anyway?','2014-10-21') , ( 'LABEL','ID_MSG_CONFIRM_DELETE_USER_ASSINGED_SUPERVISOR','en','The user can not be deleted while assigned as a supervisor. Do you want to delete it anyway?','2014-10-21') ,
( 'LABEL','ID_MSG_CONFIRM_DELETE_USER_PRIVATE_PROCESSES','en',"This user has private processes, if you continue all the user's private processes will become public processes. Do you want to continue?",'2020-09-02') ,
( 'LABEL','ID_MSG_CONFIRM_DELETE_WEBBOT','en','Are you sure you want to delete this webbot?','2014-01-15') , ( 'LABEL','ID_MSG_CONFIRM_DELETE_WEBBOT','en','Are you sure you want to delete this webbot?','2014-01-15') ,
( 'LABEL','ID_MSG_CONFIRM_REMOVE_LANGUAGE','en','Are you sure you want to remove this language?','2014-01-15') , ( 'LABEL','ID_MSG_CONFIRM_REMOVE_LANGUAGE','en','Are you sure you want to remove this language?','2014-01-15') ,
( 'LABEL','ID_MSG_CONFIRM_REMOVE_TRIGGER','en','Are you sure you want to remove this trigger?','2014-01-15') , ( 'LABEL','ID_MSG_CONFIRM_REMOVE_TRIGGER','en','Are you sure you want to remove this trigger?','2014-01-15') ,

View File

@@ -1,5 +1,7 @@
<?php <?php
use ProcessMaker\Model\Process;
try { try {
global $RBAC; global $RBAC;
switch ($RBAC->userCanAccess('PM_LOGIN')) { switch ($RBAC->userCanAccess('PM_LOGIN')) {
@@ -107,7 +109,15 @@ try {
$response .= '}'; $response .= '}';
echo $response; echo $response;
break; break;
case 'privateProcesses':
$usrUid = $_POST['USR_UID'];
//Check if the user has private processes
$r = Process::getProcessPrivateListByUser($usrUid);
$response = json_encode(['success'=>true, 'publicProcesses'=>$r]);
echo $response;
break;
case 'deleteUser': case 'deleteUser':
Process::convertPrivateProcessesToPublic(json_decode($_POST['private_processes']));
$usrUid = $_POST['USR_UID']; $usrUid = $_POST['USR_UID'];
//Check if the user was defined in a process permissions //Check if the user was defined in a process permissions
$oObjectPermission = new ObjectPermission(); $oObjectPermission = new ObjectPermission();

View File

@@ -3,6 +3,8 @@
namespace ProcessMaker\Model; namespace ProcessMaker\Model;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use RbacUsers;
use RBAC;
/** /**
* Class Process * Class Process
@@ -57,4 +59,35 @@ class Process extends Model
return ($query->get()->values()->toArray()); return ($query->get()->values()->toArray());
} }
/**
* Obtains the list of private processes assigned to the user
*
* @param string $userUid
* @return array
*/
public static function getProcessPrivateListByUser($userUid)
{
$query = Process::query()
->select()
->where('PRO_CREATE_USER', $userUid)
->where('PRO_TYPE_PROCESS', 'PRIVATE');
return ($query->get()->values()->toArray());
}
/**
* Converts the private processes to public
*
* @param array $privateProcesses
* @return void
*/
public static function convertPrivateProcessesToPublic($privateProcesses)
{
$admin = RBAC::ADMIN_USER_UID;
$processes = array_column($privateProcesses, 'PRO_ID');
Process::whereIn('PRO_ID', $processes)
->update(['PRO_TYPE_PROCESS' => 'PUBLIC', 'PRO_CREATE_USER' => $admin]);
}
} }

View File

@@ -1,19 +1,19 @@
<?php <?php
namespace ProcessMaker\Services\Api; namespace ProcessMaker\Services\Api;
use Exception;
use Luracast\Restler\RestException; use Luracast\Restler\RestException;
use ProcessMaker\Project\Bpmn;
use ProcessMaker\Services\Api;
use \ProcessMaker\Project\Adapter;
use \ProcessMaker\Util;
use \ProcessMaker\Util\DateTime;
use \ProcessMaker\BusinessModel\Validator;
use \ProcessMaker\BusinessModel\Migrator\GranularExporter; use \ProcessMaker\BusinessModel\Migrator\GranularExporter;
use \ProcessMaker\BusinessModel\Migrator\ExportObjects; use \ProcessMaker\BusinessModel\Migrator\ExportObjects;
use \ProcessMaker\Util\IO\HttpStream; use \ProcessMaker\BusinessModel\Validator;
use \ProcessMaker\Util\Common; use \ProcessMaker\Project\Adapter;
use ProcessMaker\Project\Adapter\BpmnWorkflow; use ProcessMaker\Project\Adapter\BpmnWorkflow;
use Exception; use ProcessMaker\Project\Bpmn;
use ProcessMaker\Services\Api;
use \ProcessMaker\Util\Common;
use \ProcessMaker\Util\DateTime;
use \ProcessMaker\Util\IO\HttpStream;
use RbacUsers;
/** /**
* @package Services\Api\ProcessMaker * @package Services\Api\ProcessMaker
@@ -296,6 +296,14 @@ class Project extends Api
$response = $process->getProcess($prj_uid); $response = $process->getProcess($prj_uid);
$rbacUser = new RbacUsers();
$res = $rbacUser->load($response['pro_create_user']);
if (!empty($res)) {
$response['pro_create_username'] = $res['USR_USERNAME'];
$response['pro_create_firstname'] = $res['USR_FIRSTNAME'];
$response['pro_create_lastname'] = $res['USR_LASTNAME'];
}
return DateTime::convertUtcToIso8601($response, $this->arrayFieldIso8601); return DateTime::convertUtcToIso8601($response, $this->arrayFieldIso8601);
} catch (Exception $e) { } catch (Exception $e) {

View File

@@ -525,7 +525,7 @@ DeleteUserAction = function(){
if (response.hashistory){ if (response.hashistory){
Ext.Msg.confirm(_('ID_CONFIRM'), _('ID_USERS_DELETE_WITH_HISTORY'), Ext.Msg.confirm(_('ID_CONFIRM'), _('ID_USERS_DELETE_WITH_HISTORY'),
function(btn){ function(btn){
if (btn=='yes') DeleteUser(uid.data.USR_UID); if (btn=='yes') hasPrivateProcesses(uid.data.USR_UID);
} }
); );
}else{ }else{
@@ -533,7 +533,7 @@ DeleteUserAction = function(){
Ext.Msg.confirm(_('ID_CONFIRM'), msgConfirm, Ext.Msg.confirm(_('ID_CONFIRM'), msgConfirm,
function(btn){ function(btn){
if (btn=='yes') DeleteUser(uid.data.USR_UID); if (btn=='yes') hasPrivateProcesses(uid.data.USR_UID);
} }
); );
} }
@@ -649,10 +649,10 @@ DoSearch = function(){
}; };
//Delete User Function //Delete User Function
DeleteUser = function(uid){ DeleteUser = function(uid, privateProcesses){
Ext.Ajax.request({ Ext.Ajax.request({
url: 'users_Ajax', url: 'users_Ajax',
params: {'function': 'deleteUser', USR_UID: uid}, params: {'function': 'deleteUser', USR_UID: uid, private_processes: privateProcesses},
success: function(res, opt){ success: function(res, opt){
var response = Ext.util.JSON.decode(res.responseText); var response = Ext.util.JSON.decode(res.responseText);
if (response.status === 'ERROR') { if (response.status === 'ERROR') {
@@ -666,6 +666,31 @@ DeleteUser = function(uid){
}); });
}; };
/**
* Show a message in case the user to be deleted has private processes
*
* @param {string} uid
*/
hasPrivateProcesses = function (uid) {
Ext.Ajax.request({
url: 'users_Ajax',
params: { 'function': 'privateProcesses', USR_UID: uid },
success: function (res, opt) {
var response = Ext.util.JSON.decode(res.responseText);
if (!(response.publicProcesses === undefined || response.publicProcesses.length == 0)) {
Ext.Msg.confirm(_('ID_CONFIRM'), _("ID_MSG_CONFIRM_DELETE_USER_PRIVATE_PROCESSES"),
function(btn){
if (btn == 'yes') DeleteUser(uid, Ext.util.JSON.encode(response.publicProcesses));
}
);
} else {
DeleteUser(uid, Ext.util.JSON.encode(response.publicProcesses));
}
},
failure: DoNothing
});
};
//Update Page Size Configuration //Update Page Size Configuration
UpdatePageConfig = function(pageSize){ UpdatePageConfig = function(pageSize){
Ext.Ajax.request({ Ext.Ajax.request({